Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Input Polling setup with ECS

Discussion in 'Input System' started by jweidenbach, Aug 25, 2019.

  1. jweidenbach

    jweidenbach

    Joined:
    Dec 29, 2018
    Posts:
    54
    Hey there,

    Since the 0.9 release added action polling, I've been trying to update my input code to work with my ECS code, and there seems to be some weirdness.

    This was prompted because I noticed (after updating to 2019.2) that I was no longer getting input in my game once I left the editor and ran a build (this was with a more complicated system that did a raw device poll and copied the values into components -- it worked fine in the Monobehaviour-based menu scenes).

    I broke out into a separate project to set everything up, so the code _should_ be pretty simple. I've set up a scene with a PlayerInputManager, and have a prefab object with just a PlayerInput object to handle joining.

    From that, I set up a InputManager script to process the joined PlayerInput objects, which can spawn an associated entity and add my input data component to it, and then reference back to the InputActions on the PlayerInput.

    Code (CSharp):
    1.     private void InputManagerOnOnPlayerJoined( PlayerInput input )
    2.     {
    3.         int _id = PlayerCount++;
    4.         m_UiMoveActions.Add( input.actions.FindAction( "UI/Move" ) );
    5.         m_UiSubmitActions.Add( input.actions.FindAction( "UI/Submit" ) );
    6.         m_UserIdLookup.Add( input, _id );
    7.  
    8.         EntityManager _manager = World.Active.EntityManager;
    9.         Entity _entity = _manager.CreateEntity();
    10.         _manager.AddComponentData( _entity, new PlayerInputIdComponent
    11.         {
    12.             Id = _id,
    13.         } );
    14.  
    15.         _manager.AddComponentData( _entity, new PlayerInputComponent() );
    16.  
    17.         m_EntityLookup.Add( _entity, _id );
    18.  
    19.     }
    Then I have a ComponentSystem, and in OnUpdate I simply look for my entities with the input component and call a polling function on my input manager object (so this should all be main thread):

    The ComponentSystem:
    Code (CSharp):
    1. public class InputSystem : ComponentSystem
    2. {
    3.  
    4.     protected override void OnUpdate()
    5.     {
    6.         if ( InputManager.Instance == null ) return;
    7.  
    8.         Entities.ForEach( ( Entity entity, ref PlayerInputComponent input ) =>
    9.         {
    10.             InputManager.Instance.PollUiInput( entity, ref input );
    11.         } );
    12.     }
    13. }
    The polling function on my input manager:
    Code (CSharp):
    1.     public void PollUiInput( Entity entity, ref PlayerInputComponent input )
    2.     {
    3.         int _id = m_EntityLookup[entity];
    4.         float2 _moveDir = m_UiMoveActions[_id].ReadValue < Vector2 >();
    5.         bool _submit = m_UiSubmitActions[_id].triggered;
    6.  
    7.         input.MoveDir = _moveDir;
    8.         input.Submit = _submit;
    9.         Debug.LogFormat( "{0}: {1}, {2}", _id, input.MoveDir, input.Submit );
    10.     }
    This specific code works, but there's some weirdness; if I directly assign the ReadValue result or triggered result, the LogFormat prints out zero and false values regardless of what I'm doing with the input.

    If I leave those intermediate variables in, and just remove the LogFormat call, the component then gets zero values again. It _seems_ similar to issues I've seen in C++ when optimization is turned on and pieces have been optimized out (important side note, I'm not using Burst anywhere here yet). In this case, I'm not actually using my input values yet, so that explanation _would_ make sense, although I'd still expect that in the editor I'd be in a debug state with no optimization. I've also (at least in 2019.1) not seen any similar issues to this with direct ECS usage. Components usually just update in the Entity debugger.

    Any ideas? I'm happy to post the testing project if it helps.
     
  2. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    This seems weird. Please supply a repro project, then we can debug what is going on.
     
  3. jweidenbach

    jweidenbach

    Joined:
    Dec 29, 2018
    Posts:
    54
    Here's the repro. As I was narrowing it down, I saw a few times where things worked, so it seems to be somewhat unpredictable. I've tried to establish a predictable case of 'do this and it reproduces the behavior', but it seems like sometimes it's a case of stale compilation data (again, strange). In those cases, I've just swapped sets of commenting, and then the issue shows up again -- I commented the code to show where I modify (in LSS/DCHL/Classic/Runtime/InputManager.cs).

    Hopefully it shows up on your end too so we can figure it out; I'm using the following setup:

    Windows 10
    Unity 2019.2.1f1
    PS4 Dualshock Controller (through USB) (Exhibits the same with Xbox One controller wireless)
     

    Attached Files:

  4. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    I gave it a try, but could not repro the problem (It worked with either code). Do you have the game window focused when testing this?
     
  5. jweidenbach

    jweidenbach

    Joined:
    Dec 29, 2018
    Posts:
    54
    That's the one thing I didn't double check on this bit. I was pretty focused on the entity debugger, selecting the input entity (Entity 0). I'll give it a quick try with the inspector locked.
     
  6. jweidenbach

    jweidenbach

    Joined:
    Dec 29, 2018
    Posts:
    54
    Yeah, the focus is the issue. I know the option to receive input without focus _was_ there a few versions back and then was removed, was it too unreliable to keep in? (I think I saw that it had been pulled due to not working in many cases). For the meanwhile though I'll see if I can get this ported over into my gamecode base and hopefully it will resolve the build issues I was seeing.
     
  7. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    Input without focus can be problematic as some virus scanners may not like it (this is what keyloggers do, log input in the background). That being said, I don't see such problem for anything but keyboard really.
     
  8. jweidenbach

    jweidenbach

    Joined:
    Dec 29, 2018
    Posts:
    54
    Yeah, I get that. The primary thing I'd be thinking about is more having the 'focus' of the controls tied to the editor rather than to just the game window, but I get that that's likely a bigger design challenge.
     
  9. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    There's an option for that in the input debugger ("Options >> Lock Input to Game View"). With that active, editor updates will no longer receive input and it'll all be routed to player updates instead regardless of whether the game view has focus or not. The setting is local to your workspace but should persist across sessions.

    ////EDIT: Just to add that, I think focus handling in the system isn't very mature yet and still needs some good tweaking. Both in the editor and in the player.
     
    pal_trefall likes this.