Unity桌游玩家掷骰移动功能失效,求技术解决方案
排查思路与解决建议
一、核心问题排查步骤
- 按钮绑定验证:检查按钮的
On Click()事件是否正确挂载了脚本实例的OnRollButtonPressed方法,确保脚本所在GameObject未被禁用,BoardGamePiece_Blue和rollResultText已在Inspector面板正确赋值。 - Rigidbody组件冲突:玩家对象挂载Rigidbody后,直接修改
transform.position会和物理引擎冲突,导致移动失效或异常。 - Update方法逻辑混乱:当前Update里调用
MovePlayerByRollNumber后,立刻修改脚本所在对象而非玩家对象的位置,且仅执行一帧,完全不符合逐步移动的逻辑。 - 无效代码冗余:
MovePlayer方法仅更新currentPosition变量,但未关联实际玩家位置更新,属于无效代码。
二、具体修复建议
- 处理Rigidbody冲突:若保留Rigidbody,改用
Rigidbody.MovePosition更新位置;若无需物理交互,直接移除Rigidbody组件。 - 重构移动逻辑:使用协程实现平滑移动到目标格子,替代瞬间位移或单帧移动。
- 清理冗余代码:移除Update中对脚本所在对象位置的修改,专注处理玩家移动触发逻辑。
- 利用棋盘格子数组:通过预设的
spaces数组(棋盘格子的Transform),让玩家直接移动到对应格子位置,避免方向位移误差。
三、修复后的完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class MovePlayerOnButtonPress : MonoBehaviour { public GameObject BoardGamePiece_Blue; // 赋值玩家对象 public Text rollResultText; // 赋值掷骰结果UI文本 public Transform[] spaces; // 按棋盘顺序赋值所有格子的Transform public float moveSpeed = 5.0f; // 移动速度 private int currentPosition = 0; private bool isMoving = false; // 标记移动状态,防止重复触发 public void OnRollButtonPressed() { // 移动中不响应新掷骰请求 if (isMoving) return; int rollNumber = Random.Range(1, 7); // 生成1-6的随机数 rollResultText.text = rollNumber.ToString(); // 计算目标位置,超出棋盘则循环(可根据需求修改规则) int targetPosition = (currentPosition + rollNumber) % spaces.Length; StartCoroutine(MovePlayerToTarget(targetPosition)); } private IEnumerator MovePlayerToTarget(int targetIndex) { isMoving = true; Transform targetTransform = spaces[targetIndex]; Vector3 startPos = BoardGamePiece_Blue.transform.position; float journeyLength = Vector3.Distance(startPos, targetTransform.position); float traveled = 0; // 平滑插值移动到目标格子 while (traveled < journeyLength) { traveled += moveSpeed * Time.deltaTime; float moveProgress = traveled / journeyLength; BoardGamePiece_Blue.transform.position = Vector3.Lerp(startPos, targetTransform.position, moveProgress); yield return null; } // 强制对齐到目标格子位置,避免插值误差 BoardGamePiece_Blue.transform.position = targetTransform.position; currentPosition = targetIndex; isMoving = false; } }
四、额外注意事项
- 确保
spaces数组在Inspector中按棋盘顺序赋值,玩家会严格按数组索引顺序移动。 - 若玩家需要物理碰撞,将协程中修改
transform.position的代码替换为:BoardGamePiece_Blue.GetComponent<Rigidbody>().MovePosition(目标位置)。 - 测试时打开Unity Scene视图,观察玩家移动路径是否对齐格子,若偏移检查格子的Transform坐标是否正确。
内容的提问来源于stack exchange,提问作者Sonya Ruje
相关产品推荐
相关产品推荐

