Search Unity

Input not updating if incorrect window is focused

Discussion in 'Input System' started by jweidenbach, Jul 12, 2019.

  1. jweidenbach

    jweidenbach

    Joined:
    Dec 29, 2018
    Posts:
    54
    Hi again,

    I've got kind of a tricky one here; I've gotten my multiplayer input system set up now, and it's getting through all the menus in what I'm calling 'Classic' mode just fine (though I have noticed that it seems to lose focus from time to time in the editor if I click somewhere else to look at something. I do remember that there _was_ a 'Update in background' option (or something similar) on the UIActionInputModule -- I don't believe that's there with the newer PlayerInputs though. That said, that specific issue isn't what I'm running into here.

    I've now gotten into my actual game, where I'm using pure ECS (to the maximum extent that I can). I've actually gotten things to the point where I can move my character around my map -- I'm doing this through a series of Systems, with the first polling (on the main thread, after setting the updateMode to manual and calling InputSystem.Update()) the input system for the player devices that were passed in from the menus, and then a second set of input-device-specific systems to translate that data to my actual game input values. But, I'm finding that now that that's working, the input values only seem to update if I have an entity (doesn't matter which) selected in the Entity debugger. If I focus that window, I can see my input values updating, and my character running around. If I select the Game window (or anything else), my input goes dead.

    This also means that at game startup, my character is running off in a direction (I'm suspecting that it's getting garbage input) and I can't stop it or redirect without selecting the Entity debugger. I _thought_ that this issue might just be an oddity of the editor, but when I make a standalone build, the character just runs off, and there's nothing I can do to stop it.

    My suspicion is that this is due to the window focus, I know that in lower-level engine work (at least on windows) one usually is required to pass the HWND to the API (for XInput or RawInput). I don't suspect (because everything else seems to be working) that this is due to ECS, but rather that I'm just not doing something properly in my manual update. Here's a snippet of the current relevant polling code:

    Code (CSharp):
    1. public sealed class InputPollingSystem : ComponentSystem
    2. {
    3.     protected override void OnUpdate()
    4.     {
    5.         InputSystem.Update();
    6.  
    7.         Entities.WithAll< PlayerInputComponent >()
    8.                 .ForEach( ( ref GamepadStateComponent state ) => ReadGamepad( ref state ) );
    9.  
    10.         // ... I process keyboard/mouse here as well, in the same way ...
    11.     }
    12.  
    13.     private static void ReadGamepad( ref GamepadStateComponent state )
    14.     {
    15.         var _gamepad = InputSystem.GetDeviceById( state.DeviceId ) as Gamepad;
    16.         if ( _gamepad == null ) return;
    17.  
    18.         state.Buttons = 0;
    19.  
    20.         if ( _gamepad.buttonWest.isPressed )
    21.         {
    22.             state.Buttons |= GamepadButtons.ButtonWest;
    23.         }
    24.  
    25.         if ( _gamepad.buttonNorth.isPressed )
    26.         {
    27.             state.Buttons |= GamepadButtons.ButtonNorth;
    28.         }
    29.  
    30.         // ... I read the entire gamepad here, but the individual buttons aren't relevant to my understanding ...
    31.  
    32.         state.LeftStick = _gamepad.leftStick.ReadValue();
    33.     }
    Short version, is there a function or setting I can activate to force updating regardless of window focus?

    Also (less important), is there any way to get access to the lower-level input data such that I could have or set up raw blittable structs that could be jobified, rather than parsing the higher-level OO structures into my own structs? That seems a bit redundant since the systems are polling under the hood, so they have to be translated to the GamepadState class and then I'm immediately putting them back into something similar to XInput's structure. Parsing the gamepads is cheap, but parsing the keyboard is taking roughly 0.2ms right now, which is the single slowest system at this stage. I'm still running at ~200fps, so not super concerned about optimization yet, but I'm still in an incredibly basic state on the game at this stage, so certainly don't want to be slower than necessary. (side note, in my last game (2014) I was using XInput.net directly so I could map controllers to inputs at runtime. My big draw for the new system is that it allows me to do that without having to implement a custom solution for each controller I want to support, so I'm not asking for the raw data, just a more 'this is the data at this time' rather than the interpreted Action-based and non-blittable data).
     
  2. jweidenbach

    jweidenbach

    Joined:
    Dec 29, 2018
    Posts:
    54
    One more piece on this, after some more investigation, I've confirmed that the polled value is updating only when a window that _isn't_ the game window is focused. So even stranger than I suspected, it seems to be updating only when the game window is NOT focused, rather than what I'd expect.

    But, if I make a standalone build, I'm still getting nothing whatsoever regardless of focus (the menus all work fine, so we are getting input, it's just not polling properly). Very very strange.
     
  3. jweidenbach

    jweidenbach

    Joined:
    Dec 29, 2018
    Posts:
    54
    Ok, I think I found a TODO situation. Setting my Update() call instead to the following sorted this:
    Code (CSharp):
    1. InputSystem.Update( InputUpdateType.Manual );
    Reading the source for InputSystem, it looks like there's a REVIEW note in there to change update to do the right thing based on the system update mode. But, in my case, I saw that and understood it as "Update() will do the appropriate thing for the update mode, and there's a second version if you want to update in special cases." That review note might be confusing for other folks as well.
     
  4. Bortos

    Bortos

    Joined:
    Apr 6, 2016
    Posts:
    12
    Resurrecting this thread, @jweidenbach are you still using that approach? Is this the only, or preferred method currently if we want input to work while out of focus?

    This is for VR projects where we wish to allow the VR player to continue to engage in the application while someone is using a browser or some other application. Pretty common in multi-screen setups and demonstrations
     
  5. jweidenbach

    jweidenbach

    Joined:
    Dec 29, 2018
    Posts:
    54
    Hmmm...I'm not sure. My system using this broke when 0.9.6-preview was released. I've been reworking around the new InputAction polling since then, but haven't gotten it fully up yet.