InputManager.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using UnityEngine;
  5. using BepInEx.Configuration;
  6. namespace MeidoPhotoStudio.Plugin
  7. {
  8. public static 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. => value < min ? min : value > max ? max : value;
  46. public static KeyCode GetActionKey(MpsKey action)
  47. => ActionKeys.TryGetValue(action, out KeyCode keyCode) ? keyCode : default;
  48. public static void StartListening()
  49. {
  50. if (inputListener == null) inputListener = new GameObject().AddComponent<InputListener>();
  51. else if (inputListener.gameObject.activeSelf) StopListening();
  52. inputListener.gameObject.SetActive(true);
  53. inputListener.KeyChange += OnKeyChange;
  54. CurrentKeyCode = KeyCode.None;
  55. Listening = true;
  56. }
  57. public static void StopListening()
  58. {
  59. if (!inputListener || !inputListener.gameObject.activeSelf) return;
  60. inputListener.gameObject.SetActive(false);
  61. inputListener.KeyChange -= OnKeyChange;
  62. CurrentKeyCode = KeyCode.None;
  63. Listening = false;
  64. Input.ResetInputAxes();
  65. }
  66. public static bool GetKey(MpsKey action)
  67. => !Listening && ActionKeys.ContainsKey(action) && Input.GetKey(ActionKeys[action]);
  68. public static bool GetKeyDown(MpsKey action)
  69. => !Listening && ActionKeys.ContainsKey(action) && Input.GetKeyDown(ActionKeys[action]);
  70. public static void Deactivate()
  71. {
  72. StopListening();
  73. GameObject.Destroy(inputListener?.gameObject);
  74. inputListener = null;
  75. }
  76. private static void OnKeyChange(object sender, KeyChangeEventArgs args)
  77. {
  78. CurrentKeyCode = args.Key;
  79. KeyChange?.Invoke(null, EventArgs.Empty);
  80. StopListening();
  81. }
  82. /* Listener taken from https://forum.unity.com/threads/find-out-which-key-was-pressed.385250/ */
  83. private class InputListener : MonoBehaviour
  84. {
  85. private static readonly KeyCode[] keyCodes;
  86. public event EventHandler<KeyChangeEventArgs> KeyChange;
  87. static InputListener()
  88. {
  89. keyCodes = Enum.GetValues(typeof(KeyCode))
  90. .Cast<KeyCode>()
  91. .Where(keyCode => keyCode <= upperKeyCode)
  92. .ToArray();
  93. }
  94. private void Awake() => DontDestroyOnLoad(this);
  95. private void Update()
  96. {
  97. if (Input.anyKeyDown)
  98. {
  99. foreach (KeyCode key in keyCodes)
  100. {
  101. if (Input.GetKeyDown(key))
  102. {
  103. KeyChange?.Invoke(this, new KeyChangeEventArgs(key));
  104. break;
  105. }
  106. }
  107. }
  108. }
  109. }
  110. private class KeyChangeEventArgs : EventArgs
  111. {
  112. public KeyCode Key { get; }
  113. public KeyChangeEventArgs(KeyCode key) => Key = key;
  114. }
  115. }
  116. public enum MpsKey
  117. {
  118. // MeidoPhotoStudio
  119. Activate, Screenshot, ToggleUI, ToggleMessage,
  120. // MeidoManager
  121. MeidoUndressing,
  122. // Camera
  123. CameraLayer, CameraReset, CameraSave, CameraLoad,
  124. // Dragpoint
  125. DragSelect, DragDelete, DragMove, DragRotate, DragScale, DragFinger,
  126. // Scene management
  127. SaveScene, LoadScene, OpenSceneManager
  128. }
  129. }