using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; public class RumbleManager : MonoBehaviour { public bool DoRubling = true; public static RumbleManager Instance { get; private set; } public static Gamepad[] pads; private class RumbleEffect { public float duration; public float startTime; public float lowFreq; public float highFreq; public RumbleEffect(float low, float high, float dur) { lowFreq = low; highFreq = high; duration = dur; startTime = Time.time; } } private static Dictionary> playerRumbles = new Dictionary>(); private void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); for (int i = 0; i < Gamepad.all.Count; i++) { playerRumbles[i] = new List(); // Initialize list for each connected controller } } else { Destroy(gameObject); } Invoke("LateStart", 0.1f); } void LateStart() { pads = Gamepad.all.ToArray(); initialized = true; } bool initialized = false; private void Update() { if (!initialized || !DoRubling) return; foreach (var player in playerRumbles.Keys) { UpdateRumble(player); } } private static void UpdateRumble(int player) { if (!playerRumbles.ContainsKey(player) || playerRumbles[player].Count == 0) return; float maxLowFreq = 0f; float maxHighFreq = 0f; bool shouldRumble = false; for (int i = playerRumbles[player].Count - 1; i >= 0; i--) { RumbleEffect effect = playerRumbles[player][i]; if (Time.time - effect.startTime >= effect.duration) { playerRumbles[player].RemoveAt(i); } else { shouldRumble = true; maxLowFreq = Mathf.Max(maxLowFreq, effect.lowFreq); maxHighFreq = Mathf.Max(maxHighFreq, effect.highFreq); } } if (shouldRumble) { SetMotorSpeeds(player, maxLowFreq, maxHighFreq); } else { SetMotorSpeeds(player, 0, 0); // Stop rumbling for this player } } // Now static, allowing it to be called without an instance public static void StartRumble(int player, float lowFreq, float highFreq, float duration) { if (player == -1) // Target both players { foreach (var p in playerRumbles.Keys) { StartRumbleForPlayer(p, lowFreq, highFreq, duration); } } else // Target a specific player { StartRumbleForPlayer(player, lowFreq, highFreq, duration); } } private static void StartRumbleForPlayer(int player, float lowFreq, float highFreq, float duration) { if (!playerRumbles.ContainsKey(player)) { playerRumbles[player] = new List(); } playerRumbles[player].Add(new RumbleEffect(lowFreq, highFreq, duration)); } public static void StopAllRumbles(int player) { if (playerRumbles.ContainsKey(player)) { playerRumbles[player].Clear(); SetMotorSpeeds(player, 0, 0); // Stop rumbling for this player } } private static void SetMotorSpeeds(int player, float lowFreq, float highFreq) { if (player >= 0 && player < pads.Length) { pads[player].SetMotorSpeeds(lowFreq, highFreq); } } }