InputManager.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. using BepInEx.Configuration;
  6. namespace COM3D2.MeidoPhotoStudio.Plugin
  7. {
  8. internal class InputManager
  9. {
  10. private static InputListener inputListener;
  11. private static readonly Dictionary<MpsKey, KeyCode> ActionKeys = new Dictionary<MpsKey, KeyCode>();
  12. private static readonly Dictionary<MpsKey, ConfigEntry<KeyCode>> ConfigEntries
  13. = new Dictionary<MpsKey, ConfigEntry<KeyCode>>();
  14. public static KeyCode CurrentKeyCode { get; private set; }
  15. public static bool Listening { get; private set; }
  16. public static event EventHandler KeyChange;
  17. public static bool Control => Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
  18. public static bool Alt => Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt);
  19. public static bool Shift => Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
  20. public static readonly AcceptableValueBase controlRange;
  21. public const KeyCode upperKeyCode = KeyCode.F15;
  22. public const string configHeader = "Controls";
  23. static InputManager() => controlRange = new AcceptableValueRange<KeyCode>(default, upperKeyCode);
  24. public static void Register(MpsKey action, KeyCode key, string description)
  25. {
  26. key = Clamp(key, default, upperKeyCode);
  27. if (ConfigEntries.ContainsKey(action)) Rebind(action, key);
  28. else
  29. {
  30. ConfigDescription configDescription = new ConfigDescription(description, controlRange);
  31. ConfigEntries[action] = Configuration.Config.Bind(
  32. configHeader, action.ToString(), key, configDescription
  33. );
  34. key = ConfigEntries[action].Value;
  35. ActionKeys[action] = key;
  36. }
  37. }
  38. public static void Rebind(MpsKey action, KeyCode key)
  39. {
  40. key = Clamp(key, default, upperKeyCode);
  41. if (ConfigEntries.ContainsKey(action)) ConfigEntries[action].Value = key;
  42. ActionKeys[action] = key;
  43. }
  44. public static KeyCode Clamp(KeyCode value, KeyCode min, KeyCode max)
  45. {
  46. return value < min ? min : value > max ? max : value;
  47. }
  48. public static KeyCode GetActionKey(MpsKey action)
  49. {
  50. ActionKeys.TryGetValue(action, out KeyCode keyCode);
  51. return keyCode;
  52. }
  53. public static void StartListening()
  54. {
  55. if (inputListener == null) inputListener = new GameObject().AddComponent<InputListener>();
  56. else if (inputListener.gameObject.activeSelf) StopListening();
  57. inputListener.gameObject.SetActive(true);
  58. inputListener.KeyChange += OnKeyChange;
  59. CurrentKeyCode = KeyCode.None;
  60. Listening = true;
  61. }
  62. public static void StopListening()
  63. {
  64. if (inputListener == null || !inputListener.gameObject.activeSelf) return;
  65. inputListener.gameObject.SetActive(false);
  66. inputListener.KeyChange -= OnKeyChange;
  67. CurrentKeyCode = KeyCode.None;
  68. Listening = false;
  69. Input.ResetInputAxes();
  70. }
  71. public static bool GetKey(MpsKey action)
  72. {
  73. return !Listening && ActionKeys.ContainsKey(action) && Input.GetKey(ActionKeys[action]);
  74. }
  75. public static bool GetKeyDown(MpsKey action)
  76. {
  77. return !Listening && ActionKeys.ContainsKey(action) && Input.GetKeyDown(ActionKeys[action]);
  78. }
  79. public static void Deactivate()
  80. {
  81. StopListening();
  82. GameObject.Destroy(inputListener?.gameObject);
  83. inputListener = null;
  84. }
  85. private static void OnKeyChange(object sender, KeyChangeEventArgs args)
  86. {
  87. CurrentKeyCode = args.Key;
  88. KeyChange?.Invoke(null, EventArgs.Empty);
  89. StopListening();
  90. }
  91. /* Listener taken from https://forum.unity.com/threads/find-out-which-key-was-pressed.385250/ */
  92. private class InputListener : MonoBehaviour
  93. {
  94. private static readonly KeyCode[] keyCodes;
  95. public event EventHandler<KeyChangeEventArgs> KeyChange;
  96. static InputListener()
  97. {
  98. keyCodes = Enum.GetValues(typeof(KeyCode))
  99. .Cast<KeyCode>()
  100. .Where(keyCode => keyCode <= upperKeyCode)
  101. .ToArray();
  102. }
  103. private void Awake() => DontDestroyOnLoad(this);
  104. private void Update()
  105. {
  106. if (Input.anyKeyDown)
  107. {
  108. foreach (KeyCode key in keyCodes)
  109. {
  110. if (Input.GetKeyDown(key))
  111. {
  112. KeyChange?.Invoke(this, new KeyChangeEventArgs(key));
  113. break;
  114. }
  115. }
  116. }
  117. }
  118. }
  119. private class KeyChangeEventArgs : EventArgs
  120. {
  121. public KeyCode Key { get; }
  122. public KeyChangeEventArgs(KeyCode key) => Key = key;
  123. }
  124. }
  125. internal enum MpsKey
  126. {
  127. // MeidoPhotoStudio
  128. Activate, Screenshot, ToggleUI, ToggleMessage,
  129. // MeidoManager
  130. MeidoUndressing,
  131. // Camera
  132. CameraLayer, CameraReset, CameraSave, CameraLoad,
  133. // Dragpoint
  134. DragSelect, DragDelete, DragMove, DragRotate, DragScale, DragFinger,
  135. // Scene management
  136. SaveScene, LoadScene, OpenSceneManager
  137. }
  138. }