|
|
@@ -0,0 +1,968 @@
|
|
|
+## NumberRollAnimation
|
|
|
+
|
|
|
+``` cs
|
|
|
+using System;
|
|
|
+using System.Collections;
|
|
|
+using UnityEngine;
|
|
|
+using UnityEngine.UI;
|
|
|
+
|
|
|
+namespace SlotGame
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ /// 数字滚动动画组件 - 用于显示数字增加的滚动效果
|
|
|
+ /// Number rolling animation component - for displaying number increment rolling effects
|
|
|
+ /// </summary>
|
|
|
+ public class NumberRollAnimation : MonoBehaviour
|
|
|
+ {
|
|
|
+ [Header("目标组件 Target Components")]
|
|
|
+ [SerializeField] private Text uiText;
|
|
|
+
|
|
|
+ [Header("动画设置 Animation Settings")]
|
|
|
+ [SerializeField] private float rollDuration = 2f;
|
|
|
+ [SerializeField] private AnimationCurve rollCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
|
|
|
+ [SerializeField] private bool useRandomRolling = true;
|
|
|
+ [SerializeField] private float randomRollSpeed = 0.05f;
|
|
|
+
|
|
|
+ [Header("大数字优化 Large Number Optimization")]
|
|
|
+ [SerializeField] private bool enableLargeNumberMode = true;
|
|
|
+ [SerializeField] private long largeNumberThreshold = 1000000; // 100万以上算大数字
|
|
|
+ [SerializeField] private float largeNumberDurationMultiplier = 1.5f; // 大数字动画时长倍数
|
|
|
+ [SerializeField] private float ultraLargeNumberThreshold = 100000000; // 1亿以上算超大数字
|
|
|
+ [SerializeField] private float ultraLargeNumberDurationMultiplier = 2.0f; // 超大数字动画时长倍数
|
|
|
+ [SerializeField] private int largeNumberUpdateInterval = 2; // 大数字更新间隔帧数(优化性能)
|
|
|
+
|
|
|
+ [Header("数字格式 Number Format")]
|
|
|
+ [SerializeField] private string numberFormat = "N0"; // N0 = 1,234,567
|
|
|
+ [SerializeField] private bool useCustomFormat = false;
|
|
|
+ [SerializeField] private string customFormat = "{0:N0}";
|
|
|
+
|
|
|
+ [Header("滚动效果 Rolling Effects")]
|
|
|
+ [SerializeField] private bool enableSound = true;
|
|
|
+ [SerializeField] private AudioClip rollSound;
|
|
|
+ [SerializeField] private AudioClip completeSound;
|
|
|
+ [SerializeField] private bool enableShake = false;
|
|
|
+ [SerializeField] private float shakeIntensity = 2f;
|
|
|
+
|
|
|
+ [Header("调试 Debug")]
|
|
|
+ [SerializeField] private bool debugMode = false;
|
|
|
+
|
|
|
+ // 私有变量
|
|
|
+ private long currentValue;
|
|
|
+ private long targetValue;
|
|
|
+ private bool isRolling = false;
|
|
|
+ private Coroutine rollCoroutine;
|
|
|
+ private AudioSource audioSource;
|
|
|
+ private Vector3 originalPosition;
|
|
|
+ private int frameCounter = 0; // 用于大数字性能优化
|
|
|
+
|
|
|
+ // 事件
|
|
|
+ public event Action<long> OnValueChanged;
|
|
|
+ public event Action<long> OnRollComplete;
|
|
|
+ public event Action OnRollStart;
|
|
|
+
|
|
|
+ #region Unity生命周期
|
|
|
+
|
|
|
+ private void Awake()
|
|
|
+ {
|
|
|
+ InitializeComponents();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Start()
|
|
|
+ {
|
|
|
+ originalPosition = transform.localPosition;
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 初始化
|
|
|
+
|
|
|
+ private void InitializeComponents()
|
|
|
+ {
|
|
|
+ // 自动获取文本组件
|
|
|
+ if (uiText == null) uiText = GetComponent<Text>();
|
|
|
+
|
|
|
+ // 获取或创建AudioSource
|
|
|
+ audioSource = GetComponent<AudioSource>();
|
|
|
+ if (audioSource == null && enableSound)
|
|
|
+ {
|
|
|
+ audioSource = gameObject.AddComponent<AudioSource>();
|
|
|
+ audioSource.playOnAwake = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 公共方法
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 设置当前值(无动画)
|
|
|
+ /// </summary>
|
|
|
+ public void SetValue(long value)
|
|
|
+ {
|
|
|
+ currentValue = value;
|
|
|
+ targetValue = value;
|
|
|
+ UpdateDisplayText(value);
|
|
|
+
|
|
|
+ if (debugMode) Debug.Log($"NumberRoll: Set value to {value}");
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 滚动到目标值
|
|
|
+ /// </summary>
|
|
|
+ public void RollToValue(long targetValue, float? customDuration = null)
|
|
|
+ {
|
|
|
+ if (isRolling)
|
|
|
+ {
|
|
|
+ StopRoll();
|
|
|
+ }
|
|
|
+
|
|
|
+ this.targetValue = targetValue;
|
|
|
+ float duration = customDuration ?? CalculateOptimalDuration(currentValue, targetValue);
|
|
|
+
|
|
|
+ rollCoroutine = StartCoroutine(RollCoroutine(currentValue, targetValue, duration));
|
|
|
+
|
|
|
+ if (debugMode) Debug.Log($"NumberRoll: Rolling from {currentValue} to {targetValue} in {duration}s");
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 增加值(从当前值滚动增加)
|
|
|
+ /// </summary>
|
|
|
+ public void AddValue(long addAmount, float? customDuration = null)
|
|
|
+ {
|
|
|
+ long newTarget = currentValue + addAmount;
|
|
|
+ RollToValue(newTarget, customDuration);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 停止滚动
|
|
|
+ /// </summary>
|
|
|
+ public void StopRoll()
|
|
|
+ {
|
|
|
+ if (rollCoroutine != null)
|
|
|
+ {
|
|
|
+ StopCoroutine(rollCoroutine);
|
|
|
+ rollCoroutine = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ isRolling = false;
|
|
|
+ currentValue = targetValue;
|
|
|
+ UpdateDisplayText(currentValue);
|
|
|
+
|
|
|
+ // 重置位置
|
|
|
+ if (enableShake)
|
|
|
+ {
|
|
|
+ transform.localPosition = originalPosition;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 立即完成滚动
|
|
|
+ /// </summary>
|
|
|
+ public void CompleteRoll()
|
|
|
+ {
|
|
|
+ StopRoll();
|
|
|
+ OnRollComplete?.Invoke(currentValue);
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 大数字优化方法
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 根据数字大小计算最佳动画时长
|
|
|
+ /// </summary>
|
|
|
+ private float CalculateOptimalDuration(long startValue, long endValue)
|
|
|
+ {
|
|
|
+ if (!enableLargeNumberMode)
|
|
|
+ return rollDuration;
|
|
|
+
|
|
|
+ long difference = Math.Abs(endValue - startValue);
|
|
|
+
|
|
|
+ if (difference >= ultraLargeNumberThreshold)
|
|
|
+ {
|
|
|
+ // 超大数字:1亿以上
|
|
|
+ return rollDuration * ultraLargeNumberDurationMultiplier;
|
|
|
+ }
|
|
|
+ else if (difference >= largeNumberThreshold)
|
|
|
+ {
|
|
|
+ // 大数字:100万以上
|
|
|
+ return rollDuration * largeNumberDurationMultiplier;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ // 普通数字
|
|
|
+ return rollDuration;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 检查是否为大数字
|
|
|
+ /// </summary>
|
|
|
+ private bool IsLargeNumber(long value)
|
|
|
+ {
|
|
|
+ return enableLargeNumberMode && Math.Abs(value) >= largeNumberThreshold;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 检查是否需要跳帧优化(大数字性能优化)
|
|
|
+ /// </summary>
|
|
|
+ private bool ShouldSkipFrame()
|
|
|
+ {
|
|
|
+ if (!IsLargeNumber(targetValue))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ frameCounter++;
|
|
|
+ if (frameCounter >= largeNumberUpdateInterval)
|
|
|
+ {
|
|
|
+ frameCounter = 0;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 滚动逻辑
|
|
|
+
|
|
|
+ private IEnumerator RollCoroutine(long startValue, long endValue, float duration)
|
|
|
+ {
|
|
|
+ isRolling = true;
|
|
|
+ frameCounter = 0;
|
|
|
+ OnRollStart?.Invoke();
|
|
|
+
|
|
|
+ // 播放滚动音效
|
|
|
+ if (enableSound && rollSound != null && audioSource != null)
|
|
|
+ {
|
|
|
+ audioSource.clip = rollSound;
|
|
|
+ audioSource.loop = true;
|
|
|
+ audioSource.Play();
|
|
|
+ }
|
|
|
+
|
|
|
+ float elapsedTime = 0f;
|
|
|
+ long difference = endValue - startValue;
|
|
|
+ bool isLargeNum = IsLargeNumber(endValue);
|
|
|
+
|
|
|
+ // 大数字使用不同的随机策略
|
|
|
+ float randomIntensity = isLargeNum ? 0.05f : 0.1f; // 大数字减少随机波动
|
|
|
+ float randomPhase = isLargeNum ? 0.9f : 0.8f; // 大数字延长随机阶段
|
|
|
+
|
|
|
+ if (debugMode && isLargeNum)
|
|
|
+ Debug.Log($"NumberRoll: Large number detected, using optimized animation for {endValue}");
|
|
|
+
|
|
|
+ while (elapsedTime < duration)
|
|
|
+ {
|
|
|
+ elapsedTime += Time.deltaTime;
|
|
|
+ float progress = elapsedTime / duration;
|
|
|
+ float curveProgress = rollCurve.Evaluate(progress);
|
|
|
+
|
|
|
+ // 计算当前值
|
|
|
+ long rollingValue;
|
|
|
+ if (useRandomRolling && progress < randomPhase)
|
|
|
+ {
|
|
|
+ rollingValue = startValue + (long)(difference * curveProgress);
|
|
|
+ // 大数字优化:减少随机波动强度,增加波动频率控制
|
|
|
+ if (Time.time % randomRollSpeed < Time.deltaTime)
|
|
|
+ {
|
|
|
+ long randomOffset = (long)(difference * randomIntensity * UnityEngine.Random.Range(-1f, 1f));
|
|
|
+ rollingValue += randomOffset;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ rollingValue = startValue + (long)(difference * curveProgress);
|
|
|
+ }
|
|
|
+
|
|
|
+ currentValue = rollingValue;
|
|
|
+
|
|
|
+ // 大数字性能优化:跳帧更新
|
|
|
+ if (!ShouldSkipFrame())
|
|
|
+ {
|
|
|
+ UpdateDisplayText(currentValue);
|
|
|
+ OnValueChanged?.Invoke(currentValue);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 震动效果
|
|
|
+ if (enableShake)
|
|
|
+ {
|
|
|
+ float shakeAmount = shakeIntensity * (1f - progress);
|
|
|
+ // 大数字减少震动强度
|
|
|
+ if (isLargeNum) shakeAmount *= 0.5f;
|
|
|
+
|
|
|
+ Vector3 shakeOffset = new Vector3(
|
|
|
+ UnityEngine.Random.Range(-shakeAmount, shakeAmount),
|
|
|
+ UnityEngine.Random.Range(-shakeAmount, shakeAmount),
|
|
|
+ 0f
|
|
|
+ );
|
|
|
+ transform.localPosition = originalPosition + shakeOffset;
|
|
|
+ }
|
|
|
+
|
|
|
+ yield return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保最终值正确
|
|
|
+ currentValue = endValue;
|
|
|
+ UpdateDisplayText(currentValue);
|
|
|
+
|
|
|
+ // 重置位置
|
|
|
+ if (enableShake)
|
|
|
+ {
|
|
|
+ transform.localPosition = originalPosition;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 停止滚动音效,播放完成音效
|
|
|
+ if (enableSound && audioSource != null)
|
|
|
+ {
|
|
|
+ audioSource.Stop();
|
|
|
+ if (completeSound != null)
|
|
|
+ {
|
|
|
+ audioSource.PlayOneShot(completeSound);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ isRolling = false;
|
|
|
+ rollCoroutine = null;
|
|
|
+
|
|
|
+ OnValueChanged?.Invoke(currentValue);
|
|
|
+ OnRollComplete?.Invoke(currentValue);
|
|
|
+
|
|
|
+ if (debugMode) Debug.Log($"NumberRoll: Completed rolling to {currentValue}");
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 文本更新
|
|
|
+
|
|
|
+ private void UpdateDisplayText(long value)
|
|
|
+ {
|
|
|
+ string formattedText = FormatNumber(value);
|
|
|
+
|
|
|
+ if (uiText != null)
|
|
|
+ uiText.text = formattedText;
|
|
|
+ }
|
|
|
+
|
|
|
+ private string FormatNumber(long value)
|
|
|
+ {
|
|
|
+ if (useCustomFormat)
|
|
|
+ {
|
|
|
+ return string.Format(customFormat, value);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return value.ToString(numberFormat);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 属性访问器
|
|
|
+
|
|
|
+ public long CurrentValue => currentValue;
|
|
|
+ public long TargetValue => targetValue;
|
|
|
+ public bool IsRolling => isRolling;
|
|
|
+
|
|
|
+ public float RollDuration
|
|
|
+ {
|
|
|
+ get => rollDuration;
|
|
|
+ set => rollDuration = Mathf.Max(0.1f, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 获取当前是否为大数字模式
|
|
|
+ /// </summary>
|
|
|
+ public bool IsInLargeNumberMode => IsLargeNumber(currentValue) || IsLargeNumber(targetValue);
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 调试方法
|
|
|
+
|
|
|
+ [ContextMenu("Test Roll +1000")]
|
|
|
+ private void TestRoll1000()
|
|
|
+ {
|
|
|
+ AddValue(1000);
|
|
|
+ }
|
|
|
+
|
|
|
+ [ContextMenu("Test Roll +10000")]
|
|
|
+ private void TestRoll10000()
|
|
|
+ {
|
|
|
+ AddValue(10000);
|
|
|
+ }
|
|
|
+
|
|
|
+ [ContextMenu("Test Set 1000000")]
|
|
|
+ private void TestSetMillion()
|
|
|
+ {
|
|
|
+ SetValue(1000000);
|
|
|
+ }
|
|
|
+
|
|
|
+ [ContextMenu("Test Large Number +10000000")]
|
|
|
+ private void TestLargeNumber()
|
|
|
+ {
|
|
|
+ AddValue(10000000); // 1千万
|
|
|
+ }
|
|
|
+
|
|
|
+ [ContextMenu("Test Ultra Large Number +100000000")]
|
|
|
+ private void TestUltraLargeNumber()
|
|
|
+ {
|
|
|
+ AddValue(100000000); // 1亿
|
|
|
+ }
|
|
|
+
|
|
|
+ [ContextMenu("Test Jackpot Size")]
|
|
|
+ private void TestJackpotSize()
|
|
|
+ {
|
|
|
+ RollToValue(999999999); // 接近10亿
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## NumberRollExample
|
|
|
+
|
|
|
+``` cs
|
|
|
+using UnityEngine;
|
|
|
+using UnityEngine.UI;
|
|
|
+
|
|
|
+namespace SlotGame
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ /// 数字滚动动画使用示例
|
|
|
+ /// Number roll animation usage examples
|
|
|
+ /// </summary>
|
|
|
+ public class NumberRollExample : MonoBehaviour
|
|
|
+ {
|
|
|
+ [Header("数字滚动组件引用 Number Roll References")]
|
|
|
+ [SerializeField] private NumberRollAnimation scoreRoll;
|
|
|
+ [SerializeField] private NumberRollAnimation jackpotRoll;
|
|
|
+ [SerializeField] private NumberRollAnimation winAmountRoll;
|
|
|
+ [SerializeField] private NumberRollAnimation balanceRoll;
|
|
|
+
|
|
|
+ [Header("翻页数字组件引用 Flip Number References")]
|
|
|
+ [SerializeField] private FlipNumberDisplay megaJackpotFlip;
|
|
|
+ [SerializeField] private FlipNumberDisplay ultraWinFlip;
|
|
|
+
|
|
|
+ [Header("测试按钮 Test Buttons")]
|
|
|
+ [SerializeField] private Button addScoreBtn;
|
|
|
+ [SerializeField] private Button addJackpotBtn;
|
|
|
+ [SerializeField] private Button showWinBtn;
|
|
|
+ [SerializeField] private Button updateBalanceBtn;
|
|
|
+
|
|
|
+ [Header("大数字测试按钮 Large Number Test Buttons")]
|
|
|
+ [SerializeField] private Button largeWinBtn;
|
|
|
+ [SerializeField] private Button megaJackpotBtn;
|
|
|
+ [SerializeField] private Button ultraWinBtn;
|
|
|
+ [SerializeField] private Button resetAllBtn;
|
|
|
+
|
|
|
+ [Header("测试数值 Test Values")]
|
|
|
+ [SerializeField] private long scoreIncrement = 1000;
|
|
|
+ [SerializeField] private long jackpotIncrement = 50000;
|
|
|
+ [SerializeField] private long winAmount = 25000;
|
|
|
+ [SerializeField] private long balanceAmount = 100000;
|
|
|
+
|
|
|
+ [Header("大数字测试数值 Large Number Test Values")]
|
|
|
+ [SerializeField] private long largeWinAmount = 50000000; // 5千万
|
|
|
+ [SerializeField] private long megaJackpotAmount = 500000000; // 5亿
|
|
|
+ [SerializeField] private long ultraWinAmount = 999999999999; // 接近万亿
|
|
|
+
|
|
|
+ private void Start()
|
|
|
+ {
|
|
|
+ InitializeUI();
|
|
|
+ RegisterEvents();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnDestroy()
|
|
|
+ {
|
|
|
+ UnregisterEvents();
|
|
|
+ }
|
|
|
+
|
|
|
+ #region 初始化
|
|
|
+
|
|
|
+ private void InitializeUI()
|
|
|
+ {
|
|
|
+ // 设置初始值
|
|
|
+ if (scoreRoll != null)
|
|
|
+ scoreRoll.SetValue(0);
|
|
|
+
|
|
|
+ if (jackpotRoll != null)
|
|
|
+ jackpotRoll.SetValue(3000000); // 初始奖池
|
|
|
+
|
|
|
+ if (winAmountRoll != null)
|
|
|
+ winAmountRoll.SetValue(0);
|
|
|
+
|
|
|
+ if (balanceRoll != null)
|
|
|
+ balanceRoll.SetValue(50000); // 初始余额
|
|
|
+
|
|
|
+ // 设置大数字显示初始值
|
|
|
+ if (megaJackpotFlip != null)
|
|
|
+ megaJackpotFlip.SetValue(1000000000); // 10亿起始奖池
|
|
|
+
|
|
|
+ if (ultraWinFlip != null)
|
|
|
+ ultraWinFlip.SetValue(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void RegisterEvents()
|
|
|
+ {
|
|
|
+ // 按钮事件
|
|
|
+ if (addScoreBtn != null)
|
|
|
+ addScoreBtn.onClick.AddListener(OnAddScore);
|
|
|
+
|
|
|
+ if (addJackpotBtn != null)
|
|
|
+ addJackpotBtn.onClick.AddListener(OnAddJackpot);
|
|
|
+
|
|
|
+ if (showWinBtn != null)
|
|
|
+ showWinBtn.onClick.AddListener(OnShowWin);
|
|
|
+
|
|
|
+ if (updateBalanceBtn != null)
|
|
|
+ updateBalanceBtn.onClick.AddListener(OnUpdateBalance);
|
|
|
+
|
|
|
+ // 大数字测试按钮事件
|
|
|
+ if (largeWinBtn != null)
|
|
|
+ largeWinBtn.onClick.AddListener(OnLargeWin);
|
|
|
+
|
|
|
+ if (megaJackpotBtn != null)
|
|
|
+ megaJackpotBtn.onClick.AddListener(OnMegaJackpot);
|
|
|
+
|
|
|
+ if (ultraWinBtn != null)
|
|
|
+ ultraWinBtn.onClick.AddListener(OnUltraWin);
|
|
|
+
|
|
|
+ if (resetAllBtn != null)
|
|
|
+ resetAllBtn.onClick.AddListener(OnResetAll);
|
|
|
+
|
|
|
+ // 数字滚动事件
|
|
|
+ if (scoreRoll != null)
|
|
|
+ {
|
|
|
+ scoreRoll.OnRollStart += () => Debug.Log("Score rolling started");
|
|
|
+ scoreRoll.OnRollComplete += (value) => Debug.Log($"Score rolling completed: {value:N0}");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (winAmountRoll != null)
|
|
|
+ {
|
|
|
+ winAmountRoll.OnRollComplete += OnWinRollComplete;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 大数字组件事件
|
|
|
+ if (megaJackpotFlip != null)
|
|
|
+ {
|
|
|
+ megaJackpotFlip.OnLargeNumberDetected += (value) => Debug.Log($"Mega Jackpot: Large number detected! {value:N0}");
|
|
|
+ megaJackpotFlip.OnSpinComplete += (value) => Debug.Log($"Mega Jackpot spin completed: {value:N0}");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ultraWinFlip != null)
|
|
|
+ {
|
|
|
+ ultraWinFlip.OnLargeNumberDetected += (value) => Debug.Log($"Ultra Win: Large number detected! {value:N0}");
|
|
|
+ ultraWinFlip.OnSpinComplete += OnUltraWinComplete;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void UnregisterEvents()
|
|
|
+ {
|
|
|
+ if (addScoreBtn != null)
|
|
|
+ addScoreBtn.onClick.RemoveListener(OnAddScore);
|
|
|
+
|
|
|
+ if (addJackpotBtn != null)
|
|
|
+ addJackpotBtn.onClick.RemoveListener(OnAddJackpot);
|
|
|
+
|
|
|
+ if (showWinBtn != null)
|
|
|
+ showWinBtn.onClick.RemoveListener(OnShowWin);
|
|
|
+
|
|
|
+ if (updateBalanceBtn != null)
|
|
|
+ updateBalanceBtn.onClick.RemoveListener(OnUpdateBalance);
|
|
|
+
|
|
|
+ // 移除大数字测试按钮事件
|
|
|
+ if (largeWinBtn != null)
|
|
|
+ largeWinBtn.onClick.RemoveListener(OnLargeWin);
|
|
|
+
|
|
|
+ if (megaJackpotBtn != null)
|
|
|
+ megaJackpotBtn.onClick.RemoveListener(OnMegaJackpot);
|
|
|
+
|
|
|
+ if (ultraWinBtn != null)
|
|
|
+ ultraWinBtn.onClick.RemoveListener(OnUltraWin);
|
|
|
+
|
|
|
+ if (resetAllBtn != null)
|
|
|
+ resetAllBtn.onClick.RemoveListener(OnResetAll);
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 按钮事件处理
|
|
|
+
|
|
|
+ private void OnAddScore()
|
|
|
+ {
|
|
|
+ if (scoreRoll != null)
|
|
|
+ {
|
|
|
+ scoreRoll.AddValue(scoreIncrement, 1.5f); // 1.5秒滚动时间
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnAddJackpot()
|
|
|
+ {
|
|
|
+ if (jackpotRoll != null)
|
|
|
+ {
|
|
|
+ jackpotRoll.AddValue(jackpotIncrement, 2f); // 2秒滚动时间
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnShowWin()
|
|
|
+ {
|
|
|
+ if (winAmountRoll != null)
|
|
|
+ {
|
|
|
+ // 先重置为0,然后滚动到中奖金额
|
|
|
+ winAmountRoll.SetValue(0);
|
|
|
+ winAmountRoll.RollToValue(winAmount, 3f); // 3秒展示中奖动画
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnUpdateBalance()
|
|
|
+ {
|
|
|
+ if (balanceRoll != null)
|
|
|
+ {
|
|
|
+ balanceRoll.RollToValue(balanceAmount, 1f);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 大数字测试事件处理
|
|
|
+
|
|
|
+ private void OnLargeWin()
|
|
|
+ {
|
|
|
+ Debug.Log($"Testing Large Win: {largeWinAmount:N0}");
|
|
|
+
|
|
|
+ // 使用NumberRollAnimation显示大奖
|
|
|
+ if (winAmountRoll != null)
|
|
|
+ {
|
|
|
+ winAmountRoll.SetValue(0);
|
|
|
+ winAmountRoll.RollToValue(largeWinAmount); // 自动使用大数字优化
|
|
|
+ }
|
|
|
+
|
|
|
+ // 同时更新分数(演示大数字性能优化)
|
|
|
+ if (scoreRoll != null)
|
|
|
+ {
|
|
|
+ StartCoroutine(DelayedScoreUpdate(largeWinAmount, 4f));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnMegaJackpot()
|
|
|
+ {
|
|
|
+ Debug.Log($"Testing Mega Jackpot: {megaJackpotAmount:N0}");
|
|
|
+
|
|
|
+ // 使用FlipNumberDisplay显示超级大奖
|
|
|
+ if (megaJackpotFlip != null)
|
|
|
+ {
|
|
|
+ megaJackpotFlip.SpinToValue(megaJackpotAmount); // 自动使用Level 2优化
|
|
|
+ }
|
|
|
+
|
|
|
+ // 同时播放特效提示
|
|
|
+ ShowMegaJackpotEffect();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnUltraWin()
|
|
|
+ {
|
|
|
+ Debug.Log($"Testing Ultra Win: {ultraWinAmount:N0}");
|
|
|
+
|
|
|
+ // 使用FlipNumberDisplay显示终极大奖
|
|
|
+ if (ultraWinFlip != null)
|
|
|
+ {
|
|
|
+ ultraWinFlip.SetValue(0);
|
|
|
+ ultraWinFlip.SpinToValue(ultraWinAmount); // 自动使用Level 3优化
|
|
|
+ }
|
|
|
+
|
|
|
+ // 触发终极大奖序列
|
|
|
+ StartCoroutine(UltraWinSequence());
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnResetAll()
|
|
|
+ {
|
|
|
+ Debug.Log("Resetting all displays to initial values");
|
|
|
+
|
|
|
+ // 重置所有数字显示
|
|
|
+ if (scoreRoll != null) scoreRoll.SetValue(0);
|
|
|
+ if (jackpotRoll != null) jackpotRoll.SetValue(3000000);
|
|
|
+ if (winAmountRoll != null) winAmountRoll.SetValue(0);
|
|
|
+ if (balanceRoll != null) balanceRoll.SetValue(50000);
|
|
|
+
|
|
|
+ if (megaJackpotFlip != null) megaJackpotFlip.SetValue(1000000000);
|
|
|
+ if (ultraWinFlip != null) ultraWinFlip.SetValue(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 大数字特效和序列
|
|
|
+
|
|
|
+ private void ShowMegaJackpotEffect()
|
|
|
+ {
|
|
|
+ // 可以在这里添加粒子特效、屏幕震动等
|
|
|
+ Debug.Log("🎉 MEGA JACKPOT EFFECT! 🎉");
|
|
|
+
|
|
|
+ // 演示颜色变化效果
|
|
|
+ if (megaJackpotFlip != null)
|
|
|
+ {
|
|
|
+ megaJackpotFlip.SetLargeNumberColorEffect(Color.white, Color.yellow);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private System.Collections.IEnumerator UltraWinSequence()
|
|
|
+ {
|
|
|
+ Debug.Log("🌟 ULTRA WIN SEQUENCE STARTED! 🌟");
|
|
|
+
|
|
|
+ // 等待翻页动画完成
|
|
|
+ yield return new WaitForSeconds(6f);
|
|
|
+
|
|
|
+ // 显示所有数字的庆祝动画
|
|
|
+ Debug.Log("💰 ULTRA WIN CELEBRATION! 💰");
|
|
|
+
|
|
|
+ // 更新所有相关数字
|
|
|
+ if (scoreRoll != null)
|
|
|
+ scoreRoll.AddValue(ultraWinAmount / 10); // 添加部分到分数
|
|
|
+
|
|
|
+ if (balanceRoll != null)
|
|
|
+ balanceRoll.AddValue(ultraWinAmount); // 添加到余额
|
|
|
+ }
|
|
|
+
|
|
|
+ private System.Collections.IEnumerator DelayedScoreUpdate(long amount, float delay)
|
|
|
+ {
|
|
|
+ yield return new WaitForSeconds(delay);
|
|
|
+
|
|
|
+ if (scoreRoll != null)
|
|
|
+ {
|
|
|
+ scoreRoll.AddValue(amount);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 游戏逻辑示例
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 模拟老虎机获胜时的数字动画序列
|
|
|
+ /// </summary>
|
|
|
+ public void SimulateSlotWin(long winAmount)
|
|
|
+ {
|
|
|
+ // 1. 显示中奖金额
|
|
|
+ if (winAmountRoll != null)
|
|
|
+ {
|
|
|
+ winAmountRoll.SetValue(0);
|
|
|
+ winAmountRoll.RollToValue(winAmount, 2f);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 延迟后更新分数和余额
|
|
|
+ StartCoroutine(UpdateScoreAndBalanceCoroutine(winAmount));
|
|
|
+ }
|
|
|
+
|
|
|
+ private System.Collections.IEnumerator UpdateScoreAndBalanceCoroutine(long winAmount)
|
|
|
+ {
|
|
|
+ // 等待中奖金额动画完成
|
|
|
+ yield return new WaitForSeconds(2.5f);
|
|
|
+
|
|
|
+ // 同时更新分数和余额
|
|
|
+ if (scoreRoll != null)
|
|
|
+ scoreRoll.AddValue(winAmount, 1.5f);
|
|
|
+
|
|
|
+ if (balanceRoll != null)
|
|
|
+ balanceRoll.AddValue(winAmount, 1.5f);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 模拟奖池增长
|
|
|
+ /// </summary>
|
|
|
+ public void SimulateJackpotGrowth()
|
|
|
+ {
|
|
|
+ if (jackpotRoll != null)
|
|
|
+ {
|
|
|
+ // 随机增加奖池金额
|
|
|
+ long randomIncrease = Random.Range(1000, 10000);
|
|
|
+ jackpotRoll.AddValue(randomIncrease, 0.5f);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 模拟大奖级别检测和处理
|
|
|
+ /// </summary>
|
|
|
+ public void SimulateLargeWinDetection(long winAmount)
|
|
|
+ {
|
|
|
+ string winLevel = GetWinLevelDescription(winAmount);
|
|
|
+ Debug.Log($"Win detected: {winAmount:N0} - {winLevel}");
|
|
|
+
|
|
|
+ // 根据奖金大小选择不同的显示组件
|
|
|
+ if (winAmount >= 1000000000000) // 1亿以上用翻页显示
|
|
|
+ {
|
|
|
+ if (ultraWinFlip != null)
|
|
|
+ {
|
|
|
+ ultraWinFlip.SpinToValue(winAmount);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (winAmount >= 100000000000) // 1千万以上用翻页显示
|
|
|
+ {
|
|
|
+ if (megaJackpotFlip != null)
|
|
|
+ {
|
|
|
+ megaJackpotFlip.SpinToValue(winAmount);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else // 普通奖金用滚动显示
|
|
|
+ {
|
|
|
+ if (winAmountRoll != null)
|
|
|
+ {
|
|
|
+ winAmountRoll.RollToValue(winAmount);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private string GetWinLevelDescription(long amount)
|
|
|
+ {
|
|
|
+ if (amount >= 1000000000000) return "ULTIMATE JACKPOT! 💎";
|
|
|
+ if (amount >= 100000000000) return "MEGA JACKPOT! 🏆";
|
|
|
+ if (amount >= 10000000000) return "SUPER JACKPOT! 🎊";
|
|
|
+ if (amount >= 1000000000) return "BIG JACKPOT! 🎉";
|
|
|
+ if (amount >= 100000000) return "Large Win! 💰";
|
|
|
+ if (amount >= 10000000) return "Good Win! 🎯";
|
|
|
+ return "Small Win";
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 事件回调
|
|
|
+
|
|
|
+ private void OnWinRollComplete(long finalValue)
|
|
|
+ {
|
|
|
+ Debug.Log($"Win amount animation completed: {finalValue:N0}");
|
|
|
+
|
|
|
+ // 可以在这里触发其他效果,比如粒子特效、音效等
|
|
|
+ // Trigger other effects like particles, sounds, etc.
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnUltraWinComplete(long finalValue)
|
|
|
+ {
|
|
|
+ Debug.Log($"🌟 ULTRA WIN COMPLETED: {finalValue:N0} 🌟");
|
|
|
+
|
|
|
+ // 超级大奖完成后的特殊处理
|
|
|
+ ShowUltraWinCelebration();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void ShowUltraWinCelebration()
|
|
|
+ {
|
|
|
+ // 这里可以触发最华丽的庆祝效果
|
|
|
+ Debug.Log("🎆🎆🎆 ULTIMATE CELEBRATION! 🎆🎆🎆");
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 公共接口
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 设置分数
|
|
|
+ /// </summary>
|
|
|
+ public void SetScore(long score)
|
|
|
+ {
|
|
|
+ if (scoreRoll != null)
|
|
|
+ scoreRoll.SetValue(score);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 增加分数
|
|
|
+ /// </summary>
|
|
|
+ public void AddScore(long amount)
|
|
|
+ {
|
|
|
+ if (scoreRoll != null)
|
|
|
+ scoreRoll.AddValue(amount);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 设置余额
|
|
|
+ /// </summary>
|
|
|
+ public void SetBalance(long balance)
|
|
|
+ {
|
|
|
+ if (balanceRoll != null)
|
|
|
+ balanceRoll.SetValue(balance);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 更新余额
|
|
|
+ /// </summary>
|
|
|
+ public void UpdateBalance(long newBalance)
|
|
|
+ {
|
|
|
+ if (balanceRoll != null)
|
|
|
+ balanceRoll.RollToValue(newBalance);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 显示大奖动画
|
|
|
+ /// </summary>
|
|
|
+ public void ShowJackpotWin(long jackpotAmount)
|
|
|
+ {
|
|
|
+ if (winAmountRoll != null)
|
|
|
+ {
|
|
|
+ winAmountRoll.SetValue(0);
|
|
|
+ winAmountRoll.RollToValue(jackpotAmount, 5f); // 大奖用更长时间
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 测试所有大数字效果
|
|
|
+ /// </summary>
|
|
|
+ public void TestAllLargeNumberEffects()
|
|
|
+ {
|
|
|
+ StartCoroutine(TestSequence());
|
|
|
+ }
|
|
|
+
|
|
|
+ private System.Collections.IEnumerator TestSequence()
|
|
|
+ {
|
|
|
+ Debug.Log("开始大数字测试序列...");
|
|
|
+
|
|
|
+ // 测试1: 大奖 (5千万)
|
|
|
+ OnLargeWin();
|
|
|
+ yield return new WaitForSeconds(6f);
|
|
|
+
|
|
|
+ // 测试2: 超级大奖 (5亿)
|
|
|
+ OnMegaJackpot();
|
|
|
+ yield return new WaitForSeconds(8f);
|
|
|
+
|
|
|
+ // 测试3: 终极大奖 (接近万亿)
|
|
|
+ OnUltraWin();
|
|
|
+ yield return new WaitForSeconds(10f);
|
|
|
+
|
|
|
+ Debug.Log("大数字测试序列完成!");
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 调试方法
|
|
|
+
|
|
|
+ [ContextMenu("Test Slot Win")]
|
|
|
+ private void TestSlotWin()
|
|
|
+ {
|
|
|
+ SimulateSlotWin(15000);
|
|
|
+ }
|
|
|
+
|
|
|
+ [ContextMenu("Test Jackpot Growth")]
|
|
|
+ private void TestJackpotGrowth()
|
|
|
+ {
|
|
|
+ SimulateJackpotGrowth();
|
|
|
+ }
|
|
|
+
|
|
|
+ [ContextMenu("Test Big Win")]
|
|
|
+ private void TestBigWin()
|
|
|
+ {
|
|
|
+ ShowJackpotWin(500000);
|
|
|
+ }
|
|
|
+
|
|
|
+ [ContextMenu("Test Large Win Detection")]
|
|
|
+ private void TestLargeWinDetection()
|
|
|
+ {
|
|
|
+ SimulateLargeWinDetection(50000000); // 5千万
|
|
|
+ }
|
|
|
+
|
|
|
+ [ContextMenu("Test All Large Number Effects")]
|
|
|
+ private void TestAllEffects()
|
|
|
+ {
|
|
|
+ TestAllLargeNumberEffects();
|
|
|
+ }
|
|
|
+
|
|
|
+ [ContextMenu("Demo Ultra Jackpot")]
|
|
|
+ private void DemoUltraJackpot()
|
|
|
+ {
|
|
|
+ SimulateLargeWinDetection(999999999999); // 接近万亿
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|