Search Unity

Efficient singletons entities and joins in ECS

Discussion in 'Entity Component System' started by esc_marcin, Aug 14, 2019.

  1. esc_marcin

    esc_marcin

    Joined:
    Sep 30, 2016
    Posts:
    23
    There's a pattern in used in FPS sample I dislike, but I can't see an obvious alternative.

    Code (CSharp):
    1. protected override void OnUpdate()
    2. {
    3.     var gameModeArray = m_gameModeGroup.GetComponentArray<GameMode>();
    4.     if (gameModeArray.Length == 0)
    5.         return;
    6.  
    7.     GameDebug.Assert(gameModeArray.Length == 1,
    8.         "There should only be one gamemode. Found:{0}",
    9.         gameModeArray.Length);
    10.  
    11.     var localPlayerArray = m_localPlayerGroup.GetComponentArray<LocalPlayer>();
    12.     GameDebug.Assert(localPlayerArray.Length == 1,
    13.         "There should only be one localplayer. Found:{0}",
    14.         localPlayerArray.Length);
    15.  
    16.     var gameMode = gameModeArray[0];
    17.     var localPlayer = localPlayerArray[0];
    18.  
    19.     Game.game.clientFrontend.UpdateIngame(gameMode, localPlayer);
    20. }
    source: https://github.com/Unity-Technologi.../Scripts/Game/Frontend/ClientFrontend.cs#L157

    The ClientFrontEndUpdate system expects there to be exactly one GameMode and exactly one LocalPlayer entity. It needs to do a join on those two entities in order to call clientFrontend.UpdateIngame.

    If these were not restricted to singletons it seems the general form would be the Cartesian product of gameModeGroup and localPlayerGroup. Where you would call update for every gameMode & localPlayer pair.

    But even restricting it to singleton entities I don't see how to avoid allocation due to needing to use ToComponentArray() to operate on two queries at once.
     
  2. esc_marcin

    esc_marcin

    Joined:
    Sep 30, 2016
    Posts:
    23
    From another recent post I did discover GetSingleton which seems like it would solve part of the problem but it doesn't support Monobehavior components.
     
  3. Srokaaa

    Srokaaa

    Joined:
    Sep 18, 2018
    Posts:
    169
  4. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    You can use Query.GetSingletonEntity() and grab the object from EntityManager (where Query is GetEntityQuery(typeof(Object))
     
    esc_marcin likes this.