Unity - In what cases should I add Time.deltaTime? - unity3d

I'm new to Unity and I see many times that Time.deltaTime needs to be added. In which cases should I add it? I know this is so that there will be no excess power in the event of a quick refresh of the frame's computer.
For example, in the next case, do I need to add Time.deltaTime?
playerRigidbody.AddForce(Vector3.up * 100 * Time.deltaTime, ForceMode.Impulse);

Time.deltaTime is the amount of seconds it took for the engine to process the previous frame. It's calculation is rather simple: it uses the system's internal clock to compare the system time when the engine started processing the previous frame to the system time when the engine started processing the current frame. Every motherboard has a "system clock" which is responsible to keep track of time. Operating systems have access to that system clock and provide API's to read that clock. And Unity gets the time from that API and that's how things are synchronized.
Think of a game as a movie, which is essentially a sequence of images. The difference is that a movie is rendered at a fixed rate of 24 images per second, while a game doesn't have a fixed frame rate.
In a movie, if a car travels at 1 meter per second, each image will make it move by 1/24 meter, and after 24 images (1 second) the car will have traveled exactly 1 meter. It's easy because we know that each frame takes exactly 1/24 second.
In a game, we have to do the same thing, except the frame rate varies. Some frames can take 1/60 second, some others can take 1/10 second. We can't use a fixed ratio. Instead of a fixed number we have to use Time.deltaTime. Each frame, the car will move a distance proportional to the time of the frame. After roughly 1 second, the car will have traveled roughly 1 meter
Delta is the mathematical symbol for a finite difference. Its use is very common in english when talking about something that changed over time.
deltaTime is a difference of time, so it's a Delta
Shorter Terms
You must always use Time.deltaTime when moving objects over time, either by supplying it yourself or by making use of functions like SmoothDamp that use Time.deltaTime by default (hardly any functions do that though). But you must never use Time.deltaTime for input that's already framerate-independent, such as mouse movement, since in that case using Time.deltaTime will do the opposite of what you intend.
If you're ever unsure you can always toggle vsync on and off and observe any potential speed differences. If the game's already running close to the monitor refresh rate anyway, then make use of Application.targetFrameRate instead.

In very easy words
Time.deltaTime is the time passed since last frame was rendered.
By multiplying a value with it you basically convert it from Something per frame into Something per second.
Is it needed?
Now if you need to use it totally depends on your specific use-case! In your case for AddForce: NO!.
The force influences the velocity of a physics object. The velocity itself already is an absolute per second vector.
Usually there are two use-cases for AddForce:
It is called continuously but within FixedUpdate
Because FixedUpdate is not called every frame anyway but rather on a fixed real time intervals (by default 0.02 seconds) you would not need Time.deltaTime. The Doc already provide this in the example.
It is anyway called only as a single event (e.g. by jumping)
Here there is nothing continuous, so you don't need and don't want to use Time.deltaTime either since a single event can not be frame-rate-dependent anyway.

Related

Best way to prevent physics calculations in Unity from eating too much FPS?

