Clarification on accessing managed types in the tutorial

Hi everyone, I was following the offical tutorial on Github and I am quite new on data oritented stack. Under the Step 3 - Tank movement section, a comment on the 4th step says that;

        // The Entities.ForEach below is Burst compiled (implicitly).
        // And time is a member of SystemBase, which is a managed type (class).
        // This means that it wouldn't be possible to directly access Time from there.
        // So we need to copy the value we need (DeltaTime) into a local variable.

However, in the same tutorial at Step 2 - Turret Rotation, on the 1st step we use the SystemAPI.Time.deltaTime in a burst compiled method.

    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        // The amount of rotation around Y required to do 360 degrees in 2 seconds.
        var rotation = quaternion.RotateY(SystemAPI.Time.DeltaTime * math.PI);
        ...

How does this work? Is it because one is a struct (deriving from ISystem) and other is a class (deriving from SystemBase)?

That is a case of the tutorial API being updated, but the tutorial explanation lagging behind.

I think what happened was “Step 2” used to get Time from the SystemState variable that is passed in to OnUpdate() while “Step 3” had to get Time from SystemBase. The first works with Burst while the latter does not. I assume Time was later added to SystemAPI which works with Burst and is now used in both steps for consistency. Capturing DeltaTime in the dt variable is just a relic of the older API, I believe.

It is because of Entities.Foreach is a job and job can not access anything outside its fields
UnUpdate is not job. it is just method of system it can access data outside itself

ForEach isn’t quite a job, but the lambda expression is used to generate a job. “SystemAPI.Time” is special (if you go to its definition it is just a “ThrowCodeGenException”) because it is replaced with a Unity.Core.TimeData struct field in the generated job that is automatically set to WorldUnmanaged.Time so it’s fine to use directly in a ForEach().

Alright, thinking about it a little bit more cleared things. Thanks for the help!

Interestingly enough days after the sample was made we did add support for SystemAPI.Time in EFE. So that statement is not entirely true. It’s kept there to prove the point that you can’t use a SystemBase’s function/field inside EntitiesForEach :3