Search Unity

How to set and get global values accross systems?

Discussion in 'Entity Component System' started by alexandre-fiset, Mar 7, 2019.

  1. alexandre-fiset

    alexandre-fiset

    Joined:
    Mar 19, 2012
    Posts:
    715
    I have a system (rough code below) that updates the ingame time of day.

    What is the best way to access WorldTimeClock data from other systems considering there should only be one active WorldTimeClock at a time, and that the "dependant" systems updates after this one?

    I previously used GetSingleton, but that stopped working since I converted my proxy script to IConvertGameObjectToEntity. GetComponentData is deprecated so I'm kind of lost.

    It would be nice to have this kind of scenario in the samples (sharing/accessing data between systems).

    Code (CSharp):
    1. using Unity.Burst;
    2. using Unity.Collections;
    3. using Unity.Entities;
    4. using Unity.Jobs;
    5. using UnityEngine;
    6.  
    7. namespace Game
    8. {
    9.     /// <summary>
    10.     /// Clock system that keeps track of time.
    11.     /// </summary>
    12.     public class WorldTimeClockSystem : JobComponentSystem
    13.     {
    14.         [BurstCompile]
    15.         struct TickClockJob : IJobProcessComponentData<WorldTimeClock>
    16.         {
    17.             [ReadOnly] public float SystemDeltaTime;
    18.  
    19.             public void Execute(ref WorldTimeClock t)
    20.             {
    21.                 var speed       = t.SpeedOfTime;
    22.                 var deltaTime   = SystemDeltaTime * speed;
    23.  
    24.                 float ts = t.TotalSeconds + deltaTime;
    25.  
    26.                 float s = t.Second + deltaTime;
    27.                 float m = t.Minute;
    28.                 float h = t.Hour;
    29.                 float d = t.Day;
    30.                 float w = t.Week;
    31.                 float y = t.Year;
    32.  
    33.                 while ( s > 59 ) { m += 1; s -= 59; }
    34.                 while ( m > 59 ) { h += 1; m -= 59; }
    35.                 while ( h > 23 ) { d += 1; h -= 23; }
    36.                 while ( w > 51 ) { y += 1; w -= 51; }
    37.  
    38.                 var newT = t;
    39.                     newT.Second = s;
    40.                     newT.Minute = m;
    41.                     newT.Hour = h;
    42.                     newT.Day = d;
    43.                     newT.Week = w;
    44.                     newT.Year = y;
    45.                     newT.DeltaTime = deltaTime;
    46.                     newT.SpeedOfTime = speed;
    47.                     newT.TotalSeconds = ts;
    48.  
    49.                 t = newT;
    50.             }
    51.         }
    52.  
    53.         protected override JobHandle OnUpdate(JobHandle inputDeps)
    54.         {
    55.             return new TickClockJob { SystemDeltaTime = Time.deltaTime }.Schedule(this, inputDeps);
    56.         }
    57.  
    58.     }
    59. }
    60.  
     
    Last edited: Mar 7, 2019
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    GetSingleton\SetSingleton it's best for that purposes. What the problems with singleton entity in your case? Show errors and we help you :)
     
    Krajca likes this.
  3. alexandre-fiset

    alexandre-fiset

    Joined:
    Mar 19, 2012
    Posts:
    715
    The error was that there were no WorldTimeClock entity found when I created the entity with IConvertGameObjectToEntity. But I found a solution: I absolutely need the ConvertToEntity script attached to my objects in order for the whole thing to work properly. I find it kind of odd that something this mandatory isn't attached automatically to the object like GameObjectEntity was. Anyway.

    Now GetSingleton work. But it would be nice to have an example of where and how to call SetSingleton. For now I just create one entity and the method automatically works, but knowing how to set it would be nice. I also don't know if this is the right method at all for accessing global data between job systems...
     
    lclemens likes this.
  4. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    Read @5argon blog :) (on construction now) http://68.183.97.180/ecs-singleton-data/
     
  5. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    Singleton is really just query 1 entity from the world (found 0 or >1 will be an error). And Set/GetSingleton could not create one. No matter what you have to create the singleton manually. You may create it at some system's OnCreateManager, or in Convert of some IConvertGameObjectToEntity use the provided entity manager to CreateEntity (If your singleton is not the thing being converted itself, otherwise you already get it from the convert)

    ^^^EDIT : Ah you beat me to it!!
     
    andywatts likes this.
  6. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    :p
     
  7. andywatts

    andywatts

    Joined:
    Sep 19, 2015
    Posts:
    112
    New link to 5argon's blog post on ECS Singletons and api docs.
     
    Last edited: Jan 21, 2020
  8. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    I can't believe I forgot to add the convert-to-entity script too! Doh!!