I'm a senior software engineer, but completely new to Unity programming. I've been teaching myself Unity for a few weeks by writing some SteamVR toys for myself. I wanted to ask about Unity's standard built-in ways to improve frame rate for a program with a lot of intensive physics calculation.
In my current VR scene, I have a ball with a Rigidbody on it. When I pick it up and throw it, I let it move naturally, but I apply small forces on every Update() call to adjust the landing position and always hit a target.
I saw my framerate take a big dive, so I wrote my own function to throttle the updates, limiting them to 5 per second. The question is, is there some standard Unity behavior that I should be using instead of rolling this code myself?
In my throwing script, I maintain a bunch of top level variables and update them first to decide whether I should do calculations on the current frame.
private void updateCalculationFrame() {
isCalculationFrame = Time.time > nextCalculationTime;
while (nextCalculationTime < Time.time) {
nextCalculationTime += (1 / calculationsPerSecond);
}
}
On each frame, I run this function, then if isCalculationFrame is true, I proceed to calculate and add force vectors. I just wonder if I am overlooking some more standard way to do this with less code? I feel like this must be a very common thing to try to do.
The code you have there will freeze the Unity until the loop is finished. You shouldn't do this at all.
You could simply set a new Time.fixedDeltaTime. By default it is usually about 0.02 but you can set it to anything you want.
The interval in seconds at which physics and other fixed frame rate updates (like MonoBehaviour's FixedUpdate) are performed.
...
Note that the fixedDeltaTime interval is with respect to the in-game time affected by timeScale.

When do you multiply by Time.deltaTime in Unity?

There seems to be a lot of confusing/conflicting advice out there about when you should or should not multiply a quantity by Time.deltaTime. So I was wondering, as it pertains to the Unity physics system, when should you multiply by Time.deltaTime?
I understand that Time.deltaTime is used to make certain actions framerate independent, but there are some situations where it isn't clear whether an action is framerate independent. For instance:
Doing rigidbody.velocity += acceleration*Time.deltaTime; in FixedUpdate. Since FixedUpdate runs at a constant timestep, does this make the multiply by Time.deltaTime unnecessary?
Doing rigidbody.AddForce(force*Time.deltaTime, forceMode);. How do the various ForceModes effect this?
I've seen solutions to individual situations, but it would be nice if there were a simple intuition which could address all of these situations.
The intuition
Multiplying by Time.deltaTime is used to make an instantaneous operation act in a continuous (or "smooth") way.
An instantaneous operation will cause a certain quantity to "jump" to a different value. The following operations are instantaneous:
Rigidbody.[position|velocity|rotation|angularVelocity] += x;
Rigidbody2D.[position|velocity|rotation|angularVelocity] += x;
Rigidbody.Add[Force|Torque](x, ForceMode.[Impulse|VelocityChange]);
Rigidbody2D.Add[Force|Torque](x, ForceMode2D.Impulse);
All the above operations cause a quantity to instantly jump by x, irrespective of the length of the frame.
In contrast, the following operations are continuous:
Rigidbody.Add[Force|Torque](x, ForceMode.[Force|Acceleration]);
Rigidbody2D.Add[Force|Torque](x, ForceMode.Force);
Rigidbody.velocity = x; (continuous from the perspective of Rigidbody.position. i.e. setting the velocity will not make Rigidbody.position suddenly jump to a new value)
All the above operations are applied over the course of the frame (at least conceptually this happens; what the physics system does internally is out of the scope of this answer). To illustrate this, Rigidbody.AddForce(1, ForceMode.Force) will cause a force of 1 newton to be applied to an object for the entire frame; there will be no sudden jumps in position or velocity.
So when do you multiply by Time.deltaTime?
If you are using a continuous operation, you should almost definitely not be multiplying by Time.deltaTime. But if you are using an instantaneous operation, the answer depends on if the operation is being used in a continuous way.
Example 1: Explosion
void Explode() {
rigidbody.velocity += explosionAcceleration;
}
Here you should not be multiplying by Time.deltaTime since Explode() gets called just once. It is not meant to be applied over a series of frames.
Example 2: Moving
void Update() {
rigidbody.position += velocity * Time.deltaTime;
}
Here you do have to multiply by Time.deltaTime because the object is supposed to move continuously over time, and you are also using an instantaneous operation. Note that this could be replaced with a continuous operation, and remove the need for multiplying by Time.deltaTime:
void Update() {
rigidbody.velocity = velocity;
}
Although this isn't entirely equivalent to the original, since it ignores the previous value of rigidbody.velocity.
Example 3: Accelerating
void Update() {
rigidbody.AddForce(acceleration*Time.deltaTime, ForceMode.VelocityChange);
}
Here you should be multiplying by Time.deltaTime because you want the velocity to increase at a consistent rate frame by frame. Note that this is precisely equivalent to:
void Update() {
rigidbody.AddForce(acceleration, ForceMode.Acceleration);
}
This code applies the acceleration over the course of the whole frame. This code is also (in my opinion) cleaner and easier to understand.
What about FixedUpdate?
Being in FixedUpdate does not effect any of the above advice. Yes, you could theoretically get away with never multiplying by Time.deltaTime since the time between frames would always be the same. But then all your units would have to be dependent on the fixed frame rate. So for example if you wanted to move at a rate of 1 m/s with 60 frames per second, you would have to add 1/60=.01666 to the position each frame. And then imagine what happens if you change your fixed timestep. You would have to change a bunch of your constants to accommodate.
Executing code in FixedUpdate does not suddenly make that code framerate independent. You still have to take the same precautions as in Update.
As a side note, you do not need to replace Time.deltaTime with Time.fixedDeltaTime inside FixedUpdate because Unity already does this substitution.
Conclusion
Only multiply by Time.deltaTime if you want an instantaneous operation to act smoothly over a series of frames.
Many times, you can avoid using Time.deltaTime by using continuous operations, which are often more intuitive (see examples 2 and 3). But this of course depends on the context.
A simple way to think about this is to determine:
Are objects' transforms manipulated directly?
When an object is being moved directly via its transform.position and transform.rotation components, manipulation of the transform should occur in Update(), which runs once per drawn frame. The developer should build their game with the expectation that the Update/frame rate varying between zero and the game's maximum frame rate. The way to accomplish this is by factoring in the time between now and previous frame into the movement (step) for each update/frame.
Thus, manipulations to the transform.position and transform.rotation should factor in Time.deltaTime and should occur within Update().
Are objects being manipulated with physics?
In this case, forces and torques should be applied by calling Rigidbody.AddForce() or Rigidbody.AddTorque() in FixedUpdate(). FixedUpdate() can be expected to occur at a fixed/guaranteed rate, which Unity defaults to 50 times per second (this can be adjusted within the Physics settings of your game project).
To complicate things a bit, when AddForce() and AddTorque() are called with ForceMode.Force (default) or ForceMode.Acceleration, the value provided for the force or torque parameters will be interpreted as amounts for one entire second, so these functions will adjust the value (a force/torque or acceleration/angular acceleration) for one fixed time step (i.e., x 0.02s with the default Unity Physics fixed update rate).
In case you are curious about ForceMode.Impulse or ForceMode.VelocityChange, these will interpret the force or torque as the amount to apply within that fixed time step (i.e. the value will not be adjusted with respect to time).

Is Unity's physics ahead of rendering or behind?

To my understanding of this diagram, Update() is called strictly once per game cycle, while FixedUpdate() is called 0 to multiple times when Unity feels like to do physics. Is it true?
What I'm not sure is, are physics steps commonly behind current time, or ahead of current time? In other words, how is Unity's decision made for doing physics or not, like while (currentTime - previousPhysicsUpdateTime >= fixedDeltaTime) or like while (currentTime > previousPhysicsUpdateTime)?
Or neither of the above?
It is a bit like to opposite. Physics is done regularly on a fixed time basis. That means that FixedUpdate is called on a fixed time basis. It is the Update, that can vary depending on the fps of the game (60 fps, Update was called 60 times per second).
Now, we usually thing from the Update point of view. Meaning that if you have a high fps, maybe you can have two Update calls before a FixedUpdate happens. In the same way, if you fps drops you have less Updates, but still the same amount of FixedUpdate, so you will have several FixedUpdated between two Updates.
So for example, let's say FixedUpdate happens 50 times per seconds (that's the default in unity). It you game runs at 60 fps, It means most of the time you will have one FixedUpdate and one Update call. Occasionnaly two Updates will follow (because Update is a bit more frequent). If you reach 100 fps, it is sure that you will always have at least two Update calls before a FixedUpdate.
I suggest you look at the FixedUpdate Doc if this is not clear enough

