forked from sin365/AxibugEmuOnline
引入InputSystem,输入设备管理系统迭代中
This commit is contained in:
parent
3c10873180
commit
955a35659a
@ -10,7 +10,7 @@ GameObject:
|
||||
m_Component:
|
||||
- component: {fileID: 3186794564434009199}
|
||||
- component: {fileID: 1464475178787633862}
|
||||
- component: {fileID: 2053226018124086955}
|
||||
- component: {fileID: 3126747713153700628}
|
||||
m_Layer: 0
|
||||
m_Name: EventSystem
|
||||
m_TagString: Untagged
|
||||
@ -48,7 +48,7 @@ MonoBehaviour:
|
||||
m_FirstSelected: {fileID: 0}
|
||||
m_sendNavigationEvents: 0
|
||||
m_DragThreshold: 10
|
||||
--- !u!114 &2053226018124086955
|
||||
--- !u!114 &3126747713153700628
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
@ -57,17 +57,28 @@ MonoBehaviour:
|
||||
m_GameObject: {fileID: 173080370084988713}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
|
||||
m_Script: {fileID: 11500000, guid: 01614664b831546d2ae94a42149d80ac, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_SendPointerHoverToParent: 1
|
||||
m_HorizontalAxis: Horizontal
|
||||
m_VerticalAxis: Vertical
|
||||
m_SubmitButton: Submit
|
||||
m_CancelButton: Cancel
|
||||
m_InputActionsPerSecond: 10
|
||||
m_RepeatDelay: 0.5
|
||||
m_ForceModuleActive: 0
|
||||
m_MoveRepeatDelay: 0.5
|
||||
m_MoveRepeatRate: 0.1
|
||||
m_XRTrackingOrigin: {fileID: 0}
|
||||
m_ActionsAsset: {fileID: -944628639613478452, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
||||
m_PointAction: {fileID: -1654692200621890270, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
||||
m_MoveAction: {fileID: -8784545083839296357, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
||||
m_SubmitAction: {fileID: 392368643174621059, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
||||
m_CancelAction: {fileID: 7727032971491509709, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
||||
m_LeftClickAction: {fileID: 3001919216989983466, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
||||
m_MiddleClickAction: {fileID: -2185481485913320682, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
||||
m_RightClickAction: {fileID: -4090225696740746782, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
||||
m_ScrollWheelAction: {fileID: 6240969308177333660, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
||||
m_TrackedDevicePositionAction: {fileID: 6564999863303420839, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
||||
m_TrackedDeviceOrientationAction: {fileID: 7970375526676320489, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
||||
m_DeselectOnBackgroundClick: 1
|
||||
m_PointerBehavior: 0
|
||||
m_CursorLockBehavior: 0
|
||||
m_ScrollDeltaPerTick: 6
|
||||
--- !u!1 &261166211120060501
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
|
@ -6,7 +6,8 @@
|
||||
"VirtualNes.Core",
|
||||
"UIEffect2018",
|
||||
"Mame.Core",
|
||||
"Essgee.Unity"
|
||||
"Essgee.Unity",
|
||||
"Unity.InputSystem"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
@ -1,15 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace AxibugEmuOnline.Client.InputDevices
|
||||
{
|
||||
public class InputDevicesManager
|
||||
{
|
||||
InputResolver m_inputResolver = InputResolver.Create();
|
||||
Dictionary<string, InputDevice> m_devices = new Dictionary<string, InputDevice>();
|
||||
|
||||
public InputDevicesManager()
|
||||
{
|
||||
AddDevice(new KeyBoard());
|
||||
m_inputResolver.OnDeviceConnected += OnDeviceConnected;
|
||||
m_inputResolver.OnDeviceLost += OnDeviceLost;
|
||||
foreach (var device in m_inputResolver.GetDevices())
|
||||
AddDevice(device);
|
||||
}
|
||||
|
||||
private void OnDeviceLost(InputDevice lostDevice)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void OnDeviceConnected(InputDevice connectDevice)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void AddDevice(InputDevice device)
|
||||
@ -77,9 +92,10 @@ namespace AxibugEmuOnline.Client.InputDevices
|
||||
public bool AnyKeyDown { get; private set; }
|
||||
|
||||
protected Dictionary<string, KeyBase> m_keyMapper = new Dictionary<string, KeyBase>();
|
||||
|
||||
public InputDevice()
|
||||
protected InputResolver m_resolver;
|
||||
public InputDevice(InputResolver resolver)
|
||||
{
|
||||
m_resolver = resolver;
|
||||
foreach (var key in DefineKeys())
|
||||
{
|
||||
m_keyMapper[key.KeyName] = key;
|
||||
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fec275f55ad33a4fbe0ce724bc7274f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AxibugEmuOnline.Client.InputDevices
|
||||
{
|
||||
/// <summary>
|
||||
/// 双向字典
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
public class DualWayDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary
|
||||
where TKey : notnull
|
||||
where TValue : notnull
|
||||
{
|
||||
private readonly Dictionary<TKey, TValue> _forward = new();
|
||||
private readonly Dictionary<TValue, TKey> _reverse = new();
|
||||
|
||||
// 显式实现非泛型接口
|
||||
bool IDictionary.IsFixedSize => false;
|
||||
bool IDictionary.IsReadOnly => false;
|
||||
bool ICollection.IsSynchronized => false;
|
||||
object ICollection.SyncRoot => ((ICollection)_forward).SyncRoot;
|
||||
|
||||
// 泛型接口实现
|
||||
public TValue this[TKey key]
|
||||
{
|
||||
get => _forward[key];
|
||||
set
|
||||
{
|
||||
if (_forward.TryGetValue(key, out var oldValue))
|
||||
_reverse.Remove(oldValue);
|
||||
_forward[key] = value;
|
||||
_reverse[value] = key;
|
||||
}
|
||||
}
|
||||
|
||||
object? IDictionary.this[object key]
|
||||
{
|
||||
get => key is TKey k ? _forward[k] : null;
|
||||
set
|
||||
{
|
||||
if (key is TKey tk && value is TValue tv)
|
||||
this[tk] = tv;
|
||||
}
|
||||
}
|
||||
|
||||
public ICollection<TKey> Keys => _forward.Keys;
|
||||
public ICollection<TValue> Values => _forward.Values;
|
||||
|
||||
ICollection IDictionary.Keys => _forward.Keys;
|
||||
ICollection IDictionary.Values => _forward.Values;
|
||||
|
||||
public int Count => _forward.Count;
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
// 双向查询扩展
|
||||
public bool TryGetKey(TValue value, out TKey key) => _reverse.TryGetValue(value, out key);
|
||||
public bool TryGetValue(TKey key, out TValue value) => _forward.TryGetValue(key, out value);
|
||||
|
||||
// 接口方法实现
|
||||
public void Add(TKey key, TValue value)
|
||||
{
|
||||
if (_forward.ContainsKey(key) || _reverse.ContainsKey(value))
|
||||
throw new ArgumentException("键或值已存在");
|
||||
_forward.Add(key, value);
|
||||
_reverse.Add(value, key);
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<TKey, TValue> item) => Add(item.Key, item.Value);
|
||||
|
||||
void IDictionary.Add(object key, object value)
|
||||
{
|
||||
if (key is TKey k && value is TValue v)
|
||||
Add(k, v);
|
||||
else
|
||||
throw new ArgumentException("类型不匹配");
|
||||
}
|
||||
|
||||
public bool Contains(object key) => key is TKey k && _forward.ContainsKey(k);
|
||||
public bool Contains(KeyValuePair<TKey, TValue> item) => _forward.TryGetValue(item.Key, out var v) && v.Equals(item.Value);
|
||||
public bool ContainsKey(TKey key) => _forward.ContainsKey(key);
|
||||
|
||||
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
|
||||
{
|
||||
((ICollection<KeyValuePair<TKey, TValue>>)_forward).CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
((ICollection)_forward).CopyTo(array, index);
|
||||
}
|
||||
|
||||
public bool Remove(TKey key)
|
||||
{
|
||||
if (!_forward.Remove(key, out var value)) return false;
|
||||
_reverse.Remove(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Remove(KeyValuePair<TKey, TValue> item) => Remove(item.Key);
|
||||
|
||||
void IDictionary.Remove(object key)
|
||||
{
|
||||
if (key is TKey k) Remove(k);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_forward.Clear();
|
||||
_reverse.Clear();
|
||||
}
|
||||
|
||||
// 枚举器实现
|
||||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => _forward.GetEnumerator();
|
||||
IDictionaryEnumerator IDictionary.GetEnumerator() => new DictionaryEnumerator(_forward.GetEnumerator());
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
|
||||
// 非泛型枚举器适配器
|
||||
private class DictionaryEnumerator : IDictionaryEnumerator
|
||||
{
|
||||
private readonly IEnumerator<KeyValuePair<TKey, TValue>> _enumerator;
|
||||
public DictionaryEnumerator(IEnumerator<KeyValuePair<TKey, TValue>> enumerator) => _enumerator = enumerator;
|
||||
|
||||
public DictionaryEntry Entry => new(_enumerator.Current.Key, _enumerator.Current.Value);
|
||||
public object Key => _enumerator.Current.Key;
|
||||
public object? Value => _enumerator.Current.Value;
|
||||
public object Current => Entry;
|
||||
public bool MoveNext() => _enumerator.MoveNext();
|
||||
public void Reset() => _enumerator.Reset();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c1c60fee919bdf34983705af53c629f6
|
@ -0,0 +1,57 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AxibugEmuOnline.Client.InputDevices
|
||||
{
|
||||
public abstract class InputResolver
|
||||
{
|
||||
public static InputResolver Create()
|
||||
{
|
||||
#if ENABLE_INPUT_SYSTEM //InputSystem
|
||||
return new InputSystemResolver();
|
||||
#elif UNITY_PSP2 //SDK
|
||||
throw new System.NotImplementedException();
|
||||
#elif UNITY_PS3 //SDK
|
||||
throw new System.NotImplementedException();
|
||||
#else //使用旧Input
|
||||
throw new System.NotImplementedException();
|
||||
#endif
|
||||
}
|
||||
/// <summary> 禁止外部构造 </summary>
|
||||
protected InputResolver()
|
||||
{
|
||||
OnInit();
|
||||
}
|
||||
|
||||
protected abstract void OnInit();
|
||||
|
||||
/// <summary>
|
||||
/// 获得所有当前已连入的输入设备
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract IEnumerable<InputDevice> GetDevices();
|
||||
|
||||
/// <summary>
|
||||
/// 检查指定输入设备是否还保持着连接
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool CheckOnline(InputDevice device);
|
||||
|
||||
/// <param name="lostDevice">丢失的设备</param>
|
||||
public delegate void OnDeviceLostHandle(InputDevice lostDevice);
|
||||
/// <summary> 当设备丢失时触发 </summary>
|
||||
public event OnDeviceLostHandle OnDeviceLost;
|
||||
protected void RaiseDeviceLost(InputDevice lostDevice)
|
||||
{
|
||||
OnDeviceLost?.Invoke(lostDevice);
|
||||
}
|
||||
|
||||
/// <param name="connectDevice">建立连接的设备</param>
|
||||
public delegate void OnDeviceConnectedHandle(InputDevice connectDevice);
|
||||
/// <summary> 当设备连接时触发 </summary>
|
||||
public event OnDeviceConnectedHandle OnDeviceConnected;
|
||||
protected void RaiseDeviceConnected(InputDevice connectDevice)
|
||||
{
|
||||
OnDeviceConnected?.Invoke(connectDevice);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 120c0ed2a5e098a4d84325be244aa9f3
|
@ -0,0 +1,65 @@
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
using System.Collections.Generic;
|
||||
using IP = UnityEngine.InputSystem.InputSystem;
|
||||
using IPDevice = UnityEngine.InputSystem.InputDevice;
|
||||
using IPKeyboard = UnityEngine.InputSystem.Keyboard;
|
||||
|
||||
namespace AxibugEmuOnline.Client.InputDevices
|
||||
{
|
||||
/// <summary> InputSystem对接 </summary>
|
||||
public class InputSystemResolver : InputResolver
|
||||
{
|
||||
DualWayDictionary<IPDevice, InputDevice> m_devices = new DualWayDictionary<IPDevice, InputDevice>();
|
||||
|
||||
protected override void OnInit()
|
||||
{
|
||||
foreach (var device in IP.devices)
|
||||
{
|
||||
AddDevice(device);
|
||||
}
|
||||
|
||||
IP.onDeviceChange += IP_onDeviceChange;
|
||||
}
|
||||
|
||||
private void AddDevice(IPDevice ipdev)
|
||||
{
|
||||
InputDevice newDevice = null;
|
||||
if (ipdev is IPKeyboard) newDevice = new KeyBoard(this);
|
||||
|
||||
if (newDevice != null)
|
||||
{
|
||||
m_devices.Add(ipdev, newDevice);
|
||||
RaiseDeviceConnected(newDevice);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveDevice(IPDevice ipdev)
|
||||
{
|
||||
if (m_devices.TryGetValue(ipdev, out var device))
|
||||
{
|
||||
m_devices.Remove(ipdev);
|
||||
RaiseDeviceLost(device);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CheckOnline(InputDevice device)
|
||||
{
|
||||
return m_devices.TryGetKey(device, out var _);
|
||||
}
|
||||
|
||||
private void IP_onDeviceChange(IPDevice device, UnityEngine.InputSystem.InputDeviceChange changeType)
|
||||
{
|
||||
switch (changeType)
|
||||
{
|
||||
case UnityEngine.InputSystem.InputDeviceChange.Added: AddDevice(device); break;
|
||||
case UnityEngine.InputSystem.InputDeviceChange.Removed: RemoveDevice(device); break;
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<InputDevice> GetDevices()
|
||||
{
|
||||
return m_devices.Values;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e56617975c158684eb627cfb4a1c3ebd
|
@ -1,13 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client.InputDevices
|
||||
{
|
||||
public class KeyBoard : InputDevice
|
||||
public partial class KeyBoard : InputDevice
|
||||
{
|
||||
public override string UniqueName => nameof(KeyBoard);
|
||||
public override bool Online => true;
|
||||
|
||||
public KeyBoard(InputResolver resolver) : base(resolver) { }
|
||||
|
||||
protected override IEnumerable<KeyBase> DefineKeys()
|
||||
{
|
||||
var keys = s_keyboardKeys.Select(kc => new KeyboardKey(kc) as KeyBase);
|
||||
return keys;
|
||||
}
|
||||
|
||||
public class KeyboardKey : KeyBase
|
||||
{
|
||||
internal KeyCode m_listenKey;
|
||||
|
||||
public KeyboardKey(KeyCode listenKey)
|
||||
{
|
||||
m_listenKey = listenKey;
|
||||
}
|
||||
|
||||
public override bool GetButtonDown()
|
||||
{
|
||||
return Input.GetKeyDown(m_listenKey);
|
||||
}
|
||||
|
||||
public override bool GetButtonUp()
|
||||
{
|
||||
return Input.GetKeyUp(m_listenKey);
|
||||
}
|
||||
|
||||
public override bool IsPressing()
|
||||
{
|
||||
return Input.GetKey(m_listenKey);
|
||||
}
|
||||
|
||||
public override string KeyName => m_listenKey.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
#region HardCodeForKeyboard
|
||||
public partial class KeyBoard : InputDevice
|
||||
{
|
||||
#region HardCodeForKeyboard
|
||||
static readonly List<KeyCode> s_keyboardKeys = new List<KeyCode>
|
||||
{
|
||||
// 字母键 A-Z
|
||||
@ -50,6 +90,7 @@ namespace AxibugEmuOnline.Client.InputDevices
|
||||
KeyCode.End, KeyCode.PageUp, KeyCode.PageDown, KeyCode.Pause, KeyCode.ScrollLock,
|
||||
KeyCode.Clear
|
||||
};
|
||||
|
||||
// 字母键 A-Z
|
||||
public KeyboardKey A { get; private set; } = new KeyboardKey(KeyCode.A);
|
||||
public KeyboardKey B { get; private set; } = new KeyboardKey(KeyCode.B);
|
||||
@ -174,42 +215,6 @@ namespace AxibugEmuOnline.Client.InputDevices
|
||||
public KeyboardKey Pause { get; private set; } = new KeyboardKey(KeyCode.Pause);
|
||||
public KeyboardKey ScrollLock { get; private set; } = new KeyboardKey(KeyCode.ScrollLock);
|
||||
public KeyboardKey Clear { get; private set; } = new KeyboardKey(KeyCode.Clear);
|
||||
#endregion
|
||||
|
||||
public override string UniqueName => nameof(KeyBoard);
|
||||
public override bool Online => true;
|
||||
|
||||
protected override IEnumerable<KeyBase> DefineKeys()
|
||||
{
|
||||
var keys = s_keyboardKeys.Select(kc => new KeyboardKey(kc) as KeyBase);
|
||||
return keys;
|
||||
}
|
||||
|
||||
public class KeyboardKey : KeyBase
|
||||
{
|
||||
internal KeyCode m_listenKey;
|
||||
|
||||
public KeyboardKey(KeyCode listenKey)
|
||||
{
|
||||
m_listenKey = listenKey;
|
||||
}
|
||||
|
||||
public override bool GetButtonDown()
|
||||
{
|
||||
return Input.GetKeyDown(m_listenKey);
|
||||
}
|
||||
|
||||
public override bool GetButtonUp()
|
||||
{
|
||||
return Input.GetKeyUp(m_listenKey);
|
||||
}
|
||||
|
||||
public override bool IsPressing()
|
||||
{
|
||||
return Input.GetKey(m_listenKey);
|
||||
}
|
||||
|
||||
public override string KeyName => m_listenKey.ToString();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
@ -14,8 +14,6 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
public static bool IsInputing { get; private set; }
|
||||
|
||||
|
||||
|
||||
protected override void OnShow(object param)
|
||||
{
|
||||
ValueTuple<Action<string>, string, string> t = (ValueTuple<Action<string>, string, string>)param;
|
||||
@ -30,7 +28,7 @@ namespace AxibugEmuOnline.Client
|
||||
base.Update();
|
||||
|
||||
IsInputing = m_input.isFocused;
|
||||
|
||||
|
||||
if (IsInputing && Input.GetButtonDown("Submit"))
|
||||
{
|
||||
OnCmdEnter();
|
||||
|
@ -2,6 +2,7 @@
|
||||
"dependencies": {
|
||||
"com.unity.2d.sprite": "1.0.0",
|
||||
"com.unity.ide.visualstudio": "2.0.22",
|
||||
"com.unity.inputsystem": "1.11.2",
|
||||
"com.unity.test-framework": "1.4.5",
|
||||
"com.unity.ugui": "2.0.0",
|
||||
"com.unity.modules.accessibility": "1.0.0",
|
||||
|
@ -22,6 +22,15 @@
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.inputsystem": {
|
||||
"version": "1.11.2",
|
||||
"depth": 0,
|
||||
"source": "registry",
|
||||
"dependencies": {
|
||||
"com.unity.modules.uielements": "1.0.0"
|
||||
},
|
||||
"url": "https://packages.unity.com"
|
||||
},
|
||||
"com.unity.test-framework": {
|
||||
"version": "1.4.5",
|
||||
"depth": 0,
|
||||
|
@ -8,4 +8,6 @@ EditorBuildSettings:
|
||||
- enabled: 1
|
||||
path: Assets/Scene/AxibugEmuOnline.Client.unity
|
||||
guid: eb0c18a619175384d95147898a43054b
|
||||
m_configObjects: {}
|
||||
m_configObjects:
|
||||
com.unity.input.settings.actions: {fileID: -944628639613478452, guid: ca9f5fa95ffab41fb9a615ab714db018, type: 3}
|
||||
m_UseUCBPForAssetBundles: 0
|
||||
|
Loading…
Reference in New Issue
Block a user