I’m trying to get my physics to be frame-rate independent in DOTS. It seems that both Unity.Physics and Havok.Physics use UnityEngine.Time.fixedDeltaTime, but process physics every graphics frame. The result of this is that the higher the framerate is, the faster things move around given the same PhysicsVelocity values. An easy way to see this is to simply increase the “Fixed Timestep” in edit->project settings->time, so that it doesn’t match your framerate.
from “Unity.Physics\ECS\Systems\BuildPhysicsWorld.cs”:
I tried defining UNITY_DOTSPLAYER in edit->project settings->Player->Other Settings->Scripting Define Symbols, but this seems to break many other things. Is this a bug? should it be using DeltaTime in all cases?
The DOTSSample doesn’t have this issue on the player because the player controllers are using scripted ray/collider cast physics, not Unity.Physics. I’m not sure if there’s a different sample I can reference or something.
Is there an easy way with DOTS to get frame-rate independent physics? Any help would be greatly appreciated.
Right now there is no actual solution for the problem. The easiest workaround for me was to use the following code. As you can see, it is based on another forum post. I had to make some adjustments though to get it to work.
using Unity.Entities;
using Unity.Physics.Systems;
// Source: https://discussions.unity.com/t/736062 page-18#post-5027081
[UpdateBefore(typeof(BuildPhysicsWorld))]
public class PrePhysicsSetDeltaTimeSystem : ComponentSystem
{
public bool isRealTimeStep = true;
public float timeScale = 1;
public float previousDeltaTime = UnityEngine.Time.deltaTime;
protected override void OnUpdate()
{
previousDeltaTime = UnityEngine.Time.deltaTime;
if (isRealTimeStep)
{
UnityEngine.Time.fixedDeltaTime = UnityEngine.Time.deltaTime * timeScale;
}
else
{
UnityEngine.Time.fixedDeltaTime = UnityEngine.Time.fixedDeltaTime * timeScale;
}
}
}
[UpdateAfter(typeof(ExportPhysicsWorld))]
public class PostPhysicsResetDeltaTimeSystem : ComponentSystem
{
public PrePhysicsSetDeltaTimeSystem preSystem;
protected override void OnCreate()
{
preSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem<PrePhysicsSetDeltaTimeSystem>();
}
protected override void OnUpdate()
{
UnityEngine.Time.fixedDeltaTime = preSystem.previousDeltaTime;
}
}
… which will get the physics (and the rest of the simulation group) running at a fixed framerate. Once this is done an ECS object reliably falls at the same rate as an equivalent MonoBehaviour object.
I think the downside is that the whole simulation group is now running at a fixed frame rate so you won’t get interpolation of physics objects in the non-fixed frames, and if you have other systems in that group they will also be fixed rate.
I haven’t experimented any further yet. AFAICS there is still no easy way to get a fixed rate physics simulation with interpolated movement and without the need to get involved with adjusting the system groups. Has anyone else got any further?
I put it in one of my systems - not really a great place, just somewhere quick and dirty to try it out. I found putting it in OnCreate() sent Unity into an infinite spin, but delaying it until the first OnUpdate() worked.
public class PlayerSystem : ComponentSystem
{
private bool once = false;
protected override void OnUpdate()
{
if (false == once)
{
FixedRateUtils
.EnableFixedRateWithCatchUp(World.GetOrCreateSystem(),
UnityEngine.Time.fixedDeltaTime);
once = true;
}
}
}
I didn’t persevere with this for now because I didn’t want my other simulation world systems to have the fixed rate and didn’t want to give the time to experimenting with moving systems around until it was clearer how Unity expects this all to work in the end. So, for now I’ve gone back to hacking UnityEngine.Time.fixedDeltaTime either side of the physics systems.
Thank you, I finally got around to try it, and my camera follow system at long last is smooth again.
The old FixedUpdate() system update method broke for me somewhere around last summer.
So I guess this is not the way it is supposed to be used, but it makes my game so much smoother again I love it!