Is Unity's physics ahead of rendering or behind? - unity3d

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

Related

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

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.

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.

Addforce changes with framerate

I have a line that is applying force to the player. The force is applied in an Update() while the player is in the Roll animation state.
if (anim.GetBool("isRolling") == true && anim.GetBool("IsGrounded") == true && canRoll == false)
{
rb.AddForce(transform.forward * rollLength, ForceMode.Force);
}
I am targeting two devices, one with high framerate and one with low framerate. On the one with low (30 fps) framerate, it works fine, but on the high framerate (in the 100s) the player goes too far too fast. I have read that Time.deltaTime will divide the force, which doesn't help me.
What can I do to fix this issue?
Addforce doesn't add Force in physical sense as much as it adds energy: you should control amount and frequency byt Time.deltaTime which makes single call time-dependent, but also you should keep in mind that FixedUpdate exists - it works like a classic Update but it's guaranteed to have constant time in between each calls (equal Time.fixedDeltaTime). Generally speaking if you manipulate phisics in each frame you most likely want to use FixedUpdate instead of Update
But honestly I would considered if addForce is good idea for a rolling mechanic in the first place: I feel like it would be better idea to use Rigidbody.velocity or Rigidbody.Move()
As said above: "AddForce" doesn't really adds force, but energy instead so you should scale it using Time.deltaTime
When doing physical calculations in unity it is recomended to do them inside FixedUpdate, as it is guaranteed to have constant rate of activation which allows you to avoid certain problems that are often for physics with even small framerate fluctuation and correct usage of Time.deltaTime

Am I missing something or Unity3d skips frames?

I have a gun with 4 muzzles. Each muzzle can fire a bullet (so 4 bullets can be fired at once). In my scene I have 100 guns thus 400 bullets can be fired at the same time.
The problem is, if the number of gun is below 20 then it is Ok, but if I raise it to above 20, some of the bullets go through the target (a big Cube). And ton of bullets pass through the Cube if it is above 100.
This is the code that check for collision:
private IEnumerator ProjectileCoroutine() {
while (Vector3.Distance(transform.position, Target.transform.position) > 5)
{
yield return null;
}
Explode();
yield break;
}
Some notes:
Games runs at 49 - 68 fps (100 guns on the scene)
I uses prefab pooling method
Above code is run in a separated coroutine (StartCoroutine)
Please can anyone tell me what is happening?
I suspect that Unity skips some of the frames as Coroutine has some connections to it.
I don't think Unity is "skipping frames". That said, I expect your coroutine will only run once per full graphics frame. Physics updates usually occur more often, especially at lower frame rates.
Note that the more bullets there are, the slower the scene probably runs. For a time-stepped physics simulation, this means that bullets have to move further every time step. If the bullets are moving fast, and the time step is large, it is possible for bullets to move too far through the cube for collisions to be detected and resolved in a frame. If this is the problem, you may need to add some sort of ray casting, to better detect collisions.
That said, I don't think your ProjectileCoroutine is the best way of resolving collisions. For starters, it appears to check a sphere, rather than a cube, and running it for every bullet is a bad idea performance wise.
It would be much better to use an appropriate Collider, and rely on the actual physics engine to detect collisions, instead of doing a manual distance check.

Box2D sleep time

I was just wondering if there was a way to change the amount of time until the sleep state is activated for a body in box2d (cocos2d).
I currently use the sleep state as a way to end a game so it is preferable if I can speed up the time it takes to achieve the sleep state.
Thanks
A physics engine doesn't put objects to sleep based on time. It only puts bodies to sleep which are at rest (idle). Typically the physics engine defines rules when it's safe to put a body to sleep, normally that's when the body has stopped moving at all, when there are no other moving bodies touching it, and when both conditions are met for a certain period of time.
In Box2D you can't modify this behavior unless you modify the Box2D source code (not recommended). In Chipmunk you can at least set the threshold for how long a body must be idle before it is put to sleep. Changing this value can sometimes lead to the effect that slow moving objects will suddenly fall to sleep.
To implement the behavior you want, you should define your own set of rules. Iterate over all bodies that may be moving slowly at the end of the game. Get the values for angular rotation and velocity, and check if they have fallen below a certain threshold that feels good for your game. Then end the game, or you can also manually put the object to sleep with body->SetAwake(false).