Search Unity

99% Pure ECS Camera System Example

Discussion in 'Entity Component System' started by Filtiarn_, Sep 3, 2019.

  1. Filtiarn_

    Filtiarn_

    Joined:
    Jan 24, 2013
    Posts:
    173
    Hi this is my pretty much pure ECS camera system. A Pure ECS entity is created with a camera component and has a child entity with spring arm component (Like Unreal so please don't hate on me :) )
    The SpringArm entity's position is saved and sent to Camera.Main's position and Camera entity's rotation is saved and sent to Camera.Main's rotation.

    Edit : Fixed wrong rotation being used

    Authors
    Code (CSharp):
    1. [RequiresEntityConversion]
    2. public class CameraAuthor : MonoBehaviour, IConvertGameObjectToEntity
    3. {
    4.     public void Convert(Entity entity, EntityManager entityManager, GameObjectConversionSystem conversionSystem)
    5.     {
    6.         entityManager.AddComponentData(entity, new CameraComponent());
    7.     }
    8. }
    9.  
    10. [RequiresEntityConversion]
    11. public class CameraSpringArmAuthor : MonoBehaviour, IConvertGameObjectToEntity
    12. {
    13.     public void Convert(Entity entity, EntityManager entityManager, GameObjectConversionSystem conversionSystem)
    14.     {
    15.         entityManager.AddComponentData(entity, new CameraSpringArmComponent());
    16.     }
    17. }
    18.  
    19. [RequiresEntityConversion]
    20. public class CameraTargetAuthor : MonoBehaviour, IConvertGameObjectToEntity
    21. {
    22.     public void Convert(Entity entity, EntityManager entityManager, GameObjectConversionSystem conversionSystem)
    23.     {
    24.         entityManager.AddComponentData(entity, new CameraTargetComponent());
    25.     }
    26. }
    Components
    Code (CSharp):
    1. using Unity.Entities;
    2.  
    3. public struct CameraComponent: IComponentData
    4. {
    5.     byte vaule;
    6. }
    7.  
    8. public struct CameraSpringArmComponent : IComponentData
    9. {
    10.     byte value;
    11. }
    12.  
    13. public struct CameraTargetComponent : IComponentData
    14. {
    15.     byte value;
    16. }
    System
    Code (CSharp):
    1.  
    2. using Unity.Entities;
    3. using Unity.Transforms;
    4. using Unity.Mathematics;
    5. using Unity.Collections;
    6. using UnityEngine;
    7.  
    8. [UpdateInGroup(typeof(PresentationSystemGroup))]
    9. public class CaneraSystem : ComponentSystem
    10. {
    11. private EntityQuery cameraTargetEntityQuery;
    12. private float3 cameraRenderTranslation;
    13. private float3 cameraRenderRotation;
    14.  
    15. protected override void OnCreate()
    16. {
    17. cameraTargetEntityQuery = GetEntityQuery(ComponentType.ReadOnly<CameraTargetComponent>(),ComponentType.ReadOnly<LocalToWorld>());
    18. }
    19.  
    20. protected override void OnUpdate()
    21. {
    22. var cameraTargetEntities = cameraTargetEntityQuery.ToEntityArray(Allocator.TempJob);
    23.  
    24. if (cameraTargetEntities.Length == 0)
    25. return;
    26.  
    27. //Initalize Camera
    28. Entities.WithNone(typeof(Parent)).ForEach((Entity entity, ref CameraComponent cameraComponent) =>
    29. {
    30. PostUpdateCommands.AddComponent(entity, new LocalToParent());
    31. PostUpdateCommands.AddComponent(entity,new Parent {});
    32. return;
    33.  
    34. });
    35.  
    36. //Update Spring Arm
    37. Entities.ForEach((ref Translation translation, ref Rotation rotation, ref CameraSpringArmComponent cameraSpringArmComponent, ref LocalToParent localToParent, ref LocalToWorld localToWorld) =>
    38. {
    39. translation.Value = new float3(0,0,-10);
    40. cameraRenderTranslation = localToWorld.Position;
    41. });
    42.  
    43. //Update Camera Parent | Position | Rotation
    44. Entities.ForEach((Entity entity, ref Translation translation, ref Rotation rotation, ref CameraComponent cameraComponent, ref Parent parent, ref LocalToWorld localToWorld) =>
    45. {
    46. parent.Value = cameraTargetEntities[0];
    47. cameraRenderRotation = localToWorld.Forward;
    48.  
    49. });
    50.  
    51.  
    52. //Set Camera Renderer Position And Rotation
    53. Camera.main.transform.position = cameraRenderTranslation;
    54. Camera.main.transform.forward = cameraRenderRotation;
    55.  
    56. //Dispose of Arrays
    57. cameraTargetEntities.Dispose();
    58. }
    59. }
    60.  
    61.  
    62. //Set Camera Renderer Position And Rotation
    63. Camera.main.transform.position = cameraRenderTranslation;
    64. Camera.main.transform.forward = cameraRenderRotation;
    65.  
    66. //Dispose of Arrays
    67. cameraTargetEntities.Dispose();
    68. }
    69. }
    70.  
     
    Last edited: Sep 4, 2019
  2. chelvaric

    chelvaric

    Joined:
    Mar 6, 2019
    Posts:
    5
    isn't this hybrid since you convert monobehaviours?
     
  3. shmafoo

    shmafoo

    Joined:
    Nov 22, 2016
    Posts:
    24
    Also, your system is called CaneraSystem instead of CameraSystem
     
  4. Filtiarn_

    Filtiarn_

    Joined:
    Jan 24, 2013
    Posts:
    173
    Shmafoozius opps.
    Chelvaric. I'm not using Monobehaviours. I'm using all ECS stuff. Only thing that is legacy is
    Code (CSharp):
    1. Camera.main.transform.position = cameraRenderTranslation;
    2. Camera.main.transform.forward = cameraRenderRotation;
    Thats why I called it 99% pure ecs. The camera is not a game object and is only entity. I have a game object called CameraRenderer that holds legacy camera stuff. Theres not ECS stuff being ran on that object.
     
  5. Filtiarn_

    Filtiarn_

    Joined:
    Jan 24, 2013
    Posts:
    173
    Chelvaric I am using Converters for injecting entities but at runtime its 100% percent no monobehaviours and all ECS
     
  6. alexandre-fiset

    alexandre-fiset

    Joined:
    Mar 19, 2012
    Posts:
    715
    Why don't you do things in a job and don't you pass your position/rotation through TransformAccess ?

    Pure DOTS should be jobbable; everything you do here is on the main thread and therefore have no benefits over standard Monobehaviours.
     
    Filtiarn_ likes this.
  7. Filtiarn_

    Filtiarn_

    Joined:
    Jan 24, 2013
    Posts:
    173
    Thanks for the advice alexandre-fiset. I don't have a lot of experience with DOTS. I'll look into it.
     
    MostHated likes this.