Hi, I’m using a lot of Time.DeltaTime in my project, caching it before each of my ForEach(). I see that a world has a WorldTime object but I can’t GetSingleton() on it because WorldTime is an internal struct. Is this intended? Is Time.DeltaTime still a way to go?
Seems so.
If you check ComponentSystemBase (from which SystemBase inherits) you can see following:
/// <summary>
/// The current Time data for this system's world.
/// </summary>
public ref readonly TimeData Time => ref World.Time;
And the World.Time is basically managed internally as singleton for you, injected into unmanaged world only once per frame. This is done by UpdateWorldTimeSystem:
using Unity.Core;
using Unity.Mathematics;
using UnityEngine.Scripting;
namespace Unity.Entities
{
[Preserve]
[UpdateInGroup(typeof(InitializationSystemGroup))]
public class UpdateWorldTimeSystem : ComponentSystem
{
protected override void OnStartRunning()
{
// Ensure that the final elapsedTime of the very first OnUpdate call is the
// original Time.ElapsedTime value (usually zero) without a deltaTime applied.
// Effectively, this code preemptively counteracts the first OnUpdate call.
var currentElapsedTime = Time.ElapsedTime;
var deltaTime = math.min(UnityEngine.Time.deltaTime, World.MaximumDeltaTime);
World.SetTime(new TimeData(
elapsedTime: currentElapsedTime-deltaTime,
deltaTime: deltaTime
));
}
protected override void OnUpdate()
{
var currentElapsedTime = Time.ElapsedTime;
var deltaTime = math.min(UnityEngine.Time.deltaTime, World.MaximumDeltaTime);
World.SetTime(new TimeData(
elapsedTime: currentElapsedTime + deltaTime,
deltaTime: deltaTime
));
}
}
}
WorldTime Entity is mainly used to ensure correct order of applying changes to the time / checking whether time is initialized.
World.cs:
protected Entity TimeSingleton
{
get
{
if (m_TimeSingletonQuery.IsEmptyIgnoreFilter)
{
#if UNITY_EDITOR
var entity = EntityManager.CreateEntity(typeof(WorldTime), typeof(WorldTimeQueue));
EntityManager.SetName(entity , "WorldTime");
#else
EntityManager.CreateEntity(typeof(WorldTime), typeof(WorldTimeQueue));
#endif
}
return m_TimeSingletonQuery.GetSingletonEntity();
}
}
public void SetTime(TimeData newTimeData)
{
EntityManager.SetComponentData(TimeSingleton, new WorldTime() {Time = newTimeData});
this.Time = newTimeData;
}
public void PushTime(TimeData newTimeData)
{
var queue = EntityManager.GetBuffer<WorldTimeQueue>(TimeSingleton);
queue.Add(new WorldTimeQueue() { Time = this.Time });
SetTime(newTimeData);
}
public void PopTime()
{
var queue = EntityManager.GetBuffer<WorldTimeQueue>(TimeSingleton);
Assert.IsTrue(queue.Length > 0, "PopTime without a matching PushTime");
var prevTime = queue[queue.Length - 1];
queue.RemoveAt(queue.Length - 1);
SetTime(prevTime.Time);
}
3 Likes