Search Unity

Question New Input to ECS

Discussion in 'Entity Component System' started by RoughSpaghetti3211, Jun 30, 2021.

  1. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,708
    Played around with the new input system trying to get some input to entities. This is where I landed but not sure this is the best way. Any tip would be appreciated.

    Code (CSharp):
    1.  
    2. public class InputManager : MonoBehaviour, InputActions.IUIActions
    3. {
    4.  
    5.     private bool _doQuit;
    6.     private Vector2 _mousePos;
    7.     private EntityManager _entityManager;
    8.     private EntityArchetype _entityArchetype;
    9.     private EntityQuery _entityQuery;
    10.    
    11.  
    12.     public void OnEnable()
    13.     {
    14.         _entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
    15.         _entityArchetype = _entityManager.CreateArchetype(typeof(InputComponent));
    16.         var inputEntity = _entityManager.CreateEntity(_entityArchetype);
    17.         _entityManager.SetName(inputEntity,"InputEntity");
    18.     }
    19.  
    20.     public void Update()
    21.     {
    22.         if (_doQuit)
    23.             Application.Quit();
    24.     }
    25.  
    26.     public void OnAppCommands(InputAction.CallbackContext context)
    27.     {
    28.         _doQuit = context.ReadValueAsButton();
    29.     }
    30.  
    31.     public void OnNavigate(InputAction.CallbackContext context)
    32.     {
    33.         Debug.Log($"OnNavigate");
    34.     }
    35.  
    36.     public void OnSubmit(InputAction.CallbackContext context)
    37.     {
    38.         Debug.Log($"OnSubmit");
    39.     }
    40.  
    41.     public void OnCancel(InputAction.CallbackContext context)
    42.     {
    43.         Debug.Log($"OnCancel");
    44.     }
    45.  
    46.     public void OnPoint(InputAction.CallbackContext context)
    47.     {
    48.         Vector2 mousePosition = context.ReadValue<Vector2>();
    49.         _entityQuery = _entityManager.CreateEntityQuery(typeof(InputComponent));
    50.         _entityManager.SetComponentData(_entityQuery.GetSingletonEntity(), new InputComponent
    51.         {
    52.             MouseScreenPosition = new float2(mousePosition.x, mousePosition.y)
    53.         });
    54.     }
    55.  
    56.     public void OnClick(InputAction.CallbackContext context)
    57.     {
    58.         Debug.Log($"OnClick");
    59.     }
    60.  
    61.     public void OnScrollWheel(InputAction.CallbackContext context)
    62.     {
    63.         Debug.Log($"OnScrollWheel");
    64.     }
    65.  
    66.     public void OnMiddleClick(InputAction.CallbackContext context)
    67.     {
    68.         Debug.Log($"OnMiddleClick");
    69.     }
    70.  
    71.     public void OnRightClick(InputAction.CallbackContext context)
    72.     {
    73.         Debug.Log($"OnRightClick");
    74.     }
    75.  
    76.     public void OnTrackedDevicePosition(InputAction.CallbackContext context)
    77.     {
    78.         Debug.Log($"OnTrackedDevicePosition");
    79.     }
    80.  
    81.     public void OnTrackedDeviceOrientation(InputAction.CallbackContext context)
    82.     {
    83.         Debug.Log($"OnTrackedDeviceOrientation");
    84.     }
    85. }
    86.  
    87.  
     
  2. Balphagore

    Balphagore

    Joined:
    Jul 18, 2019
    Posts:
    82
  3. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,708
  4. PhilSA

    PhilSA

    Joined:
    Jul 11, 2013
    Posts:
    1,926
    Example of how I handle this:

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Jobs;
    3. using UnityEngine;
    4. using UnityEngine.InputSystem;
    5. using static GameInputActions;
    6.  
    7. [UpdateInGroup(typeof(SimulationSystemGroup), OrderFirst = true)]
    8. public class GameInputSystem : SystemBase
    9. {
    10.     public GameInputActions InputActions;
    11.  
    12.     protected override void OnStartRunning()
    13.     {
    14.         base.OnStartRunning();
    15.  
    16.         InputActions = new GameInputActions();
    17.         InputActions.Enable();
    18.         InputActions.DefaultMap.Enable();
    19.     }
    20.  
    21.     protected override void OnUpdate()
    22.     {
    23.         DefaultMapActions inputMap = InputActions.DefaultMap;
    24.  
    25.         GameInput tmpInput = new GameInput
    26.         {
    27.             Move = Vector2.ClampMagnitude(inputMap.Move.ReadValue<Vector2>(), 1f),
    28.             Look = inputMap.Look.ReadValue<Vector2>(),
    29.             JumpDown = inputMap.Jump.GetButtonDown(),
    30.             JumpUp = inputMap.Jump.GetButtonUp(),
    31.             ShootDown = inputMap.Shoot.GetButtonDown(),
    32.             ShootUp = inputMap.Shoot.GetButtonUp(),
    33.         };
    34.  
    35.         Entities.ForEach((Entity entity, ref GameInput gameInput) =>
    36.         {
    37.             gameInput = tmpInput;
    38.         }).Schedule();
    39.     }
    40. }
    The "GetButtonDown/Up()" functions are extensions and are explained here:
    https://forum.unity.com/threads/how...e-new-input-system.627184/page-2#post-7212220

    Also I remember having issues with enabling the inputActions in OnCreate() rather than OnStartRunning(), but I can't remember the specifics. So I'd just say that it's safer to do this in OnStartRunning()
     
    Last edited: Jun 30, 2021
    RLCK and RoughSpaghetti3211 like this.
  5. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,708
    thank you this is very helpful
     
  6. scottjdaley

    scottjdaley

    Joined:
    Aug 1, 2013
    Posts:
    163
    You can also make a system that both inherits from SystemBase and implements you input action interface. I'm not sure if there are any major advantages to this approach, but I like how I get a compile-tile error if I forget to handle some new control I added to the game. There is an example of this in the ECS samples repo here.
     
    RoughSpaghetti3211 likes this.
  7. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,708
    Thank you, what I like about the interface is it ensure i have my actions implemented, I seem to always forget too otherwise.
     
  8. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,708
    Ok took a stab at getting this working but it totally not what I expected. I would think that given

    upload_2021-6-30_17-22-25.png

    I should only see "clickDown" on my mouse click down printing once, and see "clickRelease" only once on release. Instead, im seeing both print 3 times on a fast tap and both keep printing on a mouse down hold. What am i missing here.

    Code (CSharp):
    1.  
    2.  
    3. public class GraphInputSystem : SystemBase , InputActions.IGraphActions
    4. {
    5.    
    6.     private InputActions _inputActions;
    7.     private bool _clickRelease;
    8.     private bool _clickDown;
    9.  
    10.        
    11.     #region SystemBase
    12.     protected override void OnCreate()
    13.     {
    14.         _inputActions = new InputActions();
    15.         _inputActions.Graph.SetCallbacks(this);
    16.     }
    17.    
    18.     protected override void OnStartRunning() => _inputActions.Enable();
    19.    
    20.     protected override void OnStopRunning() => _inputActions.Disable();
    21.    
    22.     protected override void OnUpdate()
    23.     {
    24.        
    25.         if (_clickDown)Debug.Log($"clickDown");
    26.         if (_clickRelease)Debug.Log($"clickRelease");
    27.  
    28.     }
    29.    
    30.     #endregion
    31.  
    32.  
    33.     #region IGraphActions
    34.    
    35.     public void OnClickRelease(InputAction.CallbackContext context) => _clickRelease = context.ReadValueAsButton();
    36.    
    37.     public void OnClickDown(InputAction.CallbackContext context) => _clickDown = context.ReadValueAsButton();
    38.  
    39.     #endregion
    40.  
    41.  
    42. }
    43.  
     
  9. RoughSpaghetti3211

    RoughSpaghetti3211

    Joined:
    Aug 11, 2015
    Posts:
    1,708

    I looked at your GetButtonDown/Up() is action.triggered now is called "action.started"
    started

    Edit: Nevermind I was confused, got it working.
     
    Last edited: Jul 1, 2021