Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question [Entities 1.0.0-pre.15] ECS & Cinemachine

Discussion in 'Entity Component System' started by mcapdegelle, Jan 6, 2023.

  1. mcapdegelle

    mcapdegelle

    Joined:
    Nov 7, 2014
    Posts:
    22
    From 1.0, as I understand, all entities must reside in a sub-scene.
    How would you plug a virtual cinemachine camera (which requires a reference to a gameobject to follow) to an entity residing in the subscene?

    I'm thinking about making a ScriptaleObject containing a RigidTransform, referenced by a ReadTransform MonoBehaviour on the non-ECS side, and a WriteTransform managed component on the ECS side.

    Do you have a better solution? Looks too complicated for me.
     
    Last edited: Jan 6, 2023
  2. mcapdegelle

    mcapdegelle

    Joined:
    Nov 7, 2014
    Posts:
    22
  3. Vacummus

    Vacummus

    Joined:
    Dec 18, 2013
    Posts:
    191
    The simplest solution I have found is to keep the Player GameObject out of the subscene so it's not converted to an Entity. If you have a need for the Player GameObject in the entity world, then you can just create a Player Entity and create a System (that runs on the main thread) that copies the Transform data from the Player GameObject to the Player Entity (or vice versa depending on your use case).
     
  4. apaxnid

    apaxnid

    Joined:
    Nov 18, 2012
    Posts:
    34
    Spawn GameObject and link it with your player entity using CompanionLink.
    1. Create prefab with simple monobehaviour to find CmCamera (FindCmCamera)
    2. Add GameObjectPrefab ComponentData to store GameObject reference in your Player entity.
    3.Spawn GameObjectPrefab and link it with your Playerentity using CompanionLink.

    FindCmCamera.cs
    Code (CSharp):
    1. public class FindCMCamera : MonoBehaviour
    2. {
    3.     // Start is called before the first frame update
    4.     void Start()
    5.     {
    6.         CmCamera camera = (CmCamera)FindObjectOfType(typeof(CmCamera));
    7.         camera.Target = new CameraTarget
    8.         {
    9.             TrackingTarget = this.transform,
    10.             LookAtTarget = this.transform
    11.         };
    12.     }
    13. }
    System to spawn and link gameobject to your Player entity
    Code (CSharp):
    1. public partial struct GameObjectInitSystem : ISystem
    2. {
    3.     [BurstCompile]
    4.     public void OnCreate(ref SystemState state)
    5.     {
    6.         var query = SystemAPI.QueryBuilder().WithAll<GameObjectPrefab>().Build();
    7.         state.RequireForUpdate(query);
    8.     }
    9.  
    10.     [BurstCompile]
    11.     public void OnDestroy(ref SystemState state)
    12.     {
    13.     }
    14.  
    15.     public void OnUpdate(ref SystemState state)
    16.     {
    17.         var ecbSingleton = SystemAPI.GetSingleton<BeginSimulationEntityCommandBufferSystem.Singleton>();
    18.         var ecb = ecbSingleton.CreateCommandBuffer(state.WorldUnmanaged);
    19.  
    20.         // Instantiate the associated GameObject from the prefab.
    21.         foreach (var (goPrefab, entity) in SystemAPI.Query<GameObjectPrefab>().WithEntityAccess())
    22.         {
    23.             var go = GameObject.Instantiate(goPrefab.Prefab);
    24.             ecb.AddComponent(entity, new CompanionLink{ Companion = go });
    25.             ecb.RemoveComponent<GameObjectPrefab>(entity);
    26.         }
    27.     }
    28. }
    Code (CSharp):
    1. public class GameObjectPrefabAuthoring : MonoBehaviour
    2. {
    3.     public GameObject Prefab;
    4.  
    5.     public class Baker : Baker<GameObjectPrefabAuthoring>
    6.     {
    7.         public override void Bake(GameObjectPrefabAuthoring authoring)
    8.         {
    9.             AddComponentObject(new GameObjectPrefab { Prefab = authoring.Prefab });
    10.         }
    11.     }
    12. }
    13.  
    14. // Stores a GameObject prefab that will be instantiated and associated with the entity.
    15. public class GameObjectPrefab : IComponentData
    16. {
    17.     public GameObject Prefab;
    18. }
     
    Haxel0rd, mcapdegelle and jennal like this.
  5. mcapdegelle

    mcapdegelle

    Joined:
    Nov 7, 2014
    Posts:
    22
    Nice, Thanks a lot!
     
  6. Vacummus

    Vacummus

    Joined:
    Dec 18, 2013
    Posts:
    191
    Hmm, from what I have gathered, "CompanionLink" is not meant for public use and its functionality is limited to certain component types: https://forum.unity.com/threads/entities-0-50-addcomponentobject-not-creating-companionlink.1256181/

    Here is a recent thread of devs discussing different hybrid workflows for 1.0: https://forum.unity.com/threads/clarification-of-hybrid-changes-in-1-0.1375674/

    And here is a thread on proposals for a more official hybrid workflow: https://forum.unity.com/threads/proposal-for-hybrid-interoperability.1345562/
     
    Haxel0rd and mcapdegelle like this.
  7. mcapdegelle

    mcapdegelle

    Joined:
    Nov 7, 2014
    Posts:
    22
    Thanks for the info! Looks like it's still complicated to do hybrid :s
    For now, I did something like you suggested :

    Code (CSharp):
    1. public class PlayerTracker : MonoBehaviour
    2. {
    3.     private void Start()
    4.     {
    5.         var em = World.DefaultGameObjectInjectionWorld.EntityManager;
    6.         var entity = em.CreateEntity();
    7.         em.SetName(entity, name);
    8.         em.AddComponentObject(entity, this);
    9.     }
    10. }
    11.  
    12. [UpdateInGroup(typeof(TransformSystemGroup), OrderLast = true)]
    13. public partial class PlayerTrackerSystem : SystemBase
    14. {
    15.     protected override void OnUpdate()
    16.     {
    17.         if (!SystemAPI.TryGetSingletonEntity<PlayerTag>(out var playerEntity))
    18.             return;
    19.  
    20.         var localToWorld = SystemAPI.GetComponent<LocalToWorld>(playerEntity);
    21.  
    22.         Entities.ForEach((PlayerTracker tracker) =>
    23.         {
    24.             tracker.transform.SetPositionAndRotation(localToWorld.Position, localToWorld.Rotation);
    25.         }).WithoutBurst().Run();
    26.     }
    27. }
    Cinemachine points to the PlayerTracker Game Object residing in the same scene.
     
    Haxel0rd likes this.
  8. CosmusOne

    CosmusOne

    Joined:
    Feb 7, 2021
    Posts:
    6
    error CS0122: 'CompanionLink' is inaccessible due to its protection level entities 1.0.0
     
    Last edited: Apr 29, 2023