Unity中如何正确计算骰子停止滚动后的总点数?
问题修复:骰子点数计算错误与旧值累加问题
问题根源
- 重置时机不当:仅在脚本启用时重置计算状态,未在每次掷骰开始时执行重置,导致旧结果残留累加。
- 静止判定不准确:依赖
Rigidbody.IsSleeping()判断骰子是否停止,刚体停止后需延迟才会进入睡眠状态,可能提前触发"全部停止"判定,清空结果列表后丢失后续骰子的点数。 - 结果列表过早清空:在显示结果后立即清空列表,若有延迟触发的骰子停止事件,会导致已记录的点数丢失。
修复方案与代码修改
using System.Collections; using System.Collections.Generic; using UnityEngine; using TMPro; using System.Linq; public class DisplayCurrentDiceValue : MonoBehaviour { [SerializeField] private TextMeshProUGUI _valueText; private int totalDiceValue = 0; private bool isValueDisplayed = false; private List<int> diceResults = new List<int>(); private void OnEnable() { DiceManager.OnStopRolling += AddDiceValue; if (_valueText == null) { _valueText = GetComponentInChildren<TextMeshProUGUI>(); } // 初始重置 ResetRollState(); } private void OnDisable() { DiceManager.OnStopRolling -= AddDiceValue; } // 公开重置方法,在每次掷骰开始时调用(比如由DiceManager触发) public void ResetRollState() { totalDiceValue = 0; diceResults.Clear(); isValueDisplayed = false; // 清空显示文本 if (_valueText != null) { _valueText.text = "0"; } } private void AddDiceValue(int faceValue) { // 仅在未显示结果时添加点数(避免重复添加) if (!isValueDisplayed) { diceResults.Add(faceValue); totalDiceValue = diceResults.Sum(); } // 检查所有骰子是否真的静止 if (IsAllDiceStopped() && !isValueDisplayed) { UpdateValueText(); StartCoroutine(BounceInAnimation()); isValueDisplayed = true; } } private bool IsAllDiceStopped() { GameObject[] diceObjects = GameObject.FindGameObjectsWithTag("Dice"); foreach (GameObject diceObject in diceObjects) { Rigidbody diceRigidbody = diceObject.GetComponent<Rigidbody>(); if (diceRigidbody == null) continue; // 用速度和角速度判断是否静止,比IsSleeping更精准及时 bool isMoving = diceRigidbody.velocity.magnitude > 0.01f || diceRigidbody.angularVelocity.magnitude > 0.01f; if (isMoving) { return false; } } return true; } private void UpdateValueText() { _valueText.text = totalDiceValue.ToString(); } private IEnumerator BounceInAnimation() { // 保留你的动画逻辑 yield return null; } }
关键修改说明
- 新增
ResetRollState方法:在每次掷骰开始时调用该方法,确保所有计算状态(总和、结果列表、显示标记)完全重置,彻底解决旧值累加问题。 - 替换静止判定逻辑:改用刚体的线速度和角速度判断是否静止,避免因睡眠延迟导致的误判。
- 调整结果列表清空时机:仅在重置时清空列表,不再在显示结果后立即清空,确保所有骰子的点数都能被正确记录。
- 添加状态保护:在
AddDiceValue中增加!isValueDisplayed判断,防止重复添加点数。
使用注意
确保在DiceManager的掷骰开始逻辑中,调用 DisplayCurrentDiceValue.ResetRollState() 方法,比如在玩家点击掷骰按钮时触发重置。
内容的提问来源于stack exchange,提问作者Oueza euloge stephane
相关产品推荐
相关产品推荐

