using System; using UnityEngine; using System.Collections.Generic; namespace SK.Framework { public sealed class MouseInputController { private class MouseButtonInputInfo { public readonly int mouseButton; public readonly List mouseButtonInputs; public InputState state = InputState.None; public MouseButtonInputInfo(int mouseButton) { this.mouseButton = mouseButton; mouseButtonInputs = new List(); } public void Reset() { state = InputState.None; } } private readonly List mouseButtonInputs; private readonly List infos; private readonly Dictionary triggers; public MouseInputController() { mouseButtonInputs = new List(); infos = new List(); triggers = new Dictionary(); } private Vector2 cacheMousePosition; public Vector2 Delta { get; private set; } public void Update() { Vector2 currentMousePosition = Input.mousePosition; Delta = currentMousePosition - cacheMousePosition; for (int i = 0; i < mouseButtonInputs.Count; i++) { mouseButtonInputs[i].Value = Input.GetMouseButton(mouseButtonInputs[i].Key); } for (int i = 0; i < infos.Count; i++) { var info = infos[i]; bool flag = false; for (int j = info.mouseButtonInputs.Count - 1; j >= 0; j--) { if (info.mouseButtonInputs[j].Value) { flag = true; break; } } if (flag) { info.state = info.state == InputState.None || info.state == InputState.Released ? InputState.Pressed : InputState.Held; triggers.Clear(); } else if (triggers.ContainsKey(info.mouseButton)) { switch (triggers[info.mouseButton].type) { case InputTriggerType.Pressed: info.state = InputState.Pressed; triggers.Remove(info.mouseButton); break; case InputTriggerType.Held: info.state = InputState.Held; if (triggers[info.mouseButton].disposeWhen.Invoke()) triggers.Remove(info.mouseButton); break; case InputTriggerType.Released: info.state = InputState.Released; triggers.Remove(info.mouseButton); break; } } else { info.state = info.state == InputState.Pressed || info.state == InputState.Held ? InputState.Released : InputState.None; } } cacheMousePosition = Input.mousePosition; } public void Reset() { for (int i = 0; i < mouseButtonInputs.Count; i++) { mouseButtonInputs[i].Reset(); } cacheMousePosition = Input.mousePosition; Delta = Vector2.zero; } public bool Register(MouseButtonInput mouseButtonInput) { if (mouseButtonInputs.Contains(mouseButtonInput)) { return false; } mouseButtonInputs.Add(mouseButtonInput); var target = infos.Find(m => m.mouseButton == mouseButtonInput.Key); if (target == null) { target = new MouseButtonInputInfo(mouseButtonInput.Key); infos.Add(target); } target.mouseButtonInputs.Add(mouseButtonInput); return true; } public bool Unregister(MouseButtonInput mouseButtonInput) { if (!mouseButtonInputs.Contains(mouseButtonInput)) { return false; } mouseButtonInputs.Remove(mouseButtonInput); var target = infos.Find(m => m.mouseButton == mouseButtonInput.Key); if (target != null) { target.mouseButtonInputs.Remove(mouseButtonInput); if (target.mouseButtonInputs.Count == 0) { infos.Remove(target); } } return true; } public bool GetKeyDown(MouseButtonInput mouseButtonInput) { var target = infos.Find(m => m.mouseButton == mouseButtonInput.Key); return target != null && target.state == InputState.Pressed; } public bool GetKey(MouseButtonInput mouseButtonInput) { var target = infos.Find(m => m.mouseButton == mouseButtonInput.Key); return target != null && (target.state == InputState.Held || target.state == InputState.Pressed); } public bool GetKeyUp(MouseButtonInput mouseButtonInput) { var target = infos.Find(m => m.mouseButton == mouseButtonInput.Key); return target != null && target.state == InputState.Released; } public void Trigger(int mouseButton, InputTriggerType type) { if (mouseButton == 0 || mouseButton == 1 || mouseButton == 2) { if (!triggers.ContainsKey(mouseButton) && type != InputTriggerType.Held) { triggers.Add(mouseButton, new InputTrigger(type)); Debug.Log($"触发鼠标按键 [{mouseButton}] {(type == InputTriggerType.Pressed ? "按下" : "抬起")}"); } } } public void Trigger(int mouseButton, InputTriggerType type, Func disposeWhen) { if (mouseButton == 0 || mouseButton == 1 || mouseButton == 2) { if (!triggers.ContainsKey(mouseButton) && type == InputTriggerType.Held) { triggers.Add(mouseButton, new InputTrigger(type, disposeWhen)); Debug.Log($"触发鼠标按键 [{mouseButton}] 持续按下"); } } } public void Trigger(MouseButtonCode mouseButtonCode, InputTriggerType type) { Trigger((int)mouseButtonCode, type); } public void Trigger(MouseButtonCode mouseButtonCode, InputTriggerType type, Func disposeWhen) { Trigger((int)mouseButtonCode, type, disposeWhen); } } }