Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

How to represent a player camera in hybrid ECS?

Discussion in 'Data Oriented Technology Stack' started by Cubic_Creo, May 4, 2018.

  1. Cubic_Creo


    Oct 13, 2014
    This is probably an easy one for you guys! Let's say I have a player GameObject that I'm instantiating. It has a GameObjectEntity on it, and so I grab the entity and add a PlayerInput component. I have a PlayerInputSystem set up, no problem. But now let's say I have a camera GameObject as a child of that player GameObject. How would I represent/access that?

    When I instantiate the player, do I need to GetComponentInChildren<Camera>(), then grab the camera's entity and assign that to a entity? Or maybe I should have a "PlayerSetup" MonoBehaviour on the player GameObject that holds a reference to the child camera? Or am I completely missing something fundamental about hybrid ECS?
  2. Spy-Shifty


    May 5, 2011

    there are many ways to do this...
    So I will show you how I handle my camera (3. person game)
    Code (CSharp):
    2. public class ThirdPersonCamera : MonoBehaviour {
    3.     public Transform stayTransform;
    4.     public Transform crouchTransform;
    5.     [HideInInspector]
    6.     public float verticalAngle;
    7. }
    9. public class ThirdPersonCameraSystem : ComponentSystem {
    10.     struct CameraData {
    11.         public int Length;
    12.         public ComponentArray<Transform> transforms;
    13.         public ComponentArray<ThirdPersonCamera> thirdPersonCam;
    14.         public ComponentArray<Cinemachine.CinemachineStateDrivenCamera> stateDrivenCamera;
    15.     }
    16.     struct PlayerData {
    17.         public int Length;
    18.         public ComponentArray<Transform> transforms;
    19.         public ComponentDataArray<PlayerInput> input;
    20.         public ComponentArray<Animator> animators;
    21.     }
    22.     [Inject] CameraData cameraData;
    23.     [Inject] PlayerData playerData;
    25.     protected override void OnUpdate() {
    26.         if(playerData.Length == 0) {
    27.             return;
    28.         }
    30.         float rotationSpeed = Bootstrap.GameSettings.HorizontalLookSpeed;
    32.         PlayerInput input = playerData.input[0];
    33.         Transform playerTransform = playerData.transforms[0];
    34.         Animator animator = playerData.animators[0];
    35.         float dt = Time.deltaTime;
    36.         for (int i = 0; i < cameraData.Length; i++) {
    37.             cameraData.stateDrivenCamera[i].m_AnimatedTarget = animator;
    38.             cameraData.transforms[i].position = playerTransform.position;
    39.             cameraData.transforms[i].Rotate(new Vector3(0, input.look.x, 0) * rotationSpeed * dt);
    41.             ThirdPersonCamera thirdPersonCam = cameraData.thirdPersonCam[i];
    43.             thirdPersonCam.verticalAngle += input.look.y * rotationSpeed * dt;
    44.             thirdPersonCam.verticalAngle = Mathf.Clamp(thirdPersonCam.verticalAngle, -70, 70);
    46.             Quaternion rotation = Quaternion.Euler(-thirdPersonCam.verticalAngle, 0, 0);
    47.             thirdPersonCam.stayTransform.localRotation = rotation;
    48.             thirdPersonCam.crouchTransform.localRotation = rotation;
    49.         }
    50.     }
    51. }
    RaL and vanxining like this.
  3. Cubic_Creo


    Oct 13, 2014
    Thanks. That's very helpful.

    Looks like the solution above would work if you have a single player. But say I want to build a game with a bunch of players, some AI and some controlled by humans, and I want to move each character's head to indicate where they're looking. In that case it seems I would need to have some sort of relationship between each character and their head. Each character would know where it wants to look, and then each would tell its head where to point. Any thoughts on how that sort of relationship could be set up?

    It seems to work to have an Entity as a field in an IComponentData struct (ie it compiles). It seems like that might be a way to set up a relationship between character and head. But I haven't quite figured out yet where or how to assign a value to that entity field. My first instinct is to want to assign it when spawning a character, but I haven't found a way to to assign an Entity field in such a way that it persists.

    Maybe I'm missing something obvious. Maybe I'm overcomplicating things. Help? :)
  4. vanxining


    Mar 29, 2018
    I'm a newbie, but the transform of each game object has a "forward" field which may meet your requirement.
  5. Cubic_Creo


    Oct 13, 2014
    Thanks. What I'm really looking for is a way to set up relationships in ECS, or if not that, then another way of thinking about relationships in the context of ECS. Before I can do anything with the transform, I need to have access to the transform.
  6. mhernandez88


    Jul 20, 2016
    In case you never figured it out or need a refresher, heres a video.