Search Unity

Resolved Clarification on accessing managed types in the tutorial

Discussion in 'Entity Component System' started by Luemus, Sep 30, 2022.

  1. Luemus

    Luemus

    Joined:
    May 20, 2013
    Posts:
    107
    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;

    Code (CSharp):
    1.         // The Entities.ForEach below is Burst compiled (implicitly).
    2.         // And time is a member of SystemBase, which is a managed type (class).
    3.         // This means that it wouldn't be possible to directly access Time from there.
    4.         // 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.

    Code (CSharp):
    1.     [BurstCompile]
    2.     public void OnUpdate(ref SystemState state)
    3.     {
    4.         // The amount of rotation around Y required to do 360 degrees in 2 seconds.
    5.         var rotation = quaternion.RotateY(SystemAPI.Time.DeltaTime * math.PI);
    6.         ...
    How does this work? Is it because one is a struct (deriving from ISystem) and other is a class (deriving from SystemBase)?
     
  2. Shane_Michael

    Shane_Michael

    Joined:
    Jul 8, 2013
    Posts:
    158
    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.
     
  3. JesOb

    JesOb

    Joined:
    Sep 3, 2012
    Posts:
    1,109
    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
     
  4. Shane_Michael

    Shane_Michael

    Joined:
    Jul 8, 2013
    Posts:
    158
    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().
     
  5. Luemus

    Luemus

    Joined:
    May 20, 2013
    Posts:
    107
    Alright, thinking about it a little bit more cleared things. Thanks for the help!
     
  6. DaxodeUnity

    DaxodeUnity

    Unity Technologies

    Joined:
    Aug 5, 2021
    Posts:
    27
    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