Search Unity

How would you design 3rd person controller rotations using ECS?

Discussion in 'Entity Component System' started by questionable_nickname, Jul 1, 2018.

  1. questionable_nickname

    questionable_nickname

    Joined:
    Jul 1, 2018
    Posts:
    10
    Trying to get into this new ECS stuff, raises infinitely many questions and code structure choices. Lets say you want to implement 3rd person controller. When you hold left mouse button and move mouse, camera rotates around player, when you hold right mouse button and move mouse, player rotates itself.

    Now the ideas I have:
    1. There is only one player and one player camera, also there is only one player input. So there is probably no need for ECS at all, just use MonoBehaviours and make GameObject references freely.
    2. Make a single PlayerRotationSystem which handles both player and its camera rotations.
    3. Make separate PlayerRotationSystem and CameraRotationSystem.
    With number 1 there is no further questions. After reading this forum I've found out Unity doesn't plan to remove MonoBehavious anywhere in the future, so probably it's ok to not even bother how to do some things in ECS. However, I think it may be possible that after getting familiar with ECS some things like this can be implemented without much struggle and it would be good to make everything in ECS just for the uniformity.

    In #2, we need some data. Camera rotation depends on camera data and player position, player rotation depends on player data and camera rotation. In single PlayerRotationSystem we have all the data needed and we're ok. However, there are some design choices as well:

    • Inject component data using the same approach as TwoStickShooter in its PlayerMoveSystem. What I dislike about this approach is that there will only ever be single element in all component data arrays, so it feels redundant.
    • Hold player input and other singleton data as public properties of corresponding systems and inject systems instead.
    And also the question arises, if we have both player and its camera data in single place, how can we make it affecting two separate GameObjects (player 3d model and camera)?

    With #3 we can make separate archetypes for camera and player, so update of component data should probably automatically update corresponging game objects, but there are further questions. It's clear how to pass camera related component data to CameraRotationSystem and how to pass player data to PlayerRotationSystem, but how do we pass player position to CameraRotationSystem and camera rotation to PlayerPositionSystem?

    Any ideas are welcome, thanks!
     
    Last edited: Jul 4, 2018
  2. questionable_nickname

    questionable_nickname

    Joined:
    Jul 1, 2018
    Posts:
    10
    I've just realized my "redundancy" argument regarding player input handling using component data arrays is completely wrong. In systems like PlayerInputSystem of pure TwoStickShooter it's not necessarily the case component data arrays will only have single element, because for example if we have two separate entities Player and Camera both having PlayerInput in their archetypes, it will inject both entities so that we can fill them with recent input data they need. It makes much more sense now.

    No, it's not wrong, lol.
     
    Last edited: Jul 4, 2018
  3. isbdnt

    isbdnt

    Joined:
    May 16, 2017
    Posts:
    35
    My solution is monobehavior for playerInput and CameraSystem for camera rotation and position
     
  4. questionable_nickname

    questionable_nickname

    Joined:
    Jul 1, 2018
    Posts:
    10
    How do you reference this MonoBehavior in your CameraSystem, using GameObject.Find inside SetupGameObjects?

    PS: as for now I've decided to stick with PlayerInputSystem injection, and public static properties for input data, because it's the least amount of nonsense (both in code and RAM).
     
    Last edited: Jul 4, 2018
  5. isbdnt

    isbdnt

    Joined:
    May 16, 2017
    Posts:
    35
    I simply put FollowPosition component into camera entity to trace the player entity in CameraSystem, and public static properties for camera data. I also have a monobehavior for camera input.
    Code (CSharp):
    1. public struct FollowPosition : IComponentData
    2.     {
    3.         public Entity Followee;
    4.         public float3 Position;
    5.         public float3 FootNormal;
    6.     }