## SlotNumberManager 管理器 ``` cs using System.Collections; using UnityEngine; namespace SlotGame { /// /// 老虎机数字管理器 - 统一管理所有数字滚动动画 /// Slot machine number manager - centrally manages all number rolling animations /// public class SlotNumberManager : MonoBehaviour { [Header("数字滚动组件 Number Roll Components")] [SerializeField] private NumberRollAnimation scoreDisplay; [SerializeField] private NumberRollAnimation balanceDisplay; [SerializeField] private NumberRollAnimation jackpotDisplay; [SerializeField] private NumberRollAnimation winAmountDisplay; [SerializeField] private NumberRollAnimation betAmountDisplay; [Header("动画时间设置 Animation Timing")] [SerializeField] private float scoreRollDuration = 1.5f; [SerializeField] private float balanceRollDuration = 1.0f; [SerializeField] private float jackpotRollDuration = 0.8f; [SerializeField] private float winAmountRollDuration = 2.0f; [SerializeField] private float bigWinRollDuration = 4.0f; [Header("数值设置 Value Settings")] [SerializeField] private long currentScore = 0; [SerializeField] private long currentBalance = 50000; [SerializeField] private long currentJackpot = 3000000; [SerializeField] private long currentBetAmount = 100; [Header("大奖阈值 Big Win Threshold")] [SerializeField] private long bigWinThreshold = 100000; // 事件 public event System.Action OnScoreChanged; public event System.Action OnBalanceChanged; public event System.Action OnJackpotChanged; public event System.Action OnWinAmountShown; public event System.Action OnBigWinTriggered; #region Unity生命周期 private void Start() { InitializeDisplays(); RegisterEvents(); } private void OnDestroy() { UnregisterEvents(); } #endregion #region 初始化 private void InitializeDisplays() { // 设置初始显示值 if (scoreDisplay != null) scoreDisplay.SetValue(currentScore); if (balanceDisplay != null) balanceDisplay.SetValue(currentBalance); if (jackpotDisplay != null) jackpotDisplay.SetValue(currentJackpot); if (winAmountDisplay != null) winAmountDisplay.SetValue(0); if (betAmountDisplay != null) betAmountDisplay.SetValue(currentBetAmount); } private void RegisterEvents() { if (scoreDisplay != null) scoreDisplay.OnRollComplete += OnScoreRollComplete; if (balanceDisplay != null) balanceDisplay.OnRollComplete += OnBalanceRollComplete; if (jackpotDisplay != null) jackpotDisplay.OnRollComplete += OnJackpotRollComplete; if (winAmountDisplay != null) winAmountDisplay.OnRollComplete += OnWinAmountRollComplete; } private void UnregisterEvents() { if (scoreDisplay != null) scoreDisplay.OnRollComplete -= OnScoreRollComplete; if (balanceDisplay != null) balanceDisplay.OnRollComplete -= OnBalanceRollComplete; if (jackpotDisplay != null) jackpotDisplay.OnRollComplete -= OnJackpotRollComplete; if (winAmountDisplay != null) winAmountDisplay.OnRollComplete -= OnWinAmountRollComplete; } #endregion #region 分数管理 /// /// 增加分数 /// public void AddScore(long amount) { currentScore += amount; if (scoreDisplay != null) { scoreDisplay.RollToValue(currentScore, scoreRollDuration); } OnScoreChanged?.Invoke(currentScore); } /// /// 设置分数 /// public void SetScore(long score) { currentScore = score; if (scoreDisplay != null) { scoreDisplay.SetValue(currentScore); } OnScoreChanged?.Invoke(currentScore); } #endregion #region 余额管理 /// /// 增加余额 /// public void AddBalance(long amount) { currentBalance += amount; if (balanceDisplay != null) { balanceDisplay.RollToValue(currentBalance, balanceRollDuration); } OnBalanceChanged?.Invoke(currentBalance); } /// /// 扣除余额(下注) /// public bool DeductBalance(long amount) { if (currentBalance >= amount) { currentBalance -= amount; if (balanceDisplay != null) { balanceDisplay.RollToValue(currentBalance, balanceRollDuration); } OnBalanceChanged?.Invoke(currentBalance); return true; } return false; } /// /// 设置余额 /// public void SetBalance(long balance) { currentBalance = balance; if (balanceDisplay != null) { balanceDisplay.SetValue(currentBalance); } OnBalanceChanged?.Invoke(currentBalance); } #endregion #region 奖池管理 /// /// 增加奖池 /// public void AddJackpot(long amount) { currentJackpot += amount; if (jackpotDisplay != null) { jackpotDisplay.RollToValue(currentJackpot, jackpotRollDuration); } OnJackpotChanged?.Invoke(currentJackpot); } /// /// 重置奖池(中大奖后) /// public void ResetJackpot(long newAmount = 1000000) { currentJackpot = newAmount; if (jackpotDisplay != null) { jackpotDisplay.RollToValue(currentJackpot, jackpotRollDuration); } OnJackpotChanged?.Invoke(currentJackpot); } #endregion #region 中奖显示 /// /// 显示中奖金额 /// public void ShowWinAmount(long winAmount) { if (winAmountDisplay != null) { winAmountDisplay.SetValue(0); // 根据中奖金额决定动画时长 float duration = winAmount >= bigWinThreshold ? bigWinRollDuration : winAmountRollDuration; winAmountDisplay.RollToValue(winAmount, duration); // 检查是否是大奖 if (winAmount >= bigWinThreshold) { OnBigWinTriggered?.Invoke(winAmount); } } OnWinAmountShown?.Invoke(winAmount); } /// /// 隐藏中奖金额显示 /// public void HideWinAmount() { if (winAmountDisplay != null) { winAmountDisplay.SetValue(0); } } #endregion #region 下注金额 /// /// 设置下注金额 /// public void SetBetAmount(long betAmount) { currentBetAmount = betAmount; if (betAmountDisplay != null) { betAmountDisplay.SetValue(currentBetAmount); } } /// /// 更新下注金额(带动画) /// public void UpdateBetAmount(long betAmount) { currentBetAmount = betAmount; if (betAmountDisplay != null) { betAmountDisplay.RollToValue(currentBetAmount, 0.5f); } } #endregion #region 游戏流程 /// /// 开始游戏(扣除下注金额) /// public bool StartGame() { return DeductBalance(currentBetAmount); } /// /// 处理游戏结果 /// public void ProcessGameResult(long winAmount, bool addToScore = true) { if (winAmount > 0) { // 显示中奖金额 ShowWinAmount(winAmount); // 启动协程处理后续动画 StartCoroutine(ProcessWinSequence(winAmount, addToScore)); } } private IEnumerator ProcessWinSequence(long winAmount, bool addToScore) { // 等待中奖金额动画 float waitTime = winAmount >= bigWinThreshold ? bigWinRollDuration : winAmountRollDuration; yield return new WaitForSeconds(waitTime + 0.5f); // 同时更新余额和分数 if (addToScore) { AddScore(winAmount); } AddBalance(winAmount); // 延迟后隐藏中奖显示 yield return new WaitForSeconds(2f); HideWinAmount(); } /// /// 中大奖流程 /// public void ProcessJackpotWin() { long jackpotWin = currentJackpot; // 显示大奖金额 ShowWinAmount(jackpotWin); // 重置奖池 ResetJackpot(); // 处理大奖结果 StartCoroutine(ProcessJackpotSequence(jackpotWin)); } private IEnumerator ProcessJackpotSequence(long jackpotAmount) { // 等待大奖动画 yield return new WaitForSeconds(bigWinRollDuration + 1f); // 更新余额和分数 AddScore(jackpotAmount); AddBalance(jackpotAmount); // 延迟后隐藏显示 yield return new WaitForSeconds(3f); HideWinAmount(); } #endregion #region 事件回调 private void OnScoreRollComplete(long value) { Debug.Log($"Score roll completed: {value}"); } private void OnBalanceRollComplete(long value) { Debug.Log($"Balance roll completed: {value}"); } private void OnJackpotRollComplete(long value) { Debug.Log($"Jackpot roll completed: {value}"); } private void OnWinAmountRollComplete(long value) { Debug.Log($"Win amount roll completed: {value}"); } #endregion #region 属性访问器 public long CurrentScore => currentScore; public long CurrentBalance => currentBalance; public long CurrentJackpot => currentJackpot; public long CurrentBetAmount => currentBetAmount; public bool CanAffordBet => currentBalance >= currentBetAmount; #endregion #region 调试方法 [ContextMenu("Test Small Win")] private void TestSmallWin() { ProcessGameResult(5000); } [ContextMenu("Test Big Win")] private void TestBigWin() { ProcessGameResult(150000); } [ContextMenu("Test Jackpot Win")] private void TestJackpotWin() { ProcessJackpotWin(); } [ContextMenu("Add Balance 10000")] private void TestAddBalance() { AddBalance(10000); } [ContextMenu("Increase Jackpot")] private void TestIncreaseJackpot() { AddJackpot(50000); } #endregion } } ```