You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity桌游玩家掷骰移动功能失效,求技术解决方案

排查思路与解决建议

一、核心问题排查步骤

  • 按钮绑定验证:检查按钮的On Click()事件是否正确挂载了脚本实例的OnRollButtonPressed方法,确保脚本所在GameObject未被禁用,BoardGamePiece_Blue和rollResultText已在Inspector面板正确赋值。
  • Rigidbody组件冲突:玩家对象挂载Rigidbody后,直接修改transform.position会和物理引擎冲突,导致移动失效或异常。
  • Update方法逻辑混乱:当前Update里调用MovePlayerByRollNumber后,立刻修改脚本所在对象而非玩家对象的位置,且仅执行一帧,完全不符合逐步移动的逻辑。
  • 无效代码冗余:MovePlayer方法仅更新currentPosition变量,但未关联实际玩家位置更新,属于无效代码。

二、具体修复建议

  1. 处理Rigidbody冲突:若保留Rigidbody,改用Rigidbody.MovePosition更新位置;若无需物理交互,直接移除Rigidbody组件。
  2. 重构移动逻辑:使用协程实现平滑移动到目标格子,替代瞬间位移或单帧移动。
  3. 清理冗余代码:移除Update中对脚本所在对象位置的修改,专注处理玩家移动触发逻辑。
  4. 利用棋盘格子数组:通过预设的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 13:55:25