unity3d中用incontrol检测输入设备切换

pc上同时插着手柄的情况下,巫师3的玩家一动键盘,操作提示立即变成键盘的,一动手柄,提示立马变成手柄的了。

我们的游戏用的incontrol插件做的多输入设备管理,也有这样的需求。我问过作者,没有直接的接口可以使用,需要用incontrol的两种事件组合着来做。

直接上代码吧,注释和清楚。

/// 
/// 1.incontrol 里面的device不包括键盘鼠标,只包括各种外设手柄。
/// 要检测键盘鼠标和device之间的切换,只能用一个PlayerActionSet注册所有要触发切换的键,
/// 然后监听它的PlayerActionSet.OnLastInputTypeChanged事件。
/// 
/// 2.手柄device之间的切换用InControl.InputManager.OnActiveDeviceChanged了。
/// 
/// 3.在系统上同时插多种手柄的情况下,以上两个事件可能都会触发,
/// 所以需要在自身的update里面来检测变动,发送事件,保证事件的唯一性。
/// 

namespace Pathea.InputSolutionNs
{
    public enum InputDevice
    {
        MouseKeyboard = 0,
        XboxJoystick,
        Ps4Joystick,
        Max
    }

    public class InputDeviceDetector : UpdateDestroySingleton
    {
        private class ControllerDetector:InControl.PlayerActionSet
        {
            public void Init()
            {
                InControl.PlayerAction a = CreatePlayerAction("ControllerDetector");

                for (int i = (int)InControl.InputControlType.LeftStickUp; i <= (int)InControl.InputControlType.Action12; i++)
                {
                    a.AddDefaultBinding((InControl.InputControlType)i);
                }

                for (int i = (int)InControl.Mouse.LeftButton; i <= (int)InControl.Mouse.Button9; i++)
                {
                    a.AddDefaultBinding((InControl.Mouse)i);
                }

                for (int i = (int)InControl.Key.Shift; i <= (int)InControl.Key.CapsLock; i++)
                {
                    a.AddDefaultBinding((InControl.Key)i);
                }

            }
        }

        private InputDevice curDevice = InputDevice.Max;
        private InputDevice nextDevice = InputDevice.MouseKeyboard;

        private ControllerDetector controllerDetector = new ControllerDetector();

        public event System.Action OnDeviceChanged;

        public InputDevice CurDevice
        {
            get
            {
                return curDevice;
            }
        }

        private static bool IsPs4Joystick()
        {
            if (InControl.InputManager.ActiveDevice == null)
            {
                return false;
            }

            if (InControl.InputManager.ActiveDevice.DeviceStyle != InControl.InputDeviceStyle.PlayStation4)
            {
                return false;
            }

            return true;
        }

        private static bool IsXboxJoystick()
        {
            if (InControl.InputManager.ActiveDevice == null)
            {
                return false;
            }

            if (InControl.InputManager.ActiveDevice.DeviceStyle != InControl.InputDeviceStyle.XboxOne
                && InControl.InputManager.ActiveDevice.DeviceStyle != InControl.InputDeviceStyle.Xbox360)
            {
                return false;
            }

            return true;
        }

        protected override void Update()
        {
            if (curDevice != nextDevice)
            {
                curDevice = nextDevice;

                if (OnDeviceChanged != null)
                {
                    OnDeviceChanged(curDevice);
                }
            }
        }

        protected override void OnInit()
        {
            base.OnInit();

            controllerDetector.Init();

            controllerDetector.OnLastInputTypeChanged += ControllerDetector_OnLastInputTypeChanged;

            InControl.InputManager.OnActiveDeviceChanged += InputManager_OnActiveDeviceChanged;
        }

        //键盘,鼠标,手柄类型之间切换会受到这个消息
        private void ControllerDetector_OnLastInputTypeChanged(InControl.BindingSourceType obj)
        {
            if (obj != InControl.BindingSourceType.DeviceBindingSource)
            {
                SetNextInputDevice(InputDevice.MouseKeyboard);
            }
            else
            {
                CheckController();
            }
        }

        //只有手柄之间切换会收到这个消息。
        private void InputManager_OnActiveDeviceChanged(InControl.InputDevice obj)
        {
            CheckController();
        }

        private void CheckController()
        {
            if (IsXboxJoystick())
            {
                SetNextInputDevice(InputDevice.XboxJoystick);
            }
            else if(IsPs4Joystick())
            {
                SetNextInputDevice(InputDevice.Ps4Joystick);
            }
        }

        private void SetNextInputDevice(InputDevice device)
        {
            nextDevice = device;
        }

        protected override void Destroy()
        {
            base.Destroy();

            controllerDetector.OnLastInputTypeChanged -= ControllerDetector_OnLastInputTypeChanged;
            InControl.InputManager.OnActiveDeviceChanged -= InputManager_OnActiveDeviceChanged;
        }
    }
}

你可能感兴趣的:(unity3d中用incontrol检测输入设备切换)