Page 1 of 1

Detect current device in InpuDeviceManager for new input system

Posted: Fri Nov 29, 2024 3:28 pm
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.

Re: Detect current device in InpuDeviceManager for new input system

Posted: Fri Nov 29, 2024 3:40 pm
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.

Re: Detect current device in InpuDeviceManager for new input system

Posted: Fri Nov 29, 2024 5:14 pm
by SnaiperoG
Got it, thanks for quick answer. Just started to use new input system.