Unity 框架

InputManager.cs 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. using System;
  6. namespace TFramework
  7. {
  8. [DefaultExecutionOrder(-999)]
  9. public class InputManager : BaseManager
  10. {
  11. /// <summary>
  12. /// 是否启用输入设备
  13. /// </summary>
  14. [SerializeField]
  15. private bool m_isEnableInputDevice = true;
  16. [SerializeField]
  17. private string m_inputDevice;
  18. public int m_checkError=1;
  19. private Dictionary<string, V_Axis> _v_axes = new Dictionary<string, V_Axis>();
  20. private Dictionary<string, V_Key> _v_keys = new Dictionary<string, V_Key>();
  21. private InputDeviceBase _inputDevice;
  22. [SerializeField]
  23. private float _doubleClickInterval = 0.2f;
  24. /// <summary>
  25. /// 双击时间间隔
  26. /// </summary>
  27. public float DoubleClickInterval { get=>_doubleClickInterval; set=>_doubleClickInterval=value; }
  28. private IEnumerator _clickEnumerator;
  29. private float _currentKeyClickTime;
  30. private bool _startTime = false;
  31. /// <summary>
  32. /// 输入设备
  33. /// </summary>
  34. public InputDeviceBase InputDevice => _inputDevice = _inputDevice ?? GlobalTool.CretaInstanceToCurrentDomain<InputDeviceBase>(m_inputDevice);
  35. /// <summary>
  36. /// 鼠标位置
  37. /// </summary>
  38. public Vector3 MousePosition { get; private set; }
  39. /// <summary>
  40. /// 是否启用输入设备
  41. /// </summary>
  42. public bool IsEnableInputDevice
  43. {
  44. get
  45. {
  46. return m_isEnableInputDevice;
  47. }
  48. set
  49. {
  50. m_isEnableInputDevice = value;
  51. if (!m_isEnableInputDevice)
  52. {
  53. //InputDevice.OnShutdown();
  54. ResetAll();
  55. }
  56. else
  57. InputDevice.OnStartUp();
  58. }
  59. }
  60. private void Start()
  61. {
  62. if(IsEnableInputDevice)
  63. InputDevice?.OnStartUp();
  64. }
  65. public void Update()
  66. {
  67. if (IsEnableInputDevice)
  68. InputDevice?.OnRun();
  69. }
  70. /// <summary>
  71. /// 是否按住任意键
  72. /// </summary>
  73. public bool IsAnyKey => IsEnableInputDevice && Input.anyKey;
  74. /// <summary>
  75. /// 是否按下任意键
  76. /// </summary>
  77. public bool IsAnyKeyDown => IsEnableInputDevice && Input.anyKeyDown;
  78. /// <summary>
  79. /// 是否存在虚拟轴
  80. /// </summary>
  81. /// <param name="name"></param>
  82. /// <returns></returns>
  83. public bool IsExistV_Axis(string name) => _v_axes.ContainsKey(name);
  84. /// <summary>
  85. /// 是否存在虚拟键
  86. /// </summary>
  87. /// <param name="name"></param>
  88. /// <returns></returns>
  89. public bool IsExistV_Key(string name) => _v_keys.ContainsKey(name);
  90. /// <summary>
  91. /// 添加虚拟轴
  92. /// </summary>
  93. /// <param name="name"></param>
  94. public void AddV_Axis(string name)
  95. {
  96. if (!IsExistV_Axis(name))
  97. _v_axes.Add(name, new V_Axis(name));
  98. }
  99. /// <summary>
  100. /// 添加虚拟键
  101. /// </summary>
  102. /// <param name="name"></param>
  103. public void AddV_Key(string name)
  104. {
  105. if (!IsExistV_Key(name))
  106. _v_keys.Add(name, new V_Key(name));
  107. }
  108. /// <summary>
  109. /// 移除虚拟轴
  110. /// </summary>
  111. /// <param name="name"></param>
  112. public void RemoveV_Axis(string name)
  113. {
  114. if (!IsExistV_Axis(name))
  115. _v_axes.Remove(name);
  116. else
  117. Log.Error($"不存在虚拟轴【{name}】!");
  118. }
  119. /// <summary>
  120. /// 移除虚拟键
  121. /// </summary>
  122. /// <param name="name"></param>
  123. public void RemoveV_Key(string name)
  124. {
  125. if (IsExistV_Key(name))
  126. _v_keys.Remove(name);
  127. else
  128. Log.Error($"不存在虚拟键【{name}】!");
  129. }
  130. private IEnumerator CklickTime(V_Key key)
  131. {
  132. while (_currentKeyClickTime > 0)
  133. {
  134. _currentKeyClickTime -= Time.deltaTime;
  135. yield return YieldWaitTool.YieldWaitForFixedUpdate();
  136. }
  137. _startTime = false;
  138. key.Click();
  139. }
  140. #region 按键
  141. /// <summary>
  142. /// 设置按键按下
  143. /// </summary>
  144. /// <param name="name"></param>
  145. public void SetV_KeyDown(string name)
  146. {
  147. if (!IsExistV_Key(name))
  148. AddV_Key(name);
  149. _v_keys[name].Pressed(m_checkError);
  150. }
  151. /// <summary>
  152. /// 设置按键抬起
  153. /// </summary>
  154. /// <param name="name"></param>
  155. public void SetV_KeyUp(string name)
  156. {
  157. if (!IsExistV_Key(name))
  158. AddV_Key(name);
  159. _v_keys[name].Released(m_checkError);
  160. if (!_startTime)
  161. {
  162. _startTime = true;
  163. if (_clickEnumerator != null)
  164. {
  165. StopCoroutine(_clickEnumerator);
  166. _clickEnumerator = null;
  167. }
  168. _currentKeyClickTime = DoubleClickInterval;
  169. _clickEnumerator = CklickTime(_v_keys[name]);
  170. StartCoroutine(_clickEnumerator);
  171. }
  172. }
  173. /// <summary>
  174. /// 获取按键按下
  175. /// </summary>
  176. /// <param name="name"></param>
  177. /// <returns></returns>
  178. public bool GetV_KeyDown(string name) => GetV_KeysDown(name);
  179. /// <summary>
  180. /// 获取按键抬起
  181. /// </summary>
  182. /// <param name="name"></param>
  183. /// <returns></returns>
  184. public bool GetV_KeyUp(string name) => GetV_KeysUp(name);
  185. /// <summary>
  186. /// 按键按住
  187. /// </summary>
  188. /// <param name="name"></param>
  189. /// <returns></returns>
  190. public bool GetV_Key(string name) => GetV_Keys(name);
  191. /// <summary>
  192. /// 按键单击
  193. /// </summary>
  194. /// <param name="name"></param>
  195. /// <returns></returns>
  196. public bool GetV_KeyClick(string name)
  197. {
  198. if (!IsExistV_Key(name))
  199. AddV_Key(name);
  200. return _v_keys[name].GetClick;
  201. }
  202. /// <summary>
  203. /// 按键双击
  204. /// </summary>
  205. /// <param name="name"></param>
  206. /// <returns></returns>
  207. public bool GetV_KeyDobuleClick(string name)
  208. {
  209. if (!IsExistV_Key(name))
  210. AddV_Key(name);
  211. return _v_keys[name].GetDoubleClick;
  212. }
  213. /// <summary>
  214. /// 组合键按住
  215. /// </summary>
  216. /// <param name="names"></param>
  217. /// <returns></returns>
  218. public bool GetV_Keys(params string[] names) => GetV_KeyOp(0, names);
  219. /// <summary>
  220. /// 组合键按下
  221. /// </summary>
  222. /// <param name="names"></param>
  223. /// <returns></returns>
  224. public bool GetV_KeysDown(params string[] names) => GetV_KeyOp(-1, names);
  225. /// <summary>
  226. /// 组合键抬起
  227. /// </summary>
  228. /// <param name="names"></param>
  229. /// <returns></returns>
  230. public bool GetV_KeysUp(params string[] names) => GetV_KeyOp(1, names);
  231. /// <summary>
  232. /// 获取按键操作
  233. /// </summary>
  234. /// <param name="names"></param>
  235. /// <param name="op">1 抬起 0 按住 -1 按下</param>
  236. /// <returns></returns>
  237. private bool GetV_KeyOp(int op = 0, params string[] names)
  238. {
  239. for (int i = 0; i < names.Length; i++)
  240. {
  241. if (!IsExistV_Key(names[i]))
  242. AddV_Key(names[i]);
  243. }
  244. //if (op == 1)
  245. // return _v_keys.Where(p => names.Contains(p.Key)).Select(p => p.Value).All(p => p.GetKeyUp);
  246. //else if (op == 0)
  247. // return _v_keys.Where(p => names.Contains(p.Key)).Select(p => p.Value).All(p => p.GetKey);
  248. //else
  249. // return _v_keys.Where(p => names.Contains(p.Key)).Select(p => p.Value).All(p => p.GetKeyDown);
  250. if (op == 1)
  251. {
  252. for (int i = 0; i < names.Length; i++)
  253. {
  254. if (!_v_keys[names[i]].GetKeyUp)
  255. return false;
  256. }
  257. return true;
  258. }
  259. else if (op == 0)
  260. {
  261. for (int i = 0; i < names.Length; i++)
  262. {
  263. if (!_v_keys[names[i]].GetKey)
  264. return false;
  265. }
  266. return true;
  267. }
  268. else
  269. {
  270. for (int i = 0; i < names.Length; i++)
  271. {
  272. if (!_v_keys[names[i]].GetKeyDown)
  273. return false;
  274. }
  275. return true;
  276. }
  277. }
  278. /// <summary>
  279. /// 按键按住 可传组合键
  280. /// </summary>
  281. /// <param name="name"></param>
  282. /// <returns></returns>
  283. public bool GetKeys(params KeyCode[] keyCodes) => keyCodes.All(p => Input.GetKey(p));
  284. /// <summary>
  285. /// 按键抬起 可传组合键
  286. /// </summary>
  287. /// <param name="name"></param>
  288. /// <returns></returns>
  289. public bool GetKeysUp(params KeyCode[] keyCodes) => keyCodes.All(p => Input.GetKeyUp(p));
  290. /// <summary>
  291. /// 按键按下 可传组合键
  292. /// </summary>
  293. /// <param name="name"></param>
  294. /// <returns></returns>
  295. public bool GetKeyDown(params KeyCode[] keyCodes) => keyCodes.All(p => Input.GetKeyDown(p));
  296. #endregion
  297. #region 轴
  298. /// <summary>
  299. /// 设置轴线值
  300. /// </summary>
  301. /// <param name="name">轴线名称</param>
  302. /// <param name="value">轴线值</param>
  303. public void SetV_Axis(string name, float value)
  304. {
  305. if (!IsExistV_Axis(name))
  306. AddV_Axis(name);
  307. _v_axes[name].Update(value);
  308. }
  309. /// <summary>
  310. /// 设置轴线值为0
  311. /// </summary>
  312. /// <param name="name">轴线名称</param>
  313. public void SetV_AxisZero(string name) => SetV_Axis(name, 0);
  314. /// <summary>
  315. /// 设置轴线值为正方向1
  316. /// </summary>
  317. /// <param name="name">轴线名称</param>
  318. public void SetV_AxisPositive(string name) => SetV_Axis(name, 1);
  319. /// <summary>
  320. /// 设置轴线值为负方向-1
  321. /// </summary>
  322. /// <param name="name">轴线名称</param>
  323. public void SetV_AxisNegative(string name) => SetV_Axis(name, -1);
  324. /// <summary>
  325. /// 获取轴线值
  326. /// </summary>
  327. /// <param name="name">轴线名称</param>
  328. /// <param name="raw">是否获取整数值</param>
  329. /// <returns>轴线值</returns>
  330. public float GetAxis(string name, bool raw = false)
  331. {
  332. if (!IsExistV_Axis(name))
  333. AddV_Axis(name);
  334. return raw ? _v_axes[name].GetValueRaw : _v_axes[name].GetValue;
  335. }
  336. #endregion
  337. /// <summary>
  338. /// 设置鼠标位置
  339. /// </summary>
  340. /// <param name="value"></param>
  341. public void SetVirtualMousePosition(Vector3 value) => MousePosition = value;
  342. /// <summary>
  343. /// 清除所有输入状态
  344. /// </summary>
  345. public void ResetAll()
  346. {
  347. foreach (var item in _v_axes.Values)
  348. item.Update(0);
  349. foreach (var item in _v_keys.Values)
  350. item.Released();
  351. }
  352. /// <summary>
  353. /// 虚拟键
  354. /// </summary>
  355. private sealed class V_Key
  356. {
  357. public string Name { get; private set; }
  358. public float ClickCount
  359. {
  360. get=>_clickCount;
  361. private set
  362. {
  363. _clickCount = value;
  364. }
  365. }
  366. private float _clickCount = 0;
  367. public int _pressedFrame = -5;
  368. private int _releasedFrame = -5;
  369. private bool _pressed = false;
  370. private int _clickFrame = -5;
  371. private int _doubleClickFrame = -5;
  372. public V_Key(string name) => Name = name;
  373. public void Pressed(int error=0)
  374. {
  375. if (_pressed)
  376. return;
  377. _pressed = true;
  378. _pressedFrame = Time.frameCount+ error;
  379. ClickCount += 0.5f;
  380. }
  381. public void Released(int error = 0)
  382. {
  383. if (!_pressed)
  384. return;
  385. _pressed = false;
  386. _releasedFrame = Time.frameCount+ error;
  387. ClickCount += 0.5f;
  388. }
  389. public void Click()
  390. {
  391. if (_clickCount >= 2)
  392. _doubleClickFrame = Time.frameCount;
  393. else if (_clickCount > 0 && _clickCount <= 2)
  394. _clickFrame = Time.frameCount;
  395. ClickCount = 0;
  396. }
  397. /// <summary>
  398. /// 按住
  399. /// </summary>
  400. public bool GetKey => _pressed;
  401. /// <summary>
  402. /// 按键按下
  403. /// </summary>
  404. public bool GetKeyDown => _pressedFrame == Time.frameCount;
  405. /// <summary>
  406. /// 按键抬起
  407. /// </summary>
  408. public bool GetKeyUp => _releasedFrame == Time.frameCount;
  409. /// <summary>
  410. /// 按键单击
  411. /// </summary>
  412. public bool GetClick => _clickFrame == Time.frameCount;
  413. /// <summary>
  414. /// 按键双击
  415. /// </summary>
  416. public bool GetDoubleClick => _doubleClickFrame == Time.frameCount;
  417. }
  418. /// <summary>
  419. /// 虚拟轴
  420. /// </summary>
  421. private sealed class V_Axis
  422. {
  423. public string Name { get; private set; }
  424. private float _value;
  425. public V_Axis(string name) => Name = name;
  426. public void Update(float value) => _value = value;
  427. public float GetValue => _value;
  428. public float GetValueRaw => _value > 0 ? 1 : (_value < 0 ? -1 : 0);
  429. }
  430. }
  431. }