管理器
using System.Collections;
using UnityEngine;
namespace SlotGame
{
/// <summary>
/// 老虎机数字管理器 - 统一管理所有数字滚动动画
/// Slot machine number manager - centrally manages all number rolling animations
/// </summary>
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<long> OnScoreChanged;
public event System.Action<long> OnBalanceChanged;
public event System.Action<long> OnJackpotChanged;
public event System.Action<long> OnWinAmountShown;
public event System.Action<long> 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 分数管理
/// <summary>
/// 增加分数
/// </summary>
public void AddScore(long amount)
{
currentScore += amount;
if (scoreDisplay != null)
{
scoreDisplay.RollToValue(currentScore, scoreRollDuration);
}
OnScoreChanged?.Invoke(currentScore);
}
/// <summary>
/// 设置分数
/// </summary>
public void SetScore(long score)
{
currentScore = score;
if (scoreDisplay != null)
{
scoreDisplay.SetValue(currentScore);
}
OnScoreChanged?.Invoke(currentScore);
}
#endregion
#region 余额管理
/// <summary>
/// 增加余额
/// </summary>
public void AddBalance(long amount)
{
currentBalance += amount;
if (balanceDisplay != null)
{
balanceDisplay.RollToValue(currentBalance, balanceRollDuration);
}
OnBalanceChanged?.Invoke(currentBalance);
}
/// <summary>
/// 扣除余额(下注)
/// </summary>
public bool DeductBalance(long amount)
{
if (currentBalance >= amount)
{
currentBalance -= amount;
if (balanceDisplay != null)
{
balanceDisplay.RollToValue(currentBalance, balanceRollDuration);
}
OnBalanceChanged?.Invoke(currentBalance);
return true;
}
return false;
}
/// <summary>
/// 设置余额
/// </summary>
public void SetBalance(long balance)
{
currentBalance = balance;
if (balanceDisplay != null)
{
balanceDisplay.SetValue(currentBalance);
}
OnBalanceChanged?.Invoke(currentBalance);
}
#endregion
#region 奖池管理
/// <summary>
/// 增加奖池
/// </summary>
public void AddJackpot(long amount)
{
currentJackpot += amount;
if (jackpotDisplay != null)
{
jackpotDisplay.RollToValue(currentJackpot, jackpotRollDuration);
}
OnJackpotChanged?.Invoke(currentJackpot);
}
/// <summary>
/// 重置奖池(中大奖后)
/// </summary>
public void ResetJackpot(long newAmount = 1000000)
{
currentJackpot = newAmount;
if (jackpotDisplay != null)
{
jackpotDisplay.RollToValue(currentJackpot, jackpotRollDuration);
}
OnJackpotChanged?.Invoke(currentJackpot);
}
#endregion
#region 中奖显示
/// <summary>
/// 显示中奖金额
/// </summary>
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);
}
/// <summary>
/// 隐藏中奖金额显示
/// </summary>
public void HideWinAmount()
{
if (winAmountDisplay != null)
{
winAmountDisplay.SetValue(0);
}
}
#endregion
#region 下注金额
/// <summary>
/// 设置下注金额
/// </summary>
public void SetBetAmount(long betAmount)
{
currentBetAmount = betAmount;
if (betAmountDisplay != null)
{
betAmountDisplay.SetValue(currentBetAmount);
}
}
/// <summary>
/// 更新下注金额(带动画)
/// </summary>
public void UpdateBetAmount(long betAmount)
{
currentBetAmount = betAmount;
if (betAmountDisplay != null)
{
betAmountDisplay.RollToValue(currentBetAmount, 0.5f);
}
}
#endregion
#region 游戏流程
/// <summary>
/// 开始游戏(扣除下注金额)
/// </summary>
public bool StartGame()
{
return DeductBalance(currentBetAmount);
}
/// <summary>
/// 处理游戏结果
/// </summary>
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();
}
/// <summary>
/// 中大奖流程
/// </summary>
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
}
}