Search Unity

Question How to pass data between Entities (1.0.0) and MonoBehaviour?

Discussion in 'Entity Component System' started by Zimaell, Mar 20, 2023.

  1. Zimaell

    Zimaell

    Joined:
    May 7, 2020
    Posts:
    408
    How to transfer data from Entities to MonoBehaviour, and also how to transfer data from MonoBehaviour to Entities?

    a little more detail what I want - there is a world built on Entities, but I need to transfer the data of some objects (for example, positions) to a MonoBehaviour object, this object already contains a script that processes information, sends it to the server, and also receives a response, then the received data needs to be received again convey in Entities.
    How to do it?
     
  2. Thygrrr

    Thygrrr

    Joined:
    Sep 23, 2013
    Posts:
    700
    I do it like this (sort of dirty)


    Monobehaviour getting or setting an Entity Component Data:
    Code (CSharp):
    1.   _manager = World.DefaultGameObjectInjectionWorld.EntityManager;
    2.  
    3. var finder = _manager.CreateEntityQuery(typeof(BubbleOrigin), typeof(SceneSection));
    4.             finder.AddSharedComponentFilter(new SceneSection {SceneGUID = subScene.SceneGUID});
    5.             root = finder.GetSingletonEntity();
    6.             var origin = _manager.GetComponentData<BubbleOrigin>(root);

    Systems (not burst compatible!) interacting with Mono stuff and getting/setting transforms
    Code (CSharp):
    1.         protected override void OnStartRunning()
    2.         {
    3.             _celestial = Cam.celestial; //This is a service locator, but you can just use FindObjectOfType
    4.             _rig = Cam.local;
    5.             _zoomRail = _rig.GetChild(0);
    6.             _leanPivot = _zoomRail.GetChild(0);
    7.  
    8.             _camera = Cam.localCam;
    9.             _cam = _camera.transform;
    10.  
    11.             _goalRotation = _rig.rotation;
    12.             _rig.gameObject.SetActive(true);
    13.  
    14.             EntityManager.CreateSingleton(BuildCameraData());
    15.      
    16.             _inputActions.Enable();
    17.         }
    18.  
    19. protected override void OnUpdate()
    20.         {
    21.             if (math.length(directionLock) > 0.1f) _goalRotation = Quaternion.LookRotation(directionLock);
    22.          
    23.             //Maybe fix this... not too pretty.
    24.             if (!SystemAPI.TryGetSingletonEntity<TagFocus>(out var focused))
    25.             {
    26.                 focused = SystemAPI.GetSingletonEntity<TagCommand>();
    27.             }
    28.  
    29.             var transform = SystemAPI.GetComponent<LocalTransform>(focused);
    30.             ApplyFreeLookState(transform);  //This accesses the objects I found in OnStartRunning
    31.  
    32.             //Write CameraData for UI systems
    33.             SystemAPI.SetSingleton(BuildCameraData());
    34.         }

    I also have some native data structures for larger things, such as Navigation Meshes (not the unity type), and these can be read by whatever. I do not like that these are global variable style singletons, but dependency injection is just not my jam with ECS, it's too convoluted already.
     
    Zimaell likes this.
  3. brunocoimbra

    brunocoimbra

    Joined:
    Sep 2, 2015
    Posts:
    679
    I would do it entirely in the System land.

    So a System would be responsible for setting the data in the monobehaviours, monobehaviours do whatever they need to do and store the data that they are receiving from the server, and then another System (or maybe the same one? who knows) uses that data the way they want.

    The reasoning here is that this way you have control of your data flow in one location, while still allowing the MBs to behave as semi-independent objects (semi because they still require some input from the systems, but they don't need to care about ECS at all)
     
    dannyalgorithmic likes this.
  4. Zimaell

    Zimaell

    Joined:
    May 7, 2020
    Posts:
    408
    So I didn’t understand how to transfer data, the idea that the system will transfer data from mono to mono is good, but how?
    in fact, I need to understand how to do the following - in mono there is a field List (float3), as soon as it is filled immediately, this data is sent in Entities, I suppose to a DynamicBuffer...
    How to do this, I did not understand, can you give an example?
     
  5. FederalRazer89

    FederalRazer89

    Joined:
    Nov 24, 2019
    Posts:
    83
    Did you solve your problem? Do you just need to access the Mono from a systembase in ECS or do you have some more complex you need to do?

    If you just need to access Mono from ECS you can just use a managed component and have a reference to the GameObject. Example below this might not be the fastest or efficient, but it works. And i can also change GameObject components from systembase in ECS.


    Code (CSharp):
    1.  
    2. public class CharacterControllerClass : IComponentData
    3. {
    4.     public GameObject characterControllerGO;
    5.     public Animator animator;
    6. }
    7.  
    You can check my current solution at the bottom of this thread: Resolved - Problems with interaction with GameObject from ECS - Unity Forum
     
    dannyalgorithmic and Zimaell like this.
  6. FaithlessOne

    FaithlessOne

    Joined:
    Jun 19, 2017
    Posts:
    315
    Here in the forums I also saw a slightly different approach to directly add a component to an entity which is a MonoBehavior like this:

    Code (CSharp):
    1. public class CharacterControllerClass : MonoBehavior, IComponentData
    2. {
    3.     public Animator animator;
    4. }
    You then don't have to specify the GameObject in the CharacterControllerClass, because it can be accessed like any other MonoBehavior via

    characterControllerClassInstance.gameObject

    I don't know if the stated approach has some disadvantages compared to the approach of FederalRazer89. If someone knows I appreciate feedback.
     
  7. Ellsoworth

    Ellsoworth

    Joined:
    Mar 6, 2018
    Posts:
    1
    I tried this. It's coooooool, but less useful than I thought