Lerp with Time.deltaTime

I have a question about Lerp. So I know that lerp helps you to move your object like:
void update(){
transform.position = vector3.lerp(start.position,end.position, (Time.time / 1000));
}
this will get your object to your endposition.
But if you have this code:
void Update(){
transform.position = Vector3.Lerp(transform.position,
destination.position,
speed * 3.0f * Time.deltaTime);
}
How is it possible that your object arrives at your destination, the 3th parameter of lerp has to reaches slowly 1 so your objects arrives at your destination. But "speed" , "3.0" , "Time.deltaTime" will always be the same, so how is it possible that your object arrives at your destination?
So the big question: Is it possible to do the lerp with some variables, which have always the same value and with Time.deltaTime?
Now, because of the different comments etc. I don't know exactly how lerp works, i have to possibilities:
1.) First i thought it works like this:
Vector3.lerp(a,b,c)
The c value has to change every frame to move the object. If the c value is 0.2 your object will moved 20% of the way and if the c value doesn't change the object will always be on 20% of the way. So the get the object moved fluently your c value have to change every frame a little so you c value will go from 0 to 1 and so is your object going from start to destination.
Or is it like this
2.) Because of several comments i thought lerp works like this
Like the comments say, the c value doesn't have to change the value, becaue if you have c = 0.2 you will pass 20% of the way and the next frame, if c is still 0.2 you will pass 20% of the remaining way and so on.
So is it lerp working like 1(you have to change c) or is it working like 2(you don't have to change c)
The distance between your transform position and the destination is an exponential decay. The distance shrinks by (1 - speed) every frame (given that speed is less than 1). Say your game is supposed to run at 60FPS. If for whatever reason the frame rate drops to 30FPS, the deltaTime is gonna be twice as big and you’re supposed to execute the Lerp 2 times. In such case, the distance will shrink by (1 - speed) then (1 - speed) again yielding a result of (1 - speed)^2 shrinkage. From this, you can generalize that the shrink amount of the distance is (1 - speed) ^ (deltaTime / baseDeltaTime) with baseDeltaTime being the deltaTime the game is supposed to run at i.e. 1/60 (for 60FPS).
To put in code:
transform.position = Vector3.Lerp(transform.position, destination.position, 1 - Mathf.Pow(1 - speed * 3.0f, Time.deltaTime * 60));
The object reaches the goal because your start position is the current position, and after lerping, you set the position of the object to the resulting position of Lerp. If you change your starting position to a normal Vector3 it would Lerp to "speed * Time.deltaTime * 3f"
I guess you didn't understand that how lerp works in unity. I will recommend you this Article of Robbert How to Lerp like a pro.
I see this sort of thing far too often:
transform.position = Vector3.Lerp(startPos, endPos, Time.deltaTime);
The person posting it is usually convinced that Vector3.Lerp is
“broken”, but the real problem is that they’re not using it correctly.
Lerp, short for “linear interpolation” does one very simple thing:
given two values, x and y, it returns a value that is t percent
between them. If you expect the output to change, the arguments you
pass in need to reflect that!
In the example above, it doesn’t make sense to just pass in
Time.deltaTime, because that’s only the time that passed during the
most recent frame. If your game is running at a constant 50fps, that’s
always going to be 0.02.
myLocation = Mathf.Lerp(myLocation, myDestination, 0.02)
If you are storing the return of the Lerp function into a variable and then also using that same variable as the minimum value in that same Lerp function, then the min value is getting bigger and bigger everytime the function is called.
So, even though you're not changing T, you're changing the starting value and thus, the stored value gets closer and closer to the max value.
It will accelerate very quickly initially and then slow down the closer it gets to the max value. Also, the max value will either never be reached or take an extremely long time.
(See https://gamedev.stackexchange.com/questions/149103/why-use-time-deltatime-in-lerping-functions)
There are two common ways to use Lerp:
1. Linear blending between a start and an end
progress = Mathf.Clamp01(progress + speedPerTick);
current = Mathf.Lerp(start, end, progress);
2. Exponential ease toward a target
current = Mathf.Lerp(current, target, sharpnessPerTick);
Note that in this version the current value appears as both the output and an input. It displaces the start variable, so we're always starting from wherever we moved to on the last update. This is what gives this version of Lerp a memory from one frame to the next. From this moving starting point, we then then move a fraction of the distance toward the target dictated by a sharpness parameter.
This parameter isn't quite a "speed" anymore, because we approach the target in a Zeno-like fashion. If sharpnessPerTick were 0.5, then on the first update we'd move halfway to our goal. Then on the next update we'd move half the remaining distance (so a quarter of our initial distance). Then on the next we'd move half again...
This gives an "exponential ease-out" where the movement is fast when far from the target and gradually slows down as it approaches asymptotically (though with infinite-precision numbers it will never reach it in any finite number of updates - for our purposes it gets close enough). It's great for chasing a moving target value, or smoothing a noisy input using an "exponential moving average," usually using a very small sharpnessPerTick parameter like 0.1 or smaller.

Implementing a saved ghost for each level in a game

I'm developing a video game for the iPhone. I want each level to save a "ghost" of the best run, just like in Mario Kart.
I've already implemented it, but I used a brute force approach that stores (x, y, rotation) values each frame (60 per second). Needless to say this is very expensive, especially for a mobile device.
I guess I could store the data less often and interpolate when rendering the ghost, but I'm not 100% sure how to do this and if it will look good.
Has anyone done this before? How would you implement it? Is there a standard approach?
Linear interpolation is very easy, if that's what you want. But if the objects you want to interpolate can have non-linear trajectories (from ballistic or lateral accelleration effects) the thing gets more complicated.
The simplest approach would be for you to record the initial position for an object and its movement vector (x,y,z speed, as offsets per time unit). You won't have to record it again for that object until it changes its speed and/or its direction. Then you just record the elapsed time, the new position and the new movement vector (theoretically you don't have to record the position again, just the vectors, but I'd recommend doing so to have a check value - after the program is debugged you can discard it).
Then to playback you place the object at the original position and, for each time frame, add the movement offset to it until it reaches the time for the next recorded position. And so on.