Search Unity

  1. We are migrating the Unity Forums to Unity Discussions by the end of July. Read our announcement for more information and let us know if you have any questions.
    Dismiss Notice
  2. Dismiss Notice

Discussion DOTS Netcode: (tutorial) syncing values between monobehaviour and ecs.

Discussion in 'Multiplayer' started by AdamBebko, Oct 20, 2020.

  1. AdamBebko

    AdamBebko

    Joined:
    Apr 8, 2016
    Posts:
    168
    After much difficulty starting off with dots Netcode, I finally found a pretty easy way to sync data between mono behaviours and ecs components. I thought I'd share it to help fellow noobs in the future.

    See code below.

    The motivation: I was using AR foundation and wanted to sync tracking over dots Netcode. But so far, AR foundation uses only monobehaviours.

    The mono script is attached to a game object with ConvertToEntity Client Server script on it, set to "Convert and inject", and "Client". It stores an ecs component as a field called data. Upon conversion it stores a reference to its converted entity.

    The goal is to modify one value from mono, and have it sync to ecs, and the other value modified from ecs, and sync to mono.

    On the mono's update method, it looks for the client world, and then retrieves the data component from its converted entity using GetComponentData. It then copies the modified value from it. It then copies its own modified value back into the entity using SetComponentData.

    I haven't yet found a way to ensure that one value can't be modified from the wrong end, but I suppose you could create methods to do the work for you with very explicit names like ModifyValueFromECSOnly(value)

    Anyway, I hope this simple example saves others the huge headache that I experienced trying to get this working.

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.NetCode;
    3. using UnityEngine;
    4.  
    5. public class HybridTestMono : MonoBehaviour, IConvertGameObjectToEntity {
    6.     public HybridTestData data;
    7.     public Entity entity;
    8.    
    9.     void Update() {
    10.  
    11.         data.MonoModifiedValue += 1;
    12.        
    13.         foreach (World world in World.All) {
    14.             if (world.GetExistingSystem<ClientSimulationSystemGroup>() != null) {
    15.                 HybridTestData component = world.EntityManager.GetComponentData<HybridTestData>(entity);
    16.                 data.EcsModifiedValue = component.EcsModifiedValue;
    17.  
    18.                 component.MonoModifiedValue = data.MonoModifiedValue;
    19.                 world.EntityManager.SetComponentData(entity, component);
    20.             }
    21.  
    22.         }
    23.     }
    24.  
    25.     public void Convert(Entity entity, EntityManager dstManager, GameObjectConversionSystem conversionSystem) {
    26.         HybridTestData data = new HybridTestData {EcsModifiedValue = 3000};
    27.         dstManager.AddComponent<HybridTestData>(entity);
    28.         dstManager.SetComponentData(entity, data);
    29.         this.entity = entity;
    30.     }
    31. }
    32.  
    33. public struct HybridTestData : IComponentData {
    34.     public float EcsModifiedValue;
    35.     public float MonoModifiedValue;
    36. }
    37.  
    38.  
    39. [UpdateInGroup(typeof(ClientSimulationSystemGroup))]
    40. public class HybridTestSystem : SystemBase {
    41.     protected override void OnUpdate() {
    42.        
    43.      
    44.         Entities.ForEach((ref HybridTestData hybridTest) => {
    45.             hybridTest.EcsModifiedValue += 1;
    46.         }).WithoutBurst().Run();
    47.     }
    48. }
    49.  
     
    U_ru_Ru and BitPax like this.
  2. Jehy

    Jehy

    Joined:
    Sep 25, 2014
    Posts:
    8
    xilef00x likes this.