Unity移动平台跟随问题:玩家无法随移动平台同步移动
解决Unity玩家随移动平台同步移动的问题
问题根源分析
- 平台速度未乘以
Time.deltaTime,导致移动量计算错误 OnTriggerStay的调用时机与玩家自身移动的Update执行顺序冲突,平台移动被覆盖- 依赖
Rigidbody.velocity获取平台速度的方式兼容性差(不适用于直接修改Transform移动的平台)
解决方案及代码修改
1. 修改PlayerMovement脚本,添加平台速度叠加逻辑
新增平台速度变量,将其与玩家自身移动合并执行,避免移动指令被覆盖:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; public class PlayerMovement : MonoBehaviour { [SerializeField] private float walkSpeed = 4.0f; [SerializeField] private float jumpHeight = 2.0f; [SerializeField] private float gravity = -9.81f; [SerializeField] private float rotationSpeed = 5.0f; private CharacterController characterController; private PlayerInput playerInput; private Transform cameraTransform; private InputAction moveAction; private InputAction jumpAction; private Vector3 playerVelocity; private bool isGrounded; private Vector3 platformVelocity; // 新增:存储平台速度 private void Awake() { characterController = GetComponent<CharacterController>(); playerInput = GetComponent<PlayerInput>(); cameraTransform = Camera.main.transform; moveAction = playerInput.actions["Walk"]; jumpAction = playerInput.actions["Jump"]; Cursor.lockState = CursorLockMode.Locked; } private void Update() { isGrounded = characterController.isGrounded; if (isGrounded && playerVelocity.y < 0) { playerVelocity.y = -5.0f; gravity = -9.81f; } Vector2 input = moveAction.ReadValue<Vector2>(); Vector3 move = new Vector3(input.x, 0f, input.y); Vector3 cameraForwardDirection = new Vector3(Camera.main.transform.forward.x, 0, Camera.main.transform.forward.z); Vector3 cameraRightDirection = new Vector3(Camera.main.transform.right.x, 0, Camera.main.transform.right.z); move = cameraForwardDirection * move.z + cameraRightDirection * move.x; // 合并玩家移动与平台移动,统一执行 characterController.Move((move * walkSpeed + platformVelocity) * Time.deltaTime); if (jumpAction.triggered && isGrounded) { playerVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravity); } playerVelocity.y += gravity * Time.deltaTime; characterController.Move(playerVelocity * Time.deltaTime); float targetAngle = cameraTransform.eulerAngles.y; Quaternion targetRotation = Quaternion.Euler(0, targetAngle, 0); transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime); // 每帧重置平台速度,避免持续叠加 platformVelocity = Vector3.zero; } // 替换原PlatformMovement方法,改为设置平台速度 public void SetPlatformVelocity(Vector3 velocity) { platformVelocity = velocity; } }
2. 修改PlatformStick脚本,改用碰撞检测并兼容多种平台移动方式
放弃Trigger改用CollisionStay,通过帧位置差计算平台速度,兼容Rigidbody和Transform驱动的平台:
using UnityEngine; public class PlatformStick : MonoBehaviour { private Vector3 lastFramePosition; private void Start() { lastFramePosition = transform.position; } private void OnCollisionStay(Collision collision) { if (collision.gameObject.CompareTag("Player")) { PlayerMovement playerMovement = collision.gameObject.GetComponent<PlayerMovement>(); if (playerMovement == null) return; // 计算平台当前帧的移动速度 Vector3 positionDelta = transform.position - lastFramePosition; Vector3 platformSpeed = positionDelta / Time.deltaTime; playerMovement.SetPlatformVelocity(platformSpeed); lastFramePosition = transform.position; } } }
关键配置说明
- 移动平台的Collider不要勾选Is Trigger,确保与玩家的CharacterController能触发碰撞检测
- 如果平台使用Rigidbody,需设置为
Kinematic,避免被玩家推动同时保留移动能力
内容的提问来源于stack exchange,提问作者Siyun Cho
相关产品推荐
相关产品推荐

