Time.DeltaTime in DOTS

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