Dear Game Developers, Stop Messing This Up!

แชร์
ฝัง
  • เผยแพร่เมื่อ 2 ธ.ค. 2024

ความคิดเห็น • 1.7K

  • @JonasTyroller
    @JonasTyroller  ปีที่แล้ว +1835

    Small corrections (I learn some things from you as well, how nice, haha):
    - Using Time.deltaTime in Fixed Update is actually fine in Unity cause it automatically returns Time.fixedDeltaTime depending on where it is called from.
    - Using Delta Time in fixed update still makes sense for various reasons (it keeps speed to units/second and helps when inaccuracies in the fixed update intervals occur)
    That means 10 free points to you if your read this, haha. Will keep updating this in case I got anything else wrong. :P

    • @Robyamdam
      @Robyamdam ปีที่แล้ว +49

      Can you do more of these please?, Maybe an episode on debugging or finding code related problems that don't seem to have an answer

    • @blockify
      @blockify ปีที่แล้ว +8

      dont these 2 corrections contradict eachother? or am I being dumb xD If deltaTime returns fixedDeltaTime while in the Fixed Update, then how can it keep speed to units/second and help inaccuracies?

    • @aksimilumaspvp7278
      @aksimilumaspvp7278 ปีที่แล้ว +14

      @@blockify no because fixedDeltatime takes the inaccuraties and inconsistencies in fixedupdate into account, and deltaTime gives rhat fixedDeltatime.
      Point is in fixedUpdate
      fixedDeltatime==DeltaTime. There is no difference using one or another.
      Still, using either one can be helpful to get around inaccuraties(which can happen in fixedupdate if u use neither)

    • @wayfarergames
      @wayfarergames ปีที่แล้ว +2

      ​@@blockifyif it helps, you can think of multiplying by deltaTime or fixedDeltaTime as a sort of "per frame -> per second" conversion in unity! (You can also convert the other way by dividing by deltaTime, e.g. if you want to get the amount an object has moved in a single frame, you'd divide its velocity by deltaTime since in Unity velocities are usually per second)

    • @CyberAngel67
      @CyberAngel67 ปีที่แล้ว

      It doesn't return fixedDelta time. If we go back to what I said in another comment, the correct answer is not A in fact non of the truly was the right answer. delta time is the time it took to process the last frame, the documentation backs this up. So when you run that in FixedUpdate, that means the normal delta and the fixed delta will be the same value, but one does not simply return the other. Physics is a fixed step, therefore both are going to equal the same value!

  • @vast-games
    @vast-games 7 หลายเดือนก่อน +56

    I just love how He's one of the only devs that instead of showing "what to do" shows "why does it do" which is something so important.

  • @grbrigsted
    @grbrigsted ปีที่แล้ว +720

    If you're not using fixed updates, you might end up clipping through walls from lag spikes, unless you're using rays to assert if the player has moved through a wall between the previous frame and the current.

    • @i_makegames
      @i_makegames ปีที่แล้ว +23

      correct me if im wrong but, this will only happen if you use a rigid body controller, not for example the player controller asset, also you dont need to code a ray check as you can just set the rigid body to 'continuous' or 'continuous dynamic'

    • @JonelKingas
      @JonelKingas ปีที่แล้ว +7

      im literally so new at game dev, im just pretty much using everything in fixedupdate, and what needs to execute fast for example key pressed in update, idk if its fine but it works fine, example in my game this:
      void Update()
      {
      if (Input.GetMouseButtonDown(0))
      {
      isShooting = true;
      CalculateShootDirection();
      }
      else if (Input.GetMouseButtonUp(0))
      {
      isShooting = false;
      }
      if (isShooting)
      {
      CalculateShootDirection();
      }
      }
      void FixedUpdate()
      {
      if (isShooting)
      {
      shootTimer += Time.fixedDeltaTime;
      if (shootTimer >= shootingDelay)
      {
      Vector3 bulletVelocity = bulletSpeed * shootDirection;
      GameObject bullet1 = Instantiate(bulletPrefab, bulletSpawnPoint1.position, Quaternion.identity);
      bullet1.GetComponent().velocity = bulletVelocity;
      GameObject bullet2 = Instantiate(bulletPrefab, bulletSpawnPoint2.position, Quaternion.identity);
      bullet2.GetComponent().velocity = bulletVelocity;
      float rotationAngle = Mathf.Atan2(shootDirection.y, shootDirection.x) * Mathf.Rad2Deg;
      bullet1.transform.rotation = Quaternion.Euler(0f, 0f, rotationAngle);
      bullet1.transform.Rotate(Vector3.forward, 90f);
      bullet2.transform.rotation = Quaternion.Euler(0f, 0f, rotationAngle);
      bullet2.transform.Rotate(Vector3.forward, 90f);
      shootTimer = 0f;
      }
      }
      }
      private void CalculateShootDirection()
      {
      // Calculate the shoot direction based on the player's transform
      shootDirection = bulletSpawnMainPoint.up; // Assuming the player's forward direction is along the X-axis
      shootDirection.Normalize();
      }

    • @hexagon_
      @hexagon_ ปีที่แล้ว +2

      Orange grenade lifestyle

    • @grbrigsted
      @grbrigsted ปีที่แล้ว +2

      Neutral Milk Hotel

    • @notChocoMilk
      @notChocoMilk ปีที่แล้ว +1

      so that’s how i fix that.. too bad i’m already making a new player controller

  • @leffeup8117
    @leffeup8117 ปีที่แล้ว +1946

    As someone who litteraly had a math test earlier today on the subject of integrals, this was a great ego boost

    • @nobody.of.importance
      @nobody.of.importance ปีที่แล้ว +55

      I recall when I got into Math 251 Differential Calculus, I thought it was going to be some pretty insane shit, but it turns out we use it all the time without even realizing it. It's just so much more powerful if you know the fancy tricks. I cannot recommend enough that those who don't know at least differential calculus to learn it. You will not regret it.

    • @gogauze
      @gogauze ปีที่แล้ว +26

      ​@@nobody.of.importance*sigh* FINE. I'll go learn differental calculus this month.

    • @Nidhsa
      @Nidhsa ปีที่แล้ว +4

      @@gogauze im learning it in the fall

    • @nobody.of.importance
      @nobody.of.importance ปีที่แล้ว +5

      @@gogauze Knowledge is power! Good luck! Same for you Nidhsa c:

    • @juxyper
      @juxyper ปีที่แล้ว +3

      this is not only integrals, this is discrete integrals!

  • @metalstarver642
    @metalstarver642 ปีที่แล้ว +252

    Actually things get 100x more complicated if you have non-constant forces, you need to lookup numerical integration (initial value problem). Your recommended way is called Leapfrog integration. It can work really far from accurate if you have spring forces (with springs you need tiny timestep or other more sophisticated methods which usually are not suitable for real-time).

    • @astecheee1519
      @astecheee1519 ปีที่แล้ว +10

      I feel like springs are better expressed with approximations in games.

    • @drstrangecoin6050
      @drstrangecoin6050 ปีที่แล้ว +5

      Is a second order taylor series the wrong thing to do here?

    • @metalstarver642
      @metalstarver642 ปีที่แล้ว +5

      @@drstrangecoin6050 It depends. For springs or gravity (N-body sim) to get stable results Taylor series won't be enough. You would need implicit methods for accurate and stable results (too slow for real-time). But for games springs could be done without forces in more stable way (e.g XPBD). Stability of gravity forces usually not an issue unless you're doing Solar system simulations or the like (in which case parametrized elliptical orbits may be better option for game). For a game maybe first check implicit Euler and then XPBD if it fails, otherwise start faking it.

    • @ckjdinnj
      @ckjdinnj ปีที่แล้ว +2

      Implicit is used all the time in games.
      In fact they showed a common example in the video …
      velocity = velocity + acceleration * deltaTime
      position = position + velocity * deltaTime
      2nd order Taylor series is fine for most use-cases.
      If you have to support some wildly stiff springs or need a high degree of accuracy then you could try rk4.
      p0=initialPos
      r=restingPos
      v0=initialVelocity
      k=springStiffness
      dt=deltaTime
      m=mass
      f1=k*(r-p0) // force
      v1=dt*f1/m+v0
      p1=0.5*dt*v1+p0
      f2=k*(r-p1)
      v2=0.5*dt*f2/m+v0
      p2=0.5*dt*v2+p0
      f3=k*(r-p2)
      v3=0.5*dt*f3/m+v0
      p3=dt*v3+p0
      f4=k*(r-p3)
      v4=dt*f4/m+v0
      v_final=v0+(f1+2*f2+2*f3+f4)*(dt/m)/6
      p_final=p0+(v1+2*v2+2*v3+v4)*dt/6

    • @ckjdinnj
      @ckjdinnj ปีที่แล้ว +3

      Performance cost is relative as well. It’s all about scale of use. If you wanted a 3rd person spring arm camera and it needed to be super stiff/snappy one use of rk4 would be fine. However if you are setting up a dense foliage section where foliage physically interacts with the player then you’d probably just use a simple implicit approach with
      v_final=v0+dt*k*(r-p)/m
      p_final=v_final*dt+p0

  • @tommysedin
    @tommysedin ปีที่แล้ว +561

    6:50 I would say that it's not pointless to multiply by fixedDeltaTime; Makes it easier to code consistent units (say if you're trying to follow SI units strictly, or if you have calculations in both Update and FixedUpdate that should follow the same unit). Also, if you ever end up changing the frame rate of the FixedUpdate, you'll have to change every single calculation.

    • @JonasTyroller
      @JonasTyroller  ปีที่แล้ว +130

      Fair! :)

    • @zelos666
      @zelos666 ปีที่แล้ว +78

      The physics will actually break if you change Time.timeScale and don't multiply by fixedDeltaTime, because fixedDeltaTime will change with the timeScale. Meaning it's actually not always the same value, if you have any kind of speedup or slowdown with timeScale in your game.

    • @ThePhoenix107
      @ThePhoenix107 ปีที่แล้ว +32

      Just want to add that the code example did not need to be changed at all to be called for FixedUpdate. And that is because Time.deltaTime actually returns Time.fixedDeltaTime when called from within FixedUpdate.

    • @mrcreepypl
      @mrcreepypl ปีที่แล้ว +9

      @@ThePhoenix107 Cool to know, but I'll still stick with fixedDeltaTime for consistency and clarity.

    • @rhysvanderwaerden5518
      @rhysvanderwaerden5518 ปีที่แล้ว +8

      ​@@zelos666it actually is the other way. The fixed delta time stays the same, but anything running in fixed time will become more granular in real time because fewer fixed steps will occur between frames. This is why you might need to reduce your fixed time step for slow motion.
      If you are modifying your fixed delta time for this purpose then you definitely need multiply by it in fixed update.

  • @Randy14512
    @Randy14512 ปีที่แล้ว +628

    I don't code, but I am a physics nerd and saw delta time and it peaked my interest. Was not disappointed to see the explanations of calculating changes in distance as a function of time when not accelerating, when accelerating, and with a changing acceleration value. With the questions that were math based and not definition based other then syntax i am happy to say I got the idea right lol.

    • @superscatboy
      @superscatboy ปีที่แล้ว +65

      For future reference: It *piqued* your interest.

    • @oisyn-
      @oisyn- ปีที่แล้ว +102

      @@superscatboy Maybe his interest curve reached a local maximum, so it really did peak his interest.

    • @superscatboy
      @superscatboy ปีที่แล้ว +8

      @@oisyn- Or maybe that's just a load of old bollocks 🤷‍♂️

    • @baitposter
      @baitposter ปีที่แล้ว +10

      ​@@superscatboy
      Well, my interest definitely *peaked* when seeing the title of this video

    • @nathangamble125
      @nathangamble125 ปีที่แล้ว +22

      @@baitposter So your interest decreased when actually watching the video?

  • @jaredschneider9662
    @jaredschneider9662 3 หลายเดือนก่อน +10

    Someone needs to send this to Gearbox given the new Risk of Rain 2 update apparently commits several of these crimes.

  • @MrWolfheat
    @MrWolfheat ปีที่แล้ว +451

    I think that in the latest unity versions using deltaTime in fixedUpdate will automatically use the fixedDeltaTime internally so you do not need to change this. Unity implicitly understand which one to use by the context it is used in.

    • @CyberAngel67
      @CyberAngel67 ปีที่แล้ว +16

      it won't auto use the fixed delta time, the timing will just be identical.

    • @1vader
      @1vader ปีที่แล้ว +6

      It's not only in the latest Unity version. I recall hearing about this behavior at least several years ago.

    • @delphicdescant
      @delphicdescant ปีที่แล้ว +74

      Wow that's kind of terrible API design.
      Would be a lot better if using deltaTime in fixedUpdate were an error.
      Implicit/hidden behavior is an evil that you might expect to see in the realm of web dev frontend nonsense, but not in applications programming.

    • @DiThi
      @DiThi ปีที่แล้ว +42

      In my opinion, the best API design would be to have the delta time as argument to the update functions, that way it's impossible to mess it up.

    • @milanstevic8424
      @milanstevic8424 ปีที่แล้ว +9

      Unity's API design choices are notoriously bad. Thankfully once you learn all the shitty things and minefields it's full of, you can safely ignore it and build up your own software more robustly. But be warned, Unity is a hell to learn.

  • @JeanPhilippeBoucher
    @JeanPhilippeBoucher ปีที่แล้ว +23

    Jokes on you, I multiplied my grade by delta time and now I'm above the maximum!

    • @lFunGuyl
      @lFunGuyl 7 หลายเดือนก่อน +3

      Jokes on *you*! You multiplied your grade by a number almost certainly less than one! Your grade was lowered to a fraction of what it would've been!
      Unless you run with less than 1 FPS in which case the joke would again be on Jonas...

    • @JeanPhilippeBoucher
      @JeanPhilippeBoucher 7 หลายเดือนก่อน +1

      @@lFunGuyl I'll take the risk for a shot at glory!

  • @Ochros
    @Ochros ปีที่แล้ว +262

    21:50 From your testing scheme, it's actually possible to get everything wrong and also the -10 points, leaving you with a grading that is undefined according to your evaluation :P (if I didn't miss anything)

    • @Aeroxima
      @Aeroxima ปีที่แล้ว +35

      Negative F!

    • @Cynadyde
      @Cynadyde ปีที่แล้ว +74

      being undefined, there's every chance we hit a negative integer overflow and land on a grade no less than 150

    • @madmax404
      @madmax404 ปีที่แล้ว +37

      In this case I think you can just give yourself 4294967285 points

    • @EmersonPeters
      @EmersonPeters ปีที่แล้ว +15

      Spoken like a true game tester!

    • @Jonskipvp
      @Jonskipvp ปีที่แล้ว +4

      @@madmax404 the only winning move is not to play

  • @tcatdev
    @tcatdev ปีที่แล้ว +52

    When people misuse lerp you can really feel it in the gameplay. I did a little different than you though. I recorded the start position and start time, then I use the elapsed time to calculate the lerp factor in each frame.
    I also like using cosine instead of sqrt, because it gives a more natural feel. The formula is (1 - cos(x * PI)) / 2, where x is the elapsed time.

    • @bastian_5975
      @bastian_5975 ปีที่แล้ว

      Are you saying you did position = lerp(startingPosition, endingPosition, 1-cos(x*pi)/2)? Because that would cause it to go back and forth between the start and end, not approach but never reach the end.

    • @gajbooks
      @gajbooks ปีที่แล้ว +1

      @@bastian_5975 It should probably be cos(1/(x+2)*PI), which is really just a differently smoothed version of 1 - (1/(x+1)), where x is elapsed time in both scenarios. (There's an absolute ton of "sigmoid" functions you can use to infinitely approach a number.) The delta-time lerp works though, just it makes a little less sense logically because instead of lerping between two fixed points, you end up lerping between the destination and the previous location.

    • @bastian_5975
      @bastian_5975 ปีที่แล้ว

      @@gajbooks at first I thought you meant cos(1/(pi*(x+2))), but cos(pi/(x+2)) looks so much better that I think you mean that.
      And are you saying that the function you defined was a sigmoid function or that sigmoid functions are a class of functions that also achieve that effect?

  • @sammtavv
    @sammtavv ปีที่แล้ว +540

    I didn't know i always wanted a video from Jonas directly to the developers. Gotta love these videos!

  • @XoIoRouge
    @XoIoRouge ปีที่แล้ว +34

    I love the presentation of this video, with an actual test. The whole "YOU WILL BE GRADED JOKE" actually motivated me to do well on this test that no one will see. I've seen many youtubers educate with information, by just telling us the right answer, showing it in examples, with great animations to help visualize. That process works, but I think many content creators forgot how effective it is to challenge our knowledge. At 3:41, despite me using deltaTime in many places, I realize that... I'm not EXACTLY sure which of these four are true.
    Thank you for challenging my knowledge, and because of that, you've stuck out as a memorable youtube educator. I've subscribed and I look forward to learning more from you.

  • @Random-kj1go
    @Random-kj1go ปีที่แล้ว +62

    please we need more of thisss this is the exact technical info no one talks about and it even has a visualisation very good video 10/10

  • @klikkolee
    @klikkolee ปีที่แล้ว +31

    I'm going to contest question 2 based on the wording.
    The presentation of a frame can be conceptualized as happening at specific instant of time, but the game logic of a frame takes meaningful time to happen. If I just see phrases like "the current frame" and "the last frame" in reference to timing and without further indication, I will interpret that as referring to those spans of time. In the context of timing, frames have a start and an end, and that end is before the frame's presentation. Since each operation can be conceptualized as contributing to a specific frame, the end of a frame is the same as the start of the next.
    You don't know when the current frame will finish or when it will present, but you do know when it started. A game engine is going to use the most recent frame-time estimate it can, and that would be the time between the start of the current frame and the start of the previous frame. This is more consistent with the wording of option B than the wording of option A, and it is consistent with the wording in the Unity script reference for Time.deltaTime: "The interval in seconds from the last frame to the current one"

    • @rumbleball542
      @rumbleball542 9 หลายเดือนก่อน

      Thank you.

    • @Julianiolo
      @Julianiolo 8 หลายเดือนก่อน +1

      wtf this is exactly what I just wrote lol. With a lot more fancy words sprinkled in though

    • @modernmage
      @modernmage 6 หลายเดือนก่อน +1

      I agree, and was thinking along a similar line. The wording of those questions were just bad

  • @Ombarus
    @Ombarus ปีที่แล้ว +36

    Very impressed, you've covered many of the pitfalls. Just two remark: Fixed Update is useful to avoid costly exponent which are very common in Physics calculation because if you have a constant delta time then the linear approximation is good enough (so the "bad" lerp in a FixedUpdate would work just fine). The big drawback with FixedUpdate is that you'll usually notice "jerking" as one frame you'll update 3 times, but then the next frame only 1, then the next 2. Usually to fix this you need to extrapolate the difference between the current frame's deltatime and the FixedDeltaTime.

    • @nathanielguggenheim5522
      @nathanielguggenheim5522 ปีที่แล้ว +2

      Or avoid FixedUpdate() altogether and call Physics.Simulate() by yourself in Update() after disabling automatic PhysX Update. Actually the only method I know to avoid Unity's microstuttering.

  • @Bobsteperous
    @Bobsteperous ปีที่แล้ว +10

    Now THIS is the kind of tutorial i need, ive had enough of people just telling me what to put in to get my desired output, and i need that perfect level between talked to like a baby, and expecting im Einstein. You hit that nail right on the head.

  • @enreeper
    @enreeper ปีที่แล้ว +129

    Way back before I even knew about delta time I used to have my games code run at 120fps and didn't noticed any weird behaviour, but as soon as other players with 60hz displays played the game everything was in slow motion running at half the speed, they often commented the game feels slow and me and my friend playing at 120 allways wondered what do they mean until I realised this issue.

    • @DOSRetroGamer
      @DOSRetroGamer ปีที่แล้ว +8

      Lol

    • @JonasTyroller
      @JonasTyroller  ปีที่แล้ว +41

      Haha. Oh, no. :D

    • @blockify
      @blockify ปีที่แล้ว +7

      haha i too didn't realise for ages because since I never did anything big scale the fps stayed relatively consistent

    • @inkedalien
      @inkedalien ปีที่แล้ว +2

      same with us lol tested it out by racing each other in different refresh rates haha

  • @BicycleName
    @BicycleName ปีที่แล้ว +56

    For anyone interested in learning more about numerical integration, there's a whole range of other schemes you can apply which have different stability properties based on the deltaTime and the equations of motion of the players. Here at 8:22, if I can recall properly, he first uses Euler Forward then Euler Backward and after that, Crank-Nicolson. If you had a more complicated movement, you could as well switch to a spicier scheme (like Runge-Kutta) but it's propably over-engineering the task you're trying to achieve.

    • @Puukiuuki
      @Puukiuuki ปีที่แล้ว +5

      True, although this makes the difference between explicit (forward Euler) and implicit methods (backward E, C-N) appear very similar, since there is only a time dependence here. Normally you will need to solve a system of equations, which makes the thing inherently stable. A good example is the exponential speed case, where an explicit method can easily overshoot.

  • @APaleDot
    @APaleDot ปีที่แล้ว +152

    For those confused about the lerp section, I have a really easy way to think about it intuitively:
    If your "lerpSpeed" is 1, then the base of the exponent (the number on the bottom) is the portion of the distance you want to cover in one second. So in the video this number is 0.5 which means the character covers 1/2 the distance to the goal every second. The reason this works is because when you do this multiple times in a row, the distance decreases exponentially. So, if you imagine your frame rate is 4 frames per second, then in the first frame the character covers 0.5 ^ 0.25 of the distance (because deltaTime is 0.25), and the next frame the distance will be less but they will still cover another 0.5 ^ 0.25 of _that_ distance. So the total distance covered will be (0.5 ^ 0.25)(0.5 ^ 0.25), which if you remember your exponent rules is equal to 0.5 ^ 0.5. In other words when you exponentiate like this, the deltaTime in the exponent adds linearly every time you lerp. In this example, if you lerp every frame for one second (that is 4 frames) then the exponent adds up to 0.5 ^ 1. In other words, you cover half the distance in one second, regardless of your deltaTime, as I stated in the beginning.
    EDIT: as explained in the replies, the base of the exponent actually represents the portion _remaining_ after 1 second, not the portion covered after 1 second, because you start at t = 0 which would give a blend value of 1, so we use 1 - 0.5^t instead (or Jonas puts the current position in the second parameter of lerp, which is equivalent)

    • @NXTangl
      @NXTangl ปีที่แล้ว +3

      For this reason, I would use Math.Exp(-lerpSpeed * deltaTime).

    • @pixelz3040
      @pixelz3040 ปีที่แล้ว

      Just want to point something out here, cause this kinda bothered me. You are correct in that the reason for the deltaTime being in the exponent is so that they add to 1, but the total distance covered is NOT just the product of the blends. You can easily see this if you use a base other than 0.5.
      Assuming you have the function laid out like Jonas did, where the target position occurs when the blend is 0, then the position of the snail after n frames is going to be (target_position)(1 - (product of all the blends)). You can deduce this through induction with the lerp function. Lets say that our blend is 0.1 ^ 0.25, where the 0.25 is our deltaTime, just like in your example. Initially, the snail's position is 0. After 4 frames, or 1 second, the snail's position will be (target_position)(1 - (0.1 ^ 0.25) ^ 4) = (target_position)(1 - 0.1) = 0.9(target_position). After 4 frames, the snail moves 90% of the distance, not 10% as you implied.
      Fundamentally, what you're saying is helpful, but I saw the comment and got caught up on that snag for a while, and it kept me from truly understanding what was going on. Also, I agree with @NXTangl, using the built in exponential function is nice because then you don't have that arbitrary base and the speed is more directly controlled by lerpSpeed.

    • @feha92
      @feha92 ปีที่แล้ว +1

      > So in the video this number (lerpspeed) is 0.5 which means the character covers 1/2 the distance to the goal every second
      No, in the video you cover 0.3 of the distance every second because of that number (lerpspeed) being 0.5.

    • @APaleDot
      @APaleDot ปีที่แล้ว

      @@feha92
      No, "this number" refers to the base of the exponent, which is 0.5 in the video. I also say that I'm setting lerpSpeed to 1 for simplicity. lerpSpeed is also 1 in the video IIRC, so I'm not sure how you mixed that up.
      Edit: actually, lerpSpeed is 0.5 in the video, so it makes sense you got mixed up. But I still said "if lerpSpeed is 1".

    • @APaleDot
      @APaleDot ปีที่แล้ว

      @@pixelz3040
      You're right, the base of the exponent is the portion _remaining_ after one second, not the portion covered. Those two numbers just happen to be the same when the base is 0.5, my bad.
      I personally still like to use the arbitrary base because the meaning of the base is clear when the exponent is 1, and I don't want to think about a base of 1 / 2.718. lerpSpeed controls the speed the same way in either case.

  • @legendgames128
    @legendgames128 ปีที่แล้ว +4

    2:20 Well, arguably, Betty has the advantage here, because as she and Jerry go really far distances, Jerry is changing his x position by a very small number, which gets essentially zeroed out as he loses precision, meanwhile, Betty can keep going for a bit longer, since she is adding a bigger number to her x position, thus precision takes longer to catch up with her.

  • @Zicrus
    @Zicrus ปีที่แล้ว +57

    3:48 This could actually be A or B depending on your definitions. I picked B, because it's the time between when the current frame started being processed and when the previous frame started being processed. If your definition for the time of a frame is when it is done processing, then A is the correct answer. I view the start of the frame as the true time, since that is also when inputs are registered, so the actual frame that is being displayed is slightly behind, not the other way around.

    • @mcarr87
      @mcarr87 ปีที่แล้ว +24

      Just to add on to your comment, the video is wrong here as per reasonable definitions. The term 'current frame' always refers to the one you're currently processing. 'deltaTime' is calculated at the start of the processing of the current frame by comparing the time to the time the previous frame began processing. deltaTime is essentially how long the last frame took to process from start to end (where 'end' is the start of the current frame).
      "Time elapsed between the last frame and the one preceeding it" is a not a good definition of deltaTime because the frame before the last one has no relevance. The current frame's deltaTime value is calculated in the current frame and not at the end of the previous one. As per Unity's own documentation for Time.deltaTime it says it's "The interval in seconds from the last frame to the current one".
      I believe the error is largely due to representing frames as a point in a timeline when something is rendered on the screen. At some time, typically very shortly after that rendered frame point on the timeline, the deltaTime value will be calculated. The only relevant frames in the calculation is the previous frame and the current frame.
      Carrying on from this the video then describes deltaTime having a "1 frame delay" which is also stated and described confusingly. Obviously deltaTime is not going to be related to how slow the current frame is because it can't predict the future. So the best value it actually could be: the previous frame's calculation time, is essentially what it actually is. Describing that as a "1 frame delay" doesn't really make sense.
      Obviously here the video is referring to deltaTime in relation to something moving on screen and pointing to how the object moves only a little bit on screen on the frame that took a long time and then has the larger jump on the next frame. Saying that "deltaTime always has a 1 frame delay" because of this particular example is not reasonable. deltaTime is not delayed, it is the correct value for when it was calculated. Nothing prevents a programmer from calculating their own deltaTime equivalent value and moving objects with that right before rendering. Time.deltaTime is not delayed, you have just chosen to use it in a way that gives a result that you refer to as having a delay.
      If anyone was confused by the 1 frame delay part of the video and curious, the way the deltaTime value would work after a slow frame is is:
      If a game was running at 60FPS on Frame A, Frame B's deltaTime would be ~0.0166s. That's how long it was from the start of Frame A to the start of Frame B.
      If Frame B was then slow and took 0.1s (10FPS) to complete, Frame C's deltaTime value would be 0.1s
      Basically the frame after the slow frame would see the larger deltaTime value.
      Not a bad video otherwise, but that section in particular I think would be very confusing to programmers trying to learn about deltaTime. I believe conceptually it's essentially correct, but by representing frames in relation to deltaTime in that way and slightly misrepresenting when deltaTime is calculated it makes something fairly simple much more confusing.

    • @technorazor976
      @technorazor976 ปีที่แล้ว +2

      I understood it that way too, thanks for confirming! +10 points to me!

    • @mcarr87
      @mcarr87 ปีที่แล้ว +5

      And I just want to say that I don't like leaving some big comment like that, I just needed to write that much to explain everything.
      Obviously Jonas seems to be great at what he does and has made an excellent video. I know I'd hate making videos like this because it'd be very had to not make errors or poorly represent some things even if you know them well yourself in reality. I'd not want to have to see comments like mine above, but know that it's only left in the interest of helping clarify those elements from the video for anyone confused or off-put by them.
      I'm sure you (Jonas) understand what I've explained yourself and just (in my opinion) didn't express them adequately in that small part of the video.

    • @Gamesaucer
      @Gamesaucer ปีที่แล้ว +4

      @@mcarr87 Your comment is far more confusing than the video is. There are a few reasons for this.
      Firstly, there are two entirely contradictory definitions of a "current frame" at play here, which you don't seem to realise. On their own, both definitions are valid, but the one you present here has some issues in its broader context.
      You seem to define a "frame" as the routine that runs to produce it. In that sense, the current frame is indeed the one you're processing. But then a frame is a process and not a point in time. This contradicts with the definition of deltaTime in the Unity documentation you quoted, "The interval in seconds from the last frame to the current one". That one notably _does_ define a "frame" as being a point in time, as evidenced by it not saying "from the _start_ of the last frame".
      One important problem with your definition is that updating the game state is not linked to visuals whatsoever. A game could poll for inputs twice as often as it renders a new frame. These are still two game updates, but there is only one frame rendered. If you define a frame as a process, you'd have to exclude the time spent updating the game state, and only include the rendering time. But that's demonstrably not the value that deltaTime contains.
      The other definition of a frame is "the image being shown on the screen". This is a far more intuitive definition, and how most people understand such terms as "fps". There are 60 images being shown to me per second. And whatever is being shown to me at any given time, is the "current" frame. This frame is shown to me all at once and does not change afterwards until the next frame arrives. Thus, the moment it appears on my screen is a single point in time and not a process.
      Reading the definition of deltaTime again, this makes a lot more sense. Because the "current frame" is what you just finished. And deltaTime is indeed the space between those points in time by all definitions.
      You say that the way this definition is worded in the video is inaccurate, but that is simply not true. "Time elapsed between the last frame and the one preceding it" is a perfectly valid way of describing it, so long as you take "last" to mean "most recent" over "previous". The current frame is the most recent frame, and therefore the current frame can also be described as the last frame. This is not a strange way to use English, and should not be confusing for someone who speaks the language well enough to watch English videos on TH-cam and writes English comments.
      Additionally, I strongly disagree with that a "1 frame delay" is a bad way to describe what happens. Of course, the variable itself isn't delayed. Because it's defined with that delay already built-in. If I told you what I ate yesterday, my statement isn't delayed by one day. But that doesn't mean that your knowledge of what I ate isn't!
      The latter is the "delay" the video refers to. The example is clear about this as well: the frame shown after the lagspike does not take the lagspike into account exactly because that frame is being calculated as if it will render in the same amount of time that the last frame did. Regardless of what you're actually building, it is theoretically impossible to react within 1 frame to the time it takes to render just by reading the deltaTime variable.
      In short, it takes exactly one frame before you can react to how long a frame takes to render. I'd like to ask what you would describe this effect as, if not a "1 frame delay." This description has nothing to do with motion; it's a factual description of what you observe when you look at the game frame by frame. It takes one frame to adjust to a frame taking longer to render. You cannot adjust immediately. This is the definition of a delay.
      Don't get me wrong, I agree that there are ways in which the video could have been clearer. I just don't think that the things you take issue with are the problem, and that the alternatives you provide make things less clear rather than more clear.
      What the video really needed is not a change in definitions, but a more precise and consistent use of language. "Last" and "current" typically have the same meaning, but it'd be clearer if you stuck to one. It'd also be helpful to distinguish a "frame" as what's being shown, from an "update" as being the process to create it. And possibly a few other similar things. The content and presentation itself is fine and doesn't need to be changed, the script for the video really just needed one more editing pass.

    • @mcarr87
      @mcarr87 ปีที่แล้ว +13

      @@Gamesaucer I appreciate your arguments and while I don't disagree that much of this depends on your particular definition, I don't agree that in this context of programming the definition of 'current frame' would only refer to the frame most recently output to the GPU. While not used too commonly as a direct term in the Unity docs and variables, you'll only find "current frame" referring to the one currently being processed that would next render (e.g. OnDemandRendering.willCurrentFrameRender) unless referencing something selected in a timeline like in the Profiler. Also I was directly referring to where the video's uses the phrase "the frame currently being processed".
      I 100% agree that a frame can and often does refer simply to the image presented to the screen, and the duration of that image on the screen in a standard, single buffered game would be determined by how long the following frame takes to update and render. That's not in question.
      But you bring up a great point that I didn't bother with because I'd already written too much before, and that is how a game could have multiple Updates without rendering a frame if it wanted. Alternatively you could have things like double or triple buffering that could delay the rendering of a frame until after other queued frames had rendered. To me, both of these are great arguments for my point.
      First, going off your concept, lets say you're in Unity with a disabled Camera object and you manually called Render() every 3rd frame. Here you have 3 Updates over 3 frames (as per Unity's definition of a frame. See e.g.: "Update[()] is called every frame") where only 1 of them is something drawn to the screen. You also have 3 different deltaTime values across those frames, 2 of which can't be said to have any relevance to what was drawn on screen last.
      You could also run your game's multiplayer server without rendering anything ever and it still has deltaTime and what most refer to as a frame rate (including Profilers, etc). You could argue that without rendering anything there is no 'frame rate' if you wanted, but that only diminishes your arguments because deltaTime still exists and is still calculated in the way I said it was without any relevance to what was drawn or if anything was drawn at all.
      The same type of example can be given for multiple buffering of frames where the deltaTime does not relate to what was last drawn on screen.
      I don't think in the context of programming your point "the moment it appears on my screen is a single point in time and not a process" has much validity. For one, saying a frame is a point in time doesn't really relate to the concept being discussed which is to do with the duration of a frame. Secondly even if you were to try to talk about it as a singular moment in time, what moment is that? When the LCD monitor draws the first line or the CRT's electron gun starts emitting or when the end of the image is finally displayed? What if the frame rate is faster than the monitor and it never finishes?
      I know that's overly pedantic, but it's just to illustrate that that is not a consistent or really even well definable thing and doesn't actually relate to actual programming and deltaTime.
      I don't really want to continue, but I'll quickly address your points on "1 frame delay" which I also find a bit odd.
      Saying what you ate yesterday is completely different from deltaTime. When deltaTime is calculated by Unity when a new frame begins processing, that is not a value telling you about something from the past. That is an immediate, current time difference between right now and back then. If it's referred to on the next line it's extremely current and relevant. You could say it's less 'current' later in the frame processing, but that depends entirely on how it's used. This is why I mentioned how you could use your own delta time calculation for rendering if you really wanted something more current for the frame you're processing than deltaTime.
      To say it has a delay is to proscribe a very weird definition to it. It is what it says it is and it does not give a delayed value at any point after its value is set. It's always 100% accurate as per what it is defined as being the value of. You know immediately at the start of processing a frame what the time the last frame took, there's no delay. That's the point of the value. To say it has a delay would be to give it the definition of "this is how long this frame will take, but you won't know until next frame because it has a 1 frame delay".
      I feel like this sort of discussion comes across as antagonistic and I apologise if it comes across that way. I also expect this could be one of those things where it's an ongoing back and forth, but I don't want to do that. I will freely admit that there's validity to the video's way of putting it and taken with certain definitions it's not wrong. This is what I said in my original post. I just don't believe in the context of programming, which this is, it was stated in the most valid and coherent way.

  • @baralike8206
    @baralike8206 ปีที่แล้ว +3

    I think this is a great subject and something that many lack a good understanding of, but in my opinion this video too shows a lack of understanding of deltaTime.
    My biggest problem with this video's explanation of deltaTime arises in the explanation of why alternative b) is wrong in the first question (around 4:18). This video seems to present the idea that a frame should represent what the state of the program is when the frame is presented, while in reality, a frame represents what the state of the program was when the frame's update function began (when deltaTime was measured, to be precise). This means we're not using "the last frame's deltaTime as an approximation for the current one's," we are instead rightfully using deltaTime as the time between the last update call and the current one, because that gives us the state of the program at the time of updating.
    This also means that deltaTime does not "always have a 1 frame delay" (5:34) as an explanation for why lag spikes are 1 frame off. Instead, the state of the program that a frame is presenting is always at a 1 frame delay from the current state of the program. There is no special feature of deltaTime making it 1 frame behind.
    Furthermore, in any well-designed double-buffer renderer, the previous frame should be drawn on the gpu while the current frame is updating on the cpu. Once updating has completed, the previous frame is presented as the current frame, making the presented frame TWO frames behind the current state of the program. (+1 for every additional frame buffer)
    Other than that, I think this video explains things well and was fun to watch. A quick point to make is that for the explanation of the last question, the idea is presented that an exponential function is essential to achieve the desired result, while any function beginning at 0 and approaching 1 would work, such as 1 - 1/(1 + deltaTime * lerpSpeed), removing the need of Math.Pow.
    I guess I'll come across as another know-it-all, but I just wanted to share my understanding of the topic and I'll be happy to discuss it further!

  • @Pontypants
    @Pontypants ปีที่แล้ว +13

    I am one of those. I know everything. No need for pen and paper. I already know. Even what I don't know I know... And then some..

    • @_sIash
      @_sIash 3 หลายเดือนก่อน

      it feels like you're a creator of a game called A difficult game about climbing

    • @evan_game_dev
      @evan_game_dev 3 หลายเดือนก่อน +1

      ​@@_sIashI kinda feel like he's the creator of a game called punch a bunch

  • @IvanLeben
    @IvanLeben ปีที่แล้ว +92

    There is actually another layer of complexity here, which even experienced games developers often miss: regardless of how much time has passed between your consecutive update calls, the monitor typically can only present images spaced at a fixed interval from each other - the refresh rate of the monitor. The only exception here would be if you are using a variable-refresh monitor with a GSync or FreeSync technology. If you are updating your game with variable deltaTimes, but presenting those frames on the screen at a fixed rate, you will create what we call "microstuttering". The animation will overall keep correct pace with the wall clock, but it will appear jerky, unsmooth. Unless you are using GSync, you should only ever update your game in increments that are a multiple of the monitor refresh rate and then tell the rendering system to present these frames at the correct time in the future - if you are updating the game for X milliseconds, then the frame you've generated should be presented exactly X milliseconds from when the previous frame was presented. This technique is callled "frame pacing" and fixes microstuttering. Note that modern game-engines like Unity and Unreal might automate frame-pacing for you behind the scenes, by feeding you deltaTimes and presenting the frames as appropriate (support might also depend on the platform you are shipping the game on).

    • @wakannnai1
      @wakannnai1 ปีที่แล้ว +10

      If your engine is developed properly, DeltaTime should be tied directly to the update of a frame. Most modern engines (Unreal Engine, Unity, and most AAA Engines) tie DeltaTime directly to the update of every frame. This by definition means that each tick is tied to the update of a frame.
      In the scenario you presented this is not what happens. If your actual frame update is not in sync with your refresh rate on your monitor, you'll typically see frame tearing (since almost all engines will queue at least a frame in advance in the back buffer and update the screen on each refresh). Screen tearing happens since the new frame that was in the process of rendering in the back buffer is being pushed to the screen in an incomplete state.
      Microstuttering really happens when you're close to the target refresh rate. Since there's some variability in each frames workload (both on the CPU and GPU), frame completion may not fall exactly on the expected interval to update (ie 1 frame may have taken 17ms rather than 16.5ms to complete rendering). In order to avoid this, a lot of devs will try to exceed performance from the target enough to minimize Microstuttering. It has nothing to do with updating your game with variable DeltaTimes. It has more to do with frame consistency.

    • @modernmage
      @modernmage 6 หลายเดือนก่อน

      screen tearing is what I call it

    • @jonpatchmodular
      @jonpatchmodular 5 หลายเดือนก่อน

      If I'm understanding this properly, you're talking about the need for vertical synchronization or VSync, right? I'm pretty sure you can actually toggle it on or off in the project settings in Unity, and I assume the frame pacing will be taken into account when calculating deltaTime. I do believe it should be the engine's job to get that working properly, you shouldn't carry that burden during the game programming phase.

  • @mathijsfrank9268
    @mathijsfrank9268 ปีที่แล้ว +29

    It is called FixedUpdate, but that doesn't mean it is actually 100% fixed. It tries to run in fixed intervals. However this will never be exactly right, either because of cpu cycles or if a fixed update exceeds its time budget. This will most likely be insignificant in most cases, but there is still a reason to use fixedDeltaTime for this.
    For example if you run physics in this fixed update and it always takes just a tiny bit longer than expected, the error can add up over time and without fixedDeltaTime it might explode your physics.

    • @JonasTyroller
      @JonasTyroller  ปีที่แล้ว +11

      That's a useful addition. Good to know.

    • @chocolate_maned_wolf
      @chocolate_maned_wolf ปีที่แล้ว +1

      @@JonasTyrollerthis comment should be pinned tbh

  • @LethalChicken77
    @LethalChicken77 ปีที่แล้ว +7

    You actually do want to multiply by fixedDeltaTime in FixedUpdate a lot of the time, to ensure that your speeds are in units per second and the numbers in the inspector actually have meaning. It's also needed for more advanced custom physics, used in the integrations.

  • @JonasTyroller
    @JonasTyroller  ปีที่แล้ว +19

    Which grade did you get? :D

    • @Alithegamer99
      @Alithegamer99 ปีที่แล้ว +1

      Please when is thronefall dropping on PS4

    • @ngoclangthi7442
      @ngoclangthi7442 ปีที่แล้ว +1

      I got grade c! (Being a beginner programmer that can't even make a simple player movement script lol)

    • @jpratt8676
      @jpratt8676 ปีที่แล้ว

      F, because I didn't write down my points. I did okay but it counts for nothing :P

    • @Pixel-fish
      @Pixel-fish ปีที่แล้ว

      F i got 10 in the second question and ten in another and then lost ten

    • @veritas7010
      @veritas7010 ปีที่แล้ว +1

      Grades are of no importance

  • @xian7221
    @xian7221 3 หลายเดือนก่อน +9

    Someone please show this video to risk of rain's game devs

  • @pixstatic200
    @pixstatic200 ปีที่แล้ว +102

    Using deltaTime in FixedUpdates still makes a lot of sense, since you often want to keep your velocity as meters/second rather than meters/(fixed update interval)

    • @JonasTyroller
      @JonasTyroller  ปีที่แล้ว +42

      Agreed. Only if you use fixedDeltaTime, though, otherwise the game dev gods are gonna cry.

    • @lhilbert_
      @lhilbert_ ปีที่แล้ว +34

      @@JonasTyroller Although when Time.deltaTime is called from inside FixedUpdate, it returns Time.fixedDeltaTime anyways (at least in Unity).

    • @mogaming163
      @mogaming163 ปีที่แล้ว +1

      isn't it the same if you multiply velocity increases by fixed update interval since a game at 30fps/s at 15m/s is 15/30 = 0.5 meters/frame

    • @JonasTyroller
      @JonasTyroller  ปีที่แล้ว +24

      @@lhilbert_ Oh, does it? Shame on me for not knowing that. That makes sense I guess. Oops-dee-doops. :D

    • @Floky
      @Floky ปีที่แล้ว +23

      @@JonasTyroller -10p!

  • @3141minecraft
    @3141minecraft 11 วันที่ผ่านมา +1

    20:24 you don't need integrals for average speed. You can get the average speed from the distance-time graph.

    • @SpectreNoodle
      @SpectreNoodle 3 วันที่ผ่านมา +1

      you're never gonna believe what the integral of the speed vs. time graph is bro

  • @cyzaine
    @cyzaine ปีที่แล้ว +171

    As a Godot user, I love that this just explains the concepts. Doesn't matter what the engine is! I felt I kinda knew all this, but it's presented so well I feel I learned something anyway.

    • @lukkkasz323
      @lukkkasz323 ปีที่แล้ว +21

      yeah, btw for those that don't know, the equivalent of FixedUpdate() in Godot is _physics_process().

    • @DevDoge_
      @DevDoge_ ปีที่แล้ว +10

      ​@@lukkkasz323isnt it _physics_process(Delta)

    • @nobody.of.importance
      @nobody.of.importance ปีที่แล้ว +7

      Yeah, thankfully stuff like this is pretty engine agnostic. Once you know how one engine works, a lot of it is easy to carry over to others, at least from a technical perspective.

    • @anyapeanutlover
      @anyapeanutlover ปีที่แล้ว +3

      I'm also a Godot user, and I know that Update() is "_process(delta)", and FixedUpdate() is "_physics_process(delta)"

    • @RADkate
      @RADkate ปีที่แล้ว +1

      ive also never seen someone mult everything by delta time in a godot tutorial

  • @descai10
    @descai10 ปีที่แล้ว +4

    19:50 I generally find it better to just use deltaTime alone as the exponent rather than multiplying by a lerp speed. This way you can adjust the 0.5 to whatever ratio you want the lerp to reach each second.

  • @routeone4790
    @routeone4790 ปีที่แล้ว +85

    This needs to be turned into a series to help new people to understand more on coding.

    • @battalll
      @battalll ปีที่แล้ว +5

      i dont think this has to do anything with coding. more like high school physics and how delta time on game engines work with a very very simple explanation.

    • @afriendlyfox
      @afriendlyfox ปีที่แล้ว +4

      @@Fix-- Why did you get scared away? If you didn't understand anything, I want to say that it's completely normal for a newbie to not understand like 70% of the video. To be able to take something from this video, you need to have basic knowledge of C# (at least be able to write a quadratic equation solver), basic knowledge of Unity (at least what GameObject is, what MonoBehaviour class and its methods are and a rough idea of how physics work in Unity), a good school level math and some calculus knowledge. Besides, you have to have tried to make a character move to encounter the problems Jonas is talking about.

  • @Harteavecmoi
    @Harteavecmoi 20 วันที่ผ่านมา +2

    12:54 any physics textbook will tell you that x(t) = x0 + v0*t + 1/2 * a * t^2

  • @MatthewCoder
    @MatthewCoder ปีที่แล้ว +13

    You think I'm using delta time incorrectly?
    Well jokes on you, I'm not using it at all.
    If the game lags, everything goes in slow motion and a pop up appears to insult the player's setup

    • @squirrrrrrrrel7483
      @squirrrrrrrrel7483 ปีที่แล้ว +1

      lol

    • @JonasTyroller
      @JonasTyroller  ปีที่แล้ว +6

      Genius solution. We should all start doing it like that!

    • @MatthewCoder
      @MatthewCoder ปีที่แล้ว

      @@JonasTyroller just finished the video, it was greatly informative and entertaining, thanks Jonas! Sorry about the meme comment hahahaha

  • @Waffle4569
    @Waffle4569 ปีที่แล้ว +1

    6:05 Objection! The developer may want to change the physics framerate in the future. If you do not account for dt, you'll have a lot of fires to put out every time you change the physics timestep (which some assets actually require). Time.deltaTime will automatically return Time.fixedDeltaTime in FixedUpdate.

  • @ThiagoJaqueta
    @ThiagoJaqueta ปีที่แล้ว +10

    The reason why fixedDeltaTime exists, is that you'll be able to change the rate of fixed updates per second. By default unity uses 50hz, but you might wanna increase or decrease this value depending on your project. If you don't multiply your values by the delta, changing the rate in [Edit > Settings > Time > Fixed Timestep] will result in the physics running faster or slower than intended.

    • @Pixelhurricane
      @Pixelhurricane ปีที่แล้ว

      yep absolutely, once was having issues with the precision of physics collisions in a project I was working on so I had to bump up the fixed update rate to help solve it. I use fixedDeltaTime in my workflow for exactly cases like that, I might have had to rewrite weeks of code otherwise

    • @rhysvanderwaerden5518
      @rhysvanderwaerden5518 ปีที่แล้ว

      You can even modify fixedDeltaTime at runtime.

  • @dylanjohnmusic
    @dylanjohnmusic ปีที่แล้ว +2

    BRO I HAD NO IDEA ABOUT ANY OF THE FIRST PART AND THEN I GOT THE 50 POINTS 😭

  • @RobLang
    @RobLang ปีที่แล้ว +54

    *screams in multiplayer*
    Love this video, Jonas. Beautifully explained. Would love to see more like it!

    • @magnusm4
      @magnusm4 ปีที่แล้ว +4

      Please elaborate. I've wanted to implement multiplayer in the future so any hiccups or things to consider is really useful.

    • @aleksapetrovic7088
      @aleksapetrovic7088 ปีที่แล้ว

      .

    • @IONProd
      @IONProd ปีที่แล้ว +3

      @@magnusm4 multiplayer you can't just use deltatime for each pc because everything needs to be synced. So you need a main computer (which could be a player too) that does the calculations, and the players' pcs need to display that information. But frames can't be involved in the calculations of the variables, otherwise things would move really weirdly. You need the numbers sent to the pcs, and the pcs to render that information using deltatime, because you need to get the correct number for that point of time based on when the individual player's frame renders. And the rendering calculations are gonna need to be precise otherwise objects are going to appear in the wrong spot because if the calculation is off the number on the server is still correct, but it's displayed incorrectly on the player pc.

    • @Kenjuudo
      @Kenjuudo ปีที่แล้ว +1

      ​@@IONProdAnd this is the reason why so many beautiful indy games lack multiplayer support. It's really hard to do properly.

  • @Stratelier
    @Stratelier ปีที่แล้ว +1

    My go-to example of why you might need integrals to handle varying delta intervals is:
    - Imagine you have a simple homing missile/enemy tracking the player.
    - It travels at a constant speed but can adjust its heading by up to 180 degrees per second.
    - At a stable 60fps, that means 3 degrees per engine tick; at 30fps, 6 degrees per tick.
    - What if there's a sudden lag spike and the next tick has a delta of, say, just 3fps? If you updated its movement simply as (adjust heading) then (increment position) this lag spike enables the projectile to change its heading by _60 degrees in a single tick_ which (under certain edge cases) can allow it to successfully target the player in a position that would (under normal conditions) be slightly outside its defined turning rate.

  • @lucaheft
    @lucaheft ปีที่แล้ว +4

    I dont think your right with the assumption that deltaTime lags behind 1 frame. Unity docs also state, that it's "The interval in seconds from the last frame to the current one".
    So it's basically the time since last frame to the start of calculation of the current frame.
    I briefly tested by logging Time.deltaTime ,Time.time and Time.frameCount. If you press Play in "Paused" mode you can see for the first frame the deltaTime is 0 but for the second frame you will get the correct deltaTime. If the deltaTime would be delayed by 1 frame you should see 0 for the first two frames. As there is nothing to compare against.
    Interestingly Unity seems to be buggy in regards to the deltaTime. If you don't start with Pause enabled, you somehow get a deltaTime > 0 in the first frame. Also if you do start in Paused Mode but disable it after stepping a few frames. You will somehow get a deltaTime of 0 at the frame you disabled paused mode ¯\_(ツ)_/¯

    • @APaleDot
      @APaleDot ปีที่แล้ว

      I think this is an ambiguity with the phrase "current frame". In the video, he means the frame that hasn't been displayed yet, and the "start" of that frame is when it is displayed. But most game developers think about the "start" of the "current frame" as when the previous frame ended and the frame is displayed at the "end" of the frame rather than the "start".

  • @apalladium5k
    @apalladium5k 9 หลายเดือนก่อน +1

    Creating and using test functions to visualize your code is so much more satisfying than most people realize.

  • @TheShelfman
    @TheShelfman ปีที่แล้ว +19

    Thank you for your service professor Jonas😎

  • @rightwingsafetysquad9872
    @rightwingsafetysquad9872 ปีที่แล้ว +1

    Using the mid point to calculate the average on an exponential function should be sufficiently accurate unless your frame time is extremely large. I do it for IRL ballistics calculations with an assumed time interval

  • @Strong256
    @Strong256 ปีที่แล้ว +4

    Mans violated my last braincell after clapping for nobody at 12:50

  • @Julianiolo
    @Julianiolo 8 หลายเดือนก่อน +1

    Umm aschually b) is the right answer to the deltaTime question (3:26). The docs say: "The interval in seconds from the last frame to the current one (Read Only).". I guess this is what you meant, but how I read it, a) is not correct. This confusion probably stemms from what you define as the "current frame": The one being calculated or the one being shown? I guess in that regard the docs are also somewhat unclear. What afaik actually happens, is that deltaTime is the time between the start of the last rendered frame and the start of the currently being rendered frame.

  • @allenhalsted4895
    @allenhalsted4895 ปีที่แล้ว +33

    I have been developing games since the 1980s and have built several game engines from scratch. So I didn't really learn anything today, but I think that Jonas did an excellent job of explaining the concept. Keep up the good work!

  • @weonadomicilio398
    @weonadomicilio398 10 หลายเดือนก่อน +1

    A. I mean, it's pretty simple. The first thing you learn about deltaTime is what it is (but I know that lots of people just rush things up to make games quicker). The rest of the reasoning flows from that

  • @_stephenhubbard
    @_stephenhubbard ปีที่แล้ว +5

    TH-cam game dev eduction needs more videos just like this! Really great format.

  • @bluefake_or_smt
    @bluefake_or_smt ปีที่แล้ว +2

    19:27 I had as a solution:
    float elapsedTime;
    void Update() {
    elapsedTime += Time.deltaTime * someMul;
    transform.position = Mathf.Lerp(startPos, target, 1 - 1 / elapsedTime);
    }
    I was hela confused when you presented your solution, but then saw you used transform.position instead of startPos. It would work if the startPos is set, but your solution doesn't need that and is therefore still better
    Edit: Looking back I see the issue that you should probably split the Time.deltaTime-adding in 2 halfs

    • @Spelo1
      @Spelo1 ปีที่แล้ว

      Same thing, was hella confused when he didn't put in a time counter until I've noticed that the start position is not a constant one

  • @louisdalibard818
    @louisdalibard818 ปีที่แล้ว +5

    Great video! However, wouldn't 19:49 still be wrong though since you are just using the deltatime for each frame and not a sum of all previous deltatimes?

    • @MichaelDarrow-tr1mn
      @MichaelDarrow-tr1mn 9 หลายเดือนก่อน

      The lerp is from the current position, not the starting position.

  • @KulaGGin
    @KulaGGin ปีที่แล้ว +1

    0:30 Ok, Ok, I got the pan and the notepad++, I'll pass ur test.
    1.
    float NumberOfTicksPassed = DeltaTime / GameTickTime;
    position.x += SpeedPerTick * NumberOfTicksPassed;
    Gonna be same speed no matter the rendering frames per second or game tick update rate(Hz).
    2. B).

  • @MythicLegionDev
    @MythicLegionDev ปีที่แล้ว +6

    Thank you for this cursed knowledge Jonas

  • @TimeWisely
    @TimeWisely ปีที่แล้ว

    OOOOOF 15:42 this is the exact thing that got me to quit Unity... I had no idea I was doing it wrong, the tutorials were always showing this type of thing, so I always thought it was right, dang. I learned something today, thanks Jonas.

  • @SpaceMushroomAdventures
    @SpaceMushroomAdventures ปีที่แล้ว +9

    The amount of work put into this video is insane! I am not even interested in deltaTime, but I am still watching

  • @CellarPhantom
    @CellarPhantom ปีที่แล้ว +2

    Interesting. My biggest takeaways were
    • The 1 frame delay
    • Splitting up speed calculation on two steps (before and after applying movement) for better accuracy
    • Exponential formula in lerp (I'm actually still confused why it can reach the destination with that method - and my way would be to add some IF-statement when close and snap it into final position)
    Edit: interesting use of lerp too as stands for linear interpolation, but because he changes the "start position" each frame it does not become linear anymore. I guess it's still legit!

  • @madmax404
    @madmax404 ปีที่แล้ว +3

    Thanks for the Lerp fix! This is something I pretty much gave up on after I realized the solution would be a easy to mess up, and almost completely just changed to using spring-damp systems, though partially because they're also often just better.
    Though I'd say that the "simple" solution to calculating per-frame movement deltas is not ok 9/10 time but probably closer to 99/99.9% of the time.
    I've never actually brushed against it but have had a lot of pain due to different update rates simply ending up with different results, and inconsistent amounts of FixedUpdates causing frame pacing issues. For the Xbox One port of Thief of Thief for example, I ended up doing a hack that connects Update and FixedUpdate rates as long as they don't want to be too far from each other and managed to remove almost all frame pacing issues (which were bad otherwise) from the game.
    I've had to do this only once, but I had a sprint-joint system smoothly controlling the camera in Among The Trolls. If the framerate got REALLY bad, the system went completely out of whack. So for that I implemented custom sub-stepping where the calculation was always calculated with an almost non-changing deltatime but just repeated enough times during a frame if the framerate was bad. This is how FixedUpdate also works in essence, but with FixedUpdate this can cause those cursed problems where the frames get longer because FixedUpdate is called more, if FixedUpdate gets even slightly expensive.
    Closest solution I have to syncing 2 clients with different frame times (in absolute time) was a server-time synchronized RPC where, I decided to trigger the event on the slower-updating client even if the trigger time wasn't yet reached as long as if the estimated time of the next frame would be even more off. Of course this also used the last frame's frametime though but made some events seem almost magically in-sync as long as I could schedule the event far enough in the past (like 300ms).

  • @2dlines
    @2dlines 6 หลายเดือนก่อน +1

    14:19 we can directly calculate the location : x = 0.5 * acceleration * time ^ 2

  • @sixtenhugosson
    @sixtenhugosson ปีที่แล้ว +12

    During the part on acceleration, you can use the equations of motion to get:
    transfrom.position += Vector.right*speed*dt+Vector.right*acceleration*dt*dt/2;
    speed += acceleration*dt;
    You should get the same result but in a "physically correct" manner. In the end it reduces to the same result, but it could still be useful.

    • @EfeDursun125
      @EfeDursun125 ปีที่แล้ว +1

      use * 0.5f

    • @mrnowhere-sc3mv
      @mrnowhere-sc3mv ปีที่แล้ว +3

      Correct me if I'm wrong, but the first method (which is the same as you provide) is called the forward Euler method, which tends to artificially adds energy to the system the further it goes. Updating speed before position (the sympletic/semi-implicit Euler method) or adding half before and after (the midpoint method, which equates to 0.5 because he is using a linear function) tends to be more stable (the error is bounded)

    • @hardtofinduniquename
      @hardtofinduniquename ปีที่แล้ว +1

      To be clear: It's not just the same result but it's also the same mathematical formula, except not applied with intermediate state (only modify speed once).
      It's easier to see if you simplify the formula to:
      transform.position += Vector.right * dt * (speed + acceleration * dt/2);
      speed += acceleration * dt;
      And then pulling out the acceleration term to apply to speed makes looks like Jonas' code:
      var boost = acceleration * dt/2;
      speed += boost;
      transform.position += Vector.right * dt * speed;
      speed += boost;

    • @hardtofinduniquename
      @hardtofinduniquename ปีที่แล้ว

      ​@@mrnowhere-sc3mvFor anyone who wants to go deeper on this math, "Math for Game Programmers: Building a Better Jump" goes into Euler integration, Velocity Verlet, and concludes simplified Verlet (the same result we have here) is a good compromise: th-cam.com/video/hG9SzQxaCm8/w-d-xo.html

  • @SauROnmiKE
    @SauROnmiKE 8 หลายเดือนก่อน

    This video was recommended to me at 1AM in bed, stayed glued to my phone screen all of the time and still understood everything. World-class explanation.
    Subscribed

  • @TagaRamer
    @TagaRamer ปีที่แล้ว +3

    I have a degree in electrical engineering and I changed my career into programming and finally the math I learned became useful! I loved your video !

  • @mskiptr
    @mskiptr ปีที่แล้ว

    I don't see why 19:55 would be consistent between different framerates.
    Let's say we start at 0, the target is 1, the speed is 1 and we use exponents of ½.
    1 Hz for 4 s:
    lerp (.5**1) 0 1 = .5
    lerp (.5**1) .5 1 = .75
    lerp (.5**1) .75 1 = .875
    2 Hz for 4 s:
    lerp (.5**.5) 0 1 = .707…
    lerp (.5**.t) .707… 1 = .914…
    0.974…
    0.9926…
    0.99784…
    0.999368…
    0.9998150…
    The positions should match on simultaneous frames. They don't

  • @rayank2010
    @rayank2010 ปีที่แล้ว +4

    when your use the lerp function your supposed to have a "linear" speed without acceleration because it's a Linear intERPolation, if it looks exponential it's because you change each frame the beginning position (parameter a)
    so :
    pos = lerp(pos_begin, pos_end, t)
    Great video though !!

    • @pepperdayjackpac4521
      @pepperdayjackpac4521 ปีที่แล้ว

      So, is the reason the lerp was looking exponential causes by the fact he use transform.Position, which got the current position, instead of the start position which never changes, so it should be a constant, somewhere outside the update function?

    • @rayank2010
      @rayank2010 ปีที่แล้ว

      @@pepperdayjackpac4521
      Yes it wouldn't be exponential if he sets the initial position.
      You can test yourself to see.

  • @charlesmayberry2825
    @charlesmayberry2825 11 หลายเดือนก่อน +2

    I'm glad you pointed out the issues with update and fixed update, The thing is, some things need to be calculated before you should continue, in which case, fixed update is the answer, however those need to be lightweight because you need them for function quickly, in some games the physics may not need high accuracy, in which case, it's fine for them to happen whenever. However games that are heavily reliant on the physics (like an FPS) you really need those collisions calculated before continuing.

  • @Firestone-Games
    @Firestone-Games ปีที่แล้ว +5

    New Jonas Video Lets gooooo!

  • @44Hd22
    @44Hd22 11 หลายเดือนก่อน +1

    9:08 Would they accelerate if their FPS accelerated?
    Edit: Also are you German? I saw a German word in your coding program and your speech sounds kinda German but I am enjoying the video despite me not knowing how to code.
    9:59 can you put that one line of code before and after the one that is code line 15 right now?
    10:17 I guessed almost correctly.

    • @hanmira
      @hanmira 10 หลายเดือนก่อน

      Yes he is German

  • @Finigini
    @Finigini 3 หลายเดือนก่อน +36

    GEARBOOOOOOOOX

    • @nyafnix7060
      @nyafnix7060 22 วันที่ผ่านมา +2

      Risk of rain 2 moment

  • @NavyPanther54
    @NavyPanther54 ปีที่แล้ว +2

    These visuals were insanely good. I didn't expect the answer for the linear acceleration, splitting it up like that. But it makes sense with the graphs!

  • @skatehansen
    @skatehansen ปีที่แล้ว +9

    Thank you ! currently developing my first game now, and want speedrunning as a focus. So I'm always scared of having inconsistent results. I mostly do FixedUpdate stuff tho. Rb char controller. But anyone know any other areas I should look out for or ways to test this easy ? the lag spike was a neat trick. Edit: oh no, im actually doing all the speed calculation in Update, time to refactor some stuff... haha

  • @KerbalLauncher
    @KerbalLauncher ปีที่แล้ว

    8:22, first solution is the forward euler method, second is the backward euler method, and the third is trapezoidal method. This has huge implications in discrete time signal analysis.

  • @jbaidley
    @jbaidley ปีที่แล้ว +5

    I disagree with your description of deltaTime, it's not the time between the last frame and the frame before that. It is the time elapsed between the START of the current frame and the START of the last frame. In most cases these mean the same thing, but it's usually implemented as I describe.

    • @JonasTyroller
      @JonasTyroller  ปีที่แล้ว +2

      Ah, I see. Thanks for specifying that further. Should still work as described in the video then, right?

    • @skatehansen
      @skatehansen ปีที่แล้ว

      way easier to wrap your head around too, thanks

    • @jbaidley
      @jbaidley ปีที่แล้ว

      @@JonasTyroller Yes, the description of how it works is correct.

    • @lennysmileyface
      @lennysmileyface ปีที่แล้ว +2

      @@JonasTyroller Yeah you just worded it unintuitively. B could be interpreted as correct because you always set the current time at the start of a frame i.e. the frame that is being processed and the last time at the end (which becomes the start of the previous frame when the next frame starts).

  • @Seipli
    @Seipli 10 หลายเดือนก่อน +2

    Okay someone has to explain to me how 16:22 would work.
    If you set the speed AFTER updating the position then how does it get applied? Because on the next update the speed value is set by the gravity again and therefore is overwritten.
    So how does this IF statement ever get applied to the move portion of the code?

  • @simaopereira9416
    @simaopereira9416 ปีที่แล้ว +4

    Wow, I'm honestly quite impressed by the quality of this video. It's very entertaining and informative at the same time, I hope you do more videos like this ;)

  • @benhur2806
    @benhur2806 ปีที่แล้ว +1

    Funnily enough the case where you do a half step before and after is a better approximation in any case, as that corresponds to the midpoint RK2 method.
    What also works for that case, and is also a valid RK2 method, is computing the average of both the speed at the start of the step and at the end of the step.
    And of course there's even fancier methods like RK4:
    (I will refer to the speed at the start as v0 for clarity)
    Make one step with 1/2*deltaTime, store the speed resulting from that step in v1
    Make one step from the starting position with v1, also 1/2*deltaTime, store the speed after that step as v2.
    Then do one step, again from the start, this time with full deltaTime, using v2 and store the speed after that step as v3.
    Now take a weighted average of 1/6 * v0 + 1/3 * v1 + 1/3 * v2 + 1/6* v3, lets call this result v, and then using this final v do the last step, yes, again from the start, with deltaTime. The resulting position will be your now even better approximation!
    Is this horribly overkill for most games? Of course! But I'd be remiss not to mention it. :P

  • @RevenaSurniak
    @RevenaSurniak ปีที่แล้ว +5

    just when you think it starts to make sense

  • @JackBond1234
    @JackBond1234 ปีที่แล้ว

    3:58, hmm, maybe I wasn't interpreting the phrasing right, but in my head, I envisioned it as the time between when the previous frame STARTED PROCESSING, and when the current frame STARTED PROCESSING, so it wouldn't matter if we hadn't finished the current frame yet, and it would still effectively behave as you illustrate answer "a" to behave.

  • @TacoTechnica
    @TacoTechnica ปีที่แล้ว +12

    Loved this, a lot to chew on even for more experienced game devs! Just one extra thing, in 15:35 isn't there also a potential error where the jump input is checked after running movement code, introducing an extra frame of delay when a user wishes to jump?

  • @fuzzypancake123
    @fuzzypancake123 6 หลายเดือนก่อน +1

    Very cool video I def learned something new!! BUT, in the lerp example I will suggest instead of using Time.deltaTime only use Time.time and compare your current time to a starting time that you set when you want the animation to start. This will completely avoid all the problems that you listed without having to figure anything out (like average speed change and what not).

  • @DaMu24
    @DaMu24 ปีที่แล้ว +20

    I highly appreciate the math explanations. Calculus is an important topic that can be learned as early as high school, maybe earlier if you have the perfect teacher, and solutions to game development like this are why learning advanced math is important.

    • @zeckma
      @zeckma ปีที่แล้ว +1

      The sad thing is that teachers make a terrible case for learning calculus, algebra, and geometry, usually throwing only rocket science as an example. I went through the classes just fine but never understood why I should learn the material and could never discover a legit use case for it. That is until dealing with graphics and games, at which point I heavily regretted forgetting most of what I had learned.

    • @JanTGTX
      @JanTGTX 10 หลายเดือนก่อน

      I'm with you, but schools don't seem to have an interest in teaching "real" math. It's all just about calculating numbers, like robots.
      Studying physics was an absolute eye opener for me. There I got taught math on a more fundamental level, which really made it click. I'm still wondering why they don't teach axiomatic systems, logic and set theory in schools and let the students be creative for once. The basics actually aren't that hard.
      After having achieved some knowledge of those topics, calculating stuff, even derivatives and integrals, which are the highest level topics in schools, becomes piss easy.

  • @feha92
    @feha92 ปีที่แล้ว +1

    Regarding the lerp code, it is the only one I got 'wrong'... except I got an _entirely_ different answer from either of your possible answers.
    First of all, your function doesn't reach half blend at 1 second, 3/4 at 2, 1-1/8 at 3, 1-1/16 at 4, and so on, instead it is closer to blend=0.5^(0.5*1)=0.7 at 1 second (which btw is much like sin((pi/2)*0.5*1); though that changes as t drifts away from 1, and if t becomes too large or negative it will obviously do sin stuff. Just a fun coincidence and little else). Had your lerpSpeed been set to 1, it should've worked...
    My solution was instead blend = 1 - ls/t, for t >= 1. And either a conditional to handle t 1 - ls/(dt+ls)
    const g = dt => 1 - 0.5**(ls*dt)
    const test = func => dts => dts.reduce( (acc, dt) => lerp(acc, 1, func(dt)) , 0)
    // ie. test(f)(dts) or test(g)(dts)```
    dts is an array of deltatimes. For some reason f differs depending on which array is used, even when sum(dts) is constant (ie. at the second second f should give 0.8. but dts's ` [0, 1, 1]` gives 0.88..9 while `[0, 2]` gives the correct 0.8. g meanwhile works correctly, even if it seems to have some floating point inaccuracies (so worthwhile to ie. set precision at 3 decimals).
    Any ideas why the exponential g worked, but the non-exponential f didn't?
    So in total, I'll give you a -30 point penalty (so you only got 20 points) for using a non-intuitive shape to your graph (humans can't calculate), and I'll put mine at +10, since my answer was in reality the ugly hack that's as incorrect as yours (mine's shape is right, but phase is wrong, as opposed to yours's that has wrong shape, but right phase), and only deserves as few points as yours _even if it had worked,_ which it didn't and thus I deducted 10 points extra from mine.
    (although I _should_ rightly deduct a couple extra points from you for using the magic number 0.5f as the base, with no explanation why - any number 0

  • @wareya
    @wareya ปีที่แล้ว +4

    Very good!!! I'm glad it's getting easier and easier to teach people about the acceleration gotcha. I'm always sad when I play a precision platformer and some of the jumps are impossible unless I limit the game to 60fps.
    I got 160 points!

    • @dexlovesgames_dlg
      @dexlovesgames_dlg ปีที่แล้ว

      Hey you seem to understand this. can you explain why he used .5f as if it means half? isn't that hexadecimal for 95? isn't he trying to get half the acceleration for the first part of the frame and half the acceleration for the second half of the frame? if that's the case why didn't he actually just use .5?
      And if he wasn't trying to get half, doesn't that mean the snails would've accelerated quicker than they were when it was just one line? was the point not to get them to move the same speed but split the acceleration addition up so that it would get an average of the frame start and the frame end acceleration?
      to be clear, i need no explanation of delta, i understand how it works. I just don't get this bit. about splitting the acceleration into two. i get why he does it, cuz i understand why you wouldn't want the acceleration from before nor the after, but rather the midpoint of the two, i just don't understand how multiplying by .5f gets that, unless .5f is in fact just .5, but it seems like it's hexadecimal for 95
      edit: oh my god, i was right the whole time it is just 1/2. 0.5f is unity notation for floats. that was so confusing as someone who uses godot. correct me if i'm wrong

    • @wareya
      @wareya ปีที่แล้ว

      @@dexlovesgames_dlg yeah, f is the suffix for "this is a single-precision float, not a double-precision one"

  • @BluesM18A1
    @BluesM18A1 ปีที่แล้ว +1

    My solution to deltatime inconsistencies was always "just make sure the game runs at full framerate even on potato computers lmao" but even so, looks like I still have a lot of things to check for and improve in my code when one of the games I'm making is about all about speed and precision with the physics engine.
    I know someone will try to run the game on a computer that's probably weaker than my already 10 year old test machine, and they'll be counting on it.

  • @thecryptacoder1126
    @thecryptacoder1126 ปีที่แล้ว +4

    It says 0-10 for an F, what happens if I got a -10?

    • @GrifGrey
      @GrifGrey ปีที่แล้ว

      give up
      (just kidding, keep on learning)

  • @philbertius
    @philbertius ปีที่แล้ว +2

    On the first question, it really depends on what you mean by “current frame” - if the engine is measuring time at the end of the last frame, then that is also the time of the beginning of the current frame - which frame owns it is a matter of semantics.
    Of course I don’t know when in the frame Unity records the current time, but in most game engines it is sandwiched between frames, if not using a fancy GPU readback scheme for “true” elapsed time.
    So assuming Unity is like other engines, B would also be correct.

    • @philbertius
      @philbertius ปีที่แล้ว

      On the second question, I would deduct points for not including fixedDeltaTime (or equivalently and more portably, deltaTime) because including it makes your game logic independent from your choice of fixed time step - e.g. going from 60 to 30 Hz or vice-versa. You don’t want to have to change every single number in code or editor if you need to change the time step, that’d be a nightmare.
      And perhaps most importantly, including the time step allows you to base velocities and such on real physical units, which gives you a frame of reference for understanding your hand-tuned variables, especially if comparing with values from other games.
      Finally, it makes your code more readable imo, since it highlights that it is time-dependent simulation code, not an instantaneous change or something.

    • @philbertius
      @philbertius ปีที่แล้ว

      Third question, the first two integration techniques are explicit Euler (position before velocity update) and semi-implicit Euler (position after velocity update). The improved version rearranges to Verlet integration, if I’m not mistaken.
      Verlet is often used in particle and fluid simulations, but is often considered overkill for physics sim. It’s close to zero added expense for something like a character controller however.
      And as you noted, Verlet will still have error if velocity changes at a non-linear rate. Discontinuities may also present error as well.
      But this is exactly why you perform this simulation in fixed update - there should never be that much error if the time step is fixed and never huge.

    • @philbertius
      @philbertius ปีที่แล้ว

      Final question - I’m impressed, almost nobody knows this! I use the “1 -“ version because I find the lerp more legible this way.
      Your parameterization is essentially a “half life”, which in chemistry would be the time until half the initial quantity is reached, given an exponential decay. I actually parameterize as follows: “1 - Math.pow(v, Time.deltaTime * 60)”, where v is “change per 60th second,” a good frame of reference for game developers, that tends to retain accuracy for most values. (You’ll notice that Pow reduces to a no-op for 60 Hz refresh rate.) If you find yourself needing values close to the extremes of 0 and 1 however, you can change the 60 in order to retain accuracy. I’m actually really curious how your version would perform given extreme values, I imagine much better!
      The way I derived this for myself was noticing that integration of addition becomes multiplication, thus integration of multiplication becomes exponentiation. This technique can be applied to any time-dependent update, and is invaluable for designing your own character controllers.
      Great video! I hope a lot of Unity devs start standardizing this stuff in discussion, would help out sooooo many newbie devs!
      I recommend everyone check out “Gaffer on Games” for some fantastic, approachable articles on all this stuff.

    • @philbertius
      @philbertius ปีที่แล้ว

      One more thing: it’s really important to understand that FixedUpdate doesn’t correspond 1-to-1 with real time. It actually plays “catchup” depending on how much varied time elapsed, executing a number of times (or none at all) until the most recent fixed update is AFTER the next regular update.
      Why? So that Update can interpolate between the previous and future FixedUpdate based on its relative time, i.e. “p = lerp(p0, p1, w); w = (time - fixedTime0) / (fixedTime1 - fixedTime0)”. Strangely, Unity doesn’t seem to compute this weight for you anywhere, so you have to compute and maintain it yourself, but it’s extremely useful if you need to render something from FixedUpdate without using the built-in “transform,” or let FixedUpdate and Update talk to each other in a meaningful and accurate way.
      If you’ve ever found yourself struggling to port code between Update and FixedUpdate, this may be the reason why.

  • @MiTheMer
    @MiTheMer ปีที่แล้ว +6

    Please more of this format!! It was helpful and entertaining at the same time!

  • @Garfield_Minecraft
    @Garfield_Minecraft หลายเดือนก่อน +2

    11:16 wait.. did you just call that *surface* area?
    it's just an area though cuz it's only 2 dimension

  • @mattb8075
    @mattb8075 ปีที่แล้ว +4

    Tell me about it. Stop locking game logic to framerate. Most game engines have built in delta time functions to do all the work for you. It's really frustrating to play a cool game and have to lock my monitor's refresh rate manually.

    • @Aeroxima
      @Aeroxima ปีที่แล้ว

      The main point in the video is that it doesn't just magically do all the work for you, you can't just multiply everything by deltaTime and call it good in every situation. Some of this stuff uses kinds of math I hadn't even heard of before (integrals), and stuff I mostly get when seeing it but wouldn't come up with myself (the math.pow exponential bit). That being said, I test things and even wrote a separate thing to shoddily graph things out to test that it lines up, to make sure, but I found just using Time.deltaTime did not make what I was doing consistent across framerates, only close to it. It was years ago so I don't remember what it was, but I gave up and accepted the approximation because I had been at it for days, getting nothing done.

    • @mattb8075
      @mattb8075 ปีที่แล้ว

      @@Aeroxima Yeah I actually made that comment before watching the video haha, just based on the title. It's way harder than I thought, so I get why some Devs don't use it. It's not rocket science as Jonas says, but it isn't particularly simple either. Really makes me respect and appreciate that much more the people that put in the work to get right.

  • @thewolfstu
    @thewolfstu 7 หลายเดือนก่อน

    0:17 I am happy to say right at the start of this that I know delta is the in-engine mathematical expression of the game's current FPS, and multiplying time-based measurements makes it so that it will calculate out by seconds elapsed rather than frames in certain context, notably often being the equation of Second/Frames Elapsed.

  • @norude
    @norude ปีที่แล้ว +4

    What grade do I get for a total of -10 points?

  • @alexrecuenco
    @alexrecuenco ปีที่แล้ว

    As a non-game developer and a physicist, at 13:00 I was thinking about" leap-frog integration" and how it conserves the hamiltonian flows... The keyword is "symplectic" and somehow that got me the right solution... (Basically, that it is stable in conserving the motion, and it doesn't "spread" the error

  • @sealsharp
    @sealsharp ปีที่แล้ว +5

    A little technical precision in times of "with AI everyone can make games without learning or hard work". Wonderful.

  • @TuriGamer
    @TuriGamer 10 หลายเดือนก่อน +3

    Who cares if it works
    Undertale is a barely working mass of steel wool and its one of the best selling indie games of all time

    • @blacktiger974
      @blacktiger974 10 หลายเดือนก่อน +1

      being a decent artist is infinitely better than being a superb dev when it comes to indie gamedev

    • @TuriGamer
      @TuriGamer 10 หลายเดือนก่อน

      it really isnt
      all that trash pixel art and ""psx"" garbage isnt even hard to do
      actual pretty games like ori are very very rare
      look at pizza tower and cruelty squad those games are hideous and still popular@@blacktiger974

  • @a.j.outlaster1222
    @a.j.outlaster1222 ปีที่แล้ว

    17:15
    The version I learned is "a + (b-a)t"
    While more compact, It's admittedly harder to read, It is awesome to see another formula.
    Also, If you want to compact some code or look tighter/more complex then this, Here you go. 🙃
    Tbh, Idk, really, Just, Here's the alt formula...😅

  • @lapissea1190
    @lapissea1190 ปีที่แล้ว +4

    I always liked the fixed update per second model more. It is actually deterministic and it is a lot simpler to write and less bug prone.
    Yes it will make the game run in slow motion if you are unable to achieve the TPS but also if you can not run quickly enough with delta time, you will get large deltas and possibly break the game in a bad way such as phasing trough walls, consuming more resources than exist and such so so much more.

  • @synthercat
    @synthercat 13 วันที่ผ่านมา

    Awesome videos Jonas! Keep up the great work. Nice to see other people loving Unity. It seems you got something slightly wrong (semantics-wise). You see according to the Unity docs (and tests I did) Time.deltaTime is "The interval in seconds from the last frame to the CURRENT one" and you also agree to this schematically on the 4:16 point where the black dot shows our point and 0.14s frame is indeed the last. To make a long story short, the correct answer is the time it took from the last frame start, to this frame's start which I think is stated in a cleaner way.

  • @Daggett1122
    @Daggett1122 ปีที่แล้ว +2

    When I first started physics programming about 15 years ago I found fixed step with accumulation and display interpolation is the way to go. It always surprises me that variable step is still a thing, but I guess it's just faster if accuracy isn't needed.

    • @zeozen
      @zeozen ปีที่แล้ว +1

      Agreed. As far as I can understand, it's stems from wanting to ship a game to a multitude of pcs with vastly different specs, and then wanting the game speed to be equal on those machines in wall time. If you look at nintendo games tho, they use fixed step, and if the game lags, the game simply runs slower, no sudden movement jumps to try to stick to wall time. I like keeping the simulation time and wall time as different.

  • @mamertvonn
    @mamertvonn ปีที่แล้ว

    10:38 that works because most of the time when your accelerating at a constant rate, the distance travelled when graphed tends to be a parabola, or half a parabola depending on your initial starting velocity.
    the derivative of that is the velocity
    and the derivative of the velocity is the acceleration
    Now here, we focus on the acceleration. For example 9.8m/s as gravity. If we integrate that up to calculating the distance traveled, we get 9.8 × x^2 / 2, let x here be time. Notice that it will always divide it by two
    Hence, when updating your position, it is always the average of your initial velocity plus the final velocity. Your final velocity being the initial velocity plus the acceleration times deltaTime
    I think this isn't a game engine thing. But more of a calculus thing and basically just how things should work in physics, I guess.
    So, the show the formula. It should looke like this
    vi is velocity initial
    vf is velocity final
    a is acceleration
    pos += ((vi + vf) / 2) × deltaTime
    where in vf = vi + a × deltaTime
    so, pos += (vi + (a × deltaTime / 2)) × deltaTime
    Then, re-assign vi = vf, for the next frame
    Now the harder question is figuring out how to accurately find the change in position when acceleration is not constant. Not really important for game development but it is an interesting math question that is very difficult or even impossible to figure out. Literally infinite possible ways you can interpolate a set of points in a graph and not introducing other factors like damping, which can affect the system.

  • @welcometochiles6156
    @welcometochiles6156 ปีที่แล้ว +1

    16:17 I hate this I hate this I hate this I hate this PUT BRACKETS DOWN I'M GOING TO PALPITATE
    16:29 Ah, so when simulating gravity such as in Brackey's FPS tutorial, I should not square time ( multiply by another Time.deltaTime ). Got it.