Search Unity

Question Reading mouse/keyboard input without window focus

Discussion in 'Input System' started by apkdev, May 13, 2022.

  1. apkdev

    apkdev

    Joined:
    Dec 12, 2015
    Posts:
    284
    Hey, is there any way to read mouse and keyboard input when the player window isn't selected? I've tried to set this up in various ways but it doesn't seem possible. I'm open to reflection black magic and/or modifying the package if this isn't supported out of the box, do you have any pointers where I should look to hack this into my app? Or is there some limitation that makes this impossible entirely?

    As a workaround I started using Windows API stuff
    Code (CSharp):
    1. [DllImport("user32.dll")]
    2. static extern short GetAsyncKeyState(ushort virtualKeyCode);
    but this is way too ugly and waaay too much effort, I'd much rather stick to the nice Input System API.

    I've tried enabling Run In Background in player settings together with Ignore Focus in input system settings. This seems like the option I wanted but it doesn't seem to work. The description doesn't clearly indicate that not all devices will receive input when Ignore Focus is selected.
    upload_2022-5-13_21-59-57.png

    The Play Mode Input Behavior setting lets me receive input when a different editor window is focused, but this isn't what I wanted. I want to receive input when outside the editor/player.

    I got desperate enough that I tried modifying InputDevice.cs:
    Code (CSharp):
    1. public bool canRunInBackground => true;
    And InputControlLayout.cs:
    Code (CSharp):
    1. public bool? canRunInBackground
    2. {
    3.     get => true;
    But it looks like this isn't decisive in allowing devices to be read in background.
     
  2. crazyfox55

    crazyfox55

    Joined:
    Jul 2, 2016
    Posts:
    1
    I tried everything I could to get the new input system to work while in the background. I was not successful so I am using this code: https://localcoder.org/get-key-from-any-process

    I've attached my code but there is some unity project setup that you will also need below:
    Make sure to put that code in its own assembly, you can do this by creating a new folder in your scripts folder, I called mine "monitoring". Then in that folder create an assembly definition I named it "monitoring" for consistency. Note that the code at the URL references "Key" just change that to "KeyCode". KeyCode is a unityengine type ironically enough.

    Below is how I consume the KeyboardHook.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using TMPro;
    4. using TutorialRunner.Monitoring;
    5. using UnityEngine;
    6.  
    7. public class BackgroundKeyboard : MonoBehaviour
    8. {
    9.     public TextMeshProUGUI TestText;
    10.  
    11.     void OnEnable()
    12.     {
    13.         KeyboardHook.CreateHook();
    14.         KeyboardHook.KeyPressed += KeyboardHook_KeyPressed;
    15.     }
    16.  
    17.     void OnDisable()
    18.     {
    19.         KeyboardHook.KeyPressed -= KeyboardHook_KeyPressed;
    20.         KeyboardHook.DisposeHook();
    21.     }
    22.  
    23.     private void KeyboardHook_KeyPressed(object sender, KeyPressedEventArgs e)
    24.     {
    25.         TestText.text = $"KeyPressed: {e.Info}";
    26.     }
    27. }
    I really hope this helps. I'm now working on getting the mouse to work in the background. Let me know if you need any help, also send anything you find my way. Thanks.
     

    Attached Files:

    RumbleStrut and apkdev like this.
  3. sgthale

    sgthale

    Joined:
    Mar 10, 2018
    Posts:
    12
    Your link is redirecting to a sussy website. I would consider removing it for security reasons.
     
    JuanLou likes this.