using UnityEngine; using TMPro; using System; using UnityEngine.UI; public class InputManager : MonoBehaviour { public static InputManager Instance { get; private set; } public static event Action OnKeyPressed; public static event Action OnKeyReleased; private static readonly string[] TrackColors = { "red", "green", "yellow", "purple", "blue" }; [Header("����ж���ʾTMP��������Inspector�����ӣ�")] public TextMeshProUGUI[] trackJudgeTexts = new TextMeshProUGUI[5]; [Header("����ָʾ�ı����������ж��ı�������ֱ��Ӧ������D,F,Space,J,K��")] public Text[] trackKeyTexts = new Text[5]; [Header("�Ƿ���ʾ�ж�����")] public bool showJudgeText = true; // ��������/�Ǽ�����ɫ [Header("����������ɫ����")] [Tooltip("����������ʱ����ɫ")] public Color keyActiveColor = Color.yellow; [Tooltip("����δ����ʱ����ɫ��Ĭ�Ϻ�ɫ��")] public Color keyInactiveColor = Color.black; // �ж������Ӧ��ɫ [Header("�ж������Ӧ��ɫ")] public Color perfectColor = Color.yellow; public Color greatColor = Color.green; public Color goodColor = Color.cyan; public Color missColor = Color.red; private KeyCode[] cachedKeys = new KeyCode[5]; private void Awake() { if (Instance == null) Instance = this; else Destroy(gameObject); // 初始化按键缓存 RefreshKeyCache(); // ��ʼ�������ı�Ϊ�Ǽ�����ɫ if (trackKeyTexts != null) { foreach (var t in trackKeyTexts) { if (t != null) t.color = keyInactiveColor; } } } private void RefreshKeyCache() { for (int i = 0; i < TrackColors.Length; i++) { cachedKeys[i] = KeyBindingManager.GetKeyForColor(TrackColors[i]); } } private void Start() { // Ensure UI shows current bindings from KeyBindingManager/PlayerPrefs RefreshKeyLabels(); } private void Update() { for (int i = 0; i < TrackColors.Length; i++) { KeyCode key = cachedKeys[i]; if (key == KeyCode.None) continue; int index = i; // TrackColors array index matches track index logic here if (Input.GetKeyDown(key)) { OnKeyPressed?.Invoke(key); // ���� JudgeManager ͳһ�ж���������� JudgeManager.Instance.JudgeEarliestNote(key); // ����ʱ���ö�Ӧ�İ����ı���ɫΪ����ɫ����������ã� if (trackKeyTexts != null && index >= 0 && index < trackKeyTexts.Length) { var txt = trackKeyTexts[index]; if (txt != null) txt.color = keyActiveColor; } } if (Input.GetKeyUp(key)) { OnKeyReleased?.Invoke(key); // �ɿ�ʱ�ָ�Ϊ�Ǽ�����ɫ if (trackKeyTexts != null && index >= 0 && index < trackKeyTexts.Length) { var txt = trackKeyTexts[index]; if (txt != null) txt.color = keyInactiveColor; } } } } /// /// Force a release event for all bound keys and reset UI indicators. /// Useful for external "clear input" operations where the system should treat /// all keys as released regardless of physical state. /// public void ForceReleaseAllKeys() { for (int i = 0; i < TrackColors.Length; i++) { string color = TrackColors[i]; KeyCode key = KeyBindingManager.GetKeyForColor(color); if (key == KeyCode.None) continue; try { OnKeyReleased?.Invoke(key); } catch { } int index = GetIndexForColor(color); if (trackKeyTexts != null && index >= 0 && index < trackKeyTexts.Length) { var txt = trackKeyTexts[index]; if (txt != null) txt.color = keyInactiveColor; } } } // Refresh displayed labels for key bindings (called after rebind) public void RefreshKeyLabels() { if (trackKeyTexts == null) return; for (int i = 0; i < TrackColors.Length && i < trackKeyTexts.Length; i++) { var txt = trackKeyTexts[i]; if (txt == null) continue; KeyCode k = KeyBindingManager.GetKeyForColor(TrackColors[i]); txt.text = KeyBindingManager.GetDisplayName(k); } } private int GetIndexForColor(string color) { // ������ trackJudgeTexts ��ͬ������ӳ�� switch (color) { case "red": return 0; case "green": return 1; case "yellow": return 2; case "purple": return 3; case "blue": return 4; default: return -1; } } /// /// ����ָ��������ж��ı�����ɫ /// public void ShowJudgeResult(int trackIndex, string result) { if (!showJudgeText) return; if (trackJudgeTexts == null || trackIndex < 0 || trackIndex >= trackJudgeTexts.Length) return; var textObj = trackJudgeTexts[trackIndex]; if (textObj == null) return; textObj.text = result; switch (result) { case "Perfect": textObj.color = perfectColor; break; case "Great": textObj.color = greatColor; break; case "Good": textObj.color = goodColor; break; case "Miss": textObj.color = missColor; break; default: textObj.color = Color.white; break; } } }