Detect current device in InpuDeviceManager for new input system

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
SnaiperoG
Posts: 2
Joined: Fri Nov 29, 2024 12:49 pm

Detect current device in InpuDeviceManager for new input system

Post by SnaiperoG »

I cant understand why there is logic in Update method to check current device with loop for buttons. Why there is even Update method for this purpose. Here is my suggestion.
1. Add LowLevel namespace on top inside USE_NEW_INPUT

Code: Select all

using UnityEngine.InputSystem.LowLevel;
2. Subscribe inside Start method inside USE_NEW_INPUT

Code: Select all

InputSystem.onEvent += OnEvent;
3. Unsubscribe inside OnDestroy, and fix that you forgot to unsubscribe from OnDeviceChange

Code: Select all

#if USE_NEW_INPUT
            InputSystem.onDeviceChange -= OnInputSystemDeviceChange;
            InputSystem.onEvent -= OnEvent;
#endif
4. Wrap whole Update method with #if !USE_NEW_INPUT to not use when new input system is used
5. Create OnEvent method based on checks in Update

Code: Select all

        float prevCheck = 0f;

        private void OnEvent(InputEventPtr eventPtr, UnityEngine.InputSystem.InputDevice device)
        {
            if (Time.time < prevCheck)
                return;
            prevCheck = Time.time + 0.5f;

            if (!(eventPtr.IsA<StateEvent>() || eventPtr.IsA<DeltaStateEvent>()))
                return;

            PixelCrushers.InputDevice newDevice = PixelCrushers.InputDevice.Joystick;
            if (device is UnityEngine.InputSystem.Joystick || device is UnityEngine.InputSystem.Gamepad)
                newDevice = PixelCrushers.InputDevice.Joystick;
            else if (device is UnityEngine.InputSystem.Keyboard)
                newDevice = keyInputSwitchesModeTo == KeyInputSwitchesModeTo.Keyboard ? PixelCrushers.InputDevice.Keyboard : PixelCrushers.InputDevice.Mouse;
            else if (device is UnityEngine.InputSystem.Mouse)
                newDevice = PixelCrushers.InputDevice.Mouse;
            else if (device is UnityEngine.InputSystem.Touchscreen)
                newDevice = PixelCrushers.InputDevice.Touch;
            else
            {
                Debug.LogWarning("Undetected device!");
                return;
            }

            if (inputDevice == newDevice)
                return;

            if (newDevice == PixelCrushers.InputDevice.Joystick)
            {
                if (!eventPtr.HasButtonPress())
                    if (device is UnityEngine.InputSystem.Joystick)
                    {
                        var joystick = device as UnityEngine.InputSystem.Joystick;
                        var x = joystick.stick.x.ReadValue();
                        var y = joystick.stick.y.ReadValue();
                        if (!(Mathf.Abs(x) > joystickAxisThreshold || Mathf.Abs(y) > joystickAxisThreshold))
                            return;
                    }
                    else
                    {
                        var gamePad = device as UnityEngine.InputSystem.Gamepad;
                        var xL = gamePad.leftStick.x.ReadValue();
                        var yL = gamePad.leftStick.y.ReadValue();
                        //Debug.LogError($"Gamepad Left Stick x: {xL}, y: {yL}");
                        if (!(Mathf.Abs(xL) > joystickAxisThreshold || Mathf.Abs(yL) > joystickAxisThreshold))
                        {
                            var xR = gamePad.rightStick.x.ReadValue();
                            var yR = gamePad.rightStick.y.ReadValue();
                            //Debug.LogError($"Gamepad Right Stick x: {xR}, y: {yR}");
                            if (!(Mathf.Abs(xR) > joystickAxisThreshold || Mathf.Abs(yR) > joystickAxisThreshold))
                                return;
                        }
                    }
            }
            else if (newDevice == PixelCrushers.InputDevice.Keyboard)
            {
                if (!isInputAllowed) return;
            }
            else if (newDevice == PixelCrushers.InputDevice.Mouse)
            {
                if (!detectMouseControl) return;
                var mousePosition = DefaultGetMousePosition();
                var didMouseMove = !m_ignoreMouse && (Mathf.Abs(mousePosition.x - m_lastMousePosition.x) > mouseMoveThreshold || Mathf.Abs(mousePosition.y - m_lastMousePosition.y) > mouseMoveThreshold);
                m_lastMousePosition = mousePosition;
            }

            Debug.Log($"Last active device: {device.displayName}");
            SetInputDevice(newDevice);
        }
Logic inside OnEvent might be optimized and added more checks from DS logic, but i guess you should get the point.
User avatar
Tony Li
Posts: 23259
Joined: Thu Jul 18, 2013 1:27 pm

Re: Detect current device in InpuDeviceManager for new input system

Post by Tony Li »

Hi,

The reason is that there was significant demand for Input System Package support when the Input System was very new (circa 2019/2020) and those API calls weren't available, so the Input Device Manager took advantage of the few Input System features that were available at the time. It took Unity a few years to shape up the Input System after that. At some point soon, we'll incorporate changes similar to what you've listed above. We're prioritizing features that are more highly requested, but I'll try to get this updated sooner rather than later.
SnaiperoG
Posts: 2
Joined: Fri Nov 29, 2024 12:49 pm

Re: Detect current device in InpuDeviceManager for new input system

Post by SnaiperoG »

Got it, thanks for quick answer. Just started to use new input system.
Post Reply