Hello everyone,
One of the long standing and rather frequent requests to Unity’s physics team is to expose the explicit control over FixedUpdate.
Let me quickly show a few examples as a motivation for this.
An obvious usage could be networking physics: turns out that in order to do convincing multiplayer interaction in FPS-like games one needs to be able to rewind back time, apply the correction that arrived from the server and tweak it with the locally applied input. The latter was pretty much impossible really since in Unity you can’t call the physics simulation manually.
Another example is a simulation game. Think golf, pool or bowling. It’s desirable to be able to preview the trajectory of the controlled ball given this particular direction, strength and type of the strike. In order to do that seamlessly one needs to be able to simulate the scene for a few frames in advance which isn’t directly possible in any of the public builds right now.
One additional bonus is that with this control exposed, it’s easy to have some logic post-update. Currently, the FixedUpdate script callbacks are called right before the physics simulation is run. Thus, if you wish to have a script that gets transforms right after the physics update was called, you have to jump through hoops. A possibly smart workaround being used these days is to create two overlapping triggers somewhere far away from the game area, subscribe to OnTriggerStay from them, and get the post-simulation callback that way.
There were multiple talks over the years where many theoretical concerns were pointed out with regards to exposing Physics.FixedUpdate to scripts. Moving the physics objects may invalidate the PhysX’s caches and thus cost performance spikes when rewinding the time back and forth. Calling simulation with the variable delta will get you unpredictable solver results. Possibly, there are lots of ways to break some assumptions when FixedUpdate is called at unexpected times from scripts.
However, having many theoretical ideas, there wasn’t much actually tried out. So this thread is targeted at correcting that. Let’s try it out together, collect ideas and have a conclusion whether it’s worthy having the control exposed this way or not.
I’ve prepared a custom build off of 5.4.3p3. Can do any Unity version if makes sense, my change is minimal. Let me know. Here it is: http://beta.unity3d.com/download/482a73abaf24/public_download.html
That’s only editor that doesn’t seem to be capable of building players. Probably, an inconvenience for the networking tests, but I believe you could still run multiple editors on the same machine. Let me know if that’s a blocker for you, I’d figure something out.
As to what’s added. The build has only two little things added: Physics.autoSimulation and Physics.SimulateStep(float delta).
- Physics.autoSimulation (also, available in the project settings): toggles whether the simulation should be run automatically, or the user should be calling Physics.SimulateStep manually
- Physics.SimulateStep: a new function that updates physics by ‘delta’ seconds forward.
Here is an example of how you get pretty much the old logic of updates, but from C#:
using UnityEngine;
public class BasicSimulation : MonoBehaviour {
private float timer;
void Update () {
if (Physics.autoSimulation)
return;
timer += Time.deltaTime;
if (timer >= Time.fixedDeltaTime)
{
timer -= Time.fixedDeltaTime;
Physics.SimulateStep(Time.fixedDeltaTime);
}
}
}
Note that in this build Physics.autoSimulation controls only the actual simulation calls to the physics engine. It doesn’t affect the FixedUpdate calls to your scripts. Those will still be called based on the fixed frequency set in the properties.
Please let me know what you think. Is it a step in the right direction? Is it a step in the wrong one? What needs to be done in a different way? What do you think?
Anthony