Search Unity

Resolved how to transfer data between mono obj with ecs runtime

Discussion in 'Entity Component System' started by firleaves1, Nov 13, 2022.

  1. firleaves1

    firleaves1

    Joined:
    Aug 18, 2021
    Posts:
    3
    i can change authoring data by editor inspector windows,so i want change authoring data via script
    Code (CSharp):
    1. public class GameConfigAuthoring : UnityEngine.MonoBehaviour
    2. {
    3.     public UnityEngine.GameObject EnemyPrefab;
    4.  
    5.     public int EnemyCount;
    6.  
    7.     public float EnemyActiveRadius;
    8.  
    9.     private static GameConfigAuthoring _Instance;
    10.     public static GameConfigAuthoring Instance
    11.     {
    12.         get => _Instance;
    13.     }
    14.     private void Awake()
    15.     {
    16.         _Instance = this;
    17.     }
    18.  
    19.  
    20. }
    21.  
    I tried to use a singleton, but this doesn't work, the awake function is not triggered, so the singleton is an empty object
    so my question is that, how to transfer data between mono obj and ecs runtime??:(
     
    Last edited: Nov 13, 2022
    Haxel0rd likes this.
  2. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    You need to either access the gameobject from the entity. (
    )

    You can use class IComponentData (not struct) to keep a reference to a Monobehaviour "on" an entity.

    Or acces an entity from the game object. (
    )

    You can get a reference to the world for the static reference World

    World.DefaultGameObjectInjectionWorld
    .

    Then using wuery you can do whetever you need, like acessing a singleton :

    Code (CSharp):
    1.         EntityQuery q =  World.EntityManager.CreateEntityQuery(new EntityQueryDesc()
    2.         {
    3.             All = new ComponentType[] { ComponentType.ReadOnly<ICOMPONENT>() }
    4.         });
    5.         if(q.TryGetSingleton<ICOMPONENT>(out var singleton)){
    6.             // Do stuff
    7.         }
    8.         q.GetSingletonEntity();
     
    Haxel0rd likes this.
  3. firleaves1

    firleaves1

    Joined:
    Aug 18, 2021
    Posts:
    3
    thx,
    I found another way to change runtime data
    Code (CSharp):
    1.  EntityManager em = World.DefaultGameObjectInjectionWorld.EntityManager;
    2.             var query = em.CreateEntityQuery(typeof(GameConfig));
    3.             NativeArray<Entity> entities = query.ToEntityArray(Allocator.Temp);
    4.             if (entities.Length == 1)
    5.             {
    6.                 var entity = entities[0];
    7.                 var gameConfig = em.GetComponentData<GameConfig>(entity);
    8.                 em.AddComponentData(entity, new GameConfig
    9.                 {
    10.                     EnemyCount = gameConfig.EnemyCount + 500,
    11.                     EnemyPrefab = gameConfig.EnemyPrefab,
    12.                     EnemyActiveRadius = gameConfig.EnemyActiveRadius
    13.                 });
    14.             }
     
    Haxel0rd likes this.
  4. WAYNGames

    WAYNGames

    Joined:
    Mar 16, 2019
    Posts:
    992
    That's the same thing has my last code block.
    You are essentially referencing a singleton entity that has the GameConfig component and setting it's value.
    What you do in the if statement makes no sense to me.
    You get a component from an entity to add the same new component and just add 500 to the enemy count.
    You could just get the singleton component and increments the enemy count value.
     
  5. firleaves1

    firleaves1

    Joined:
    Aug 18, 2021
    Posts:
    3
    thx, the singleton is better than my code :D