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

Unity中CharacterController角色随移动平台同步移动的实现问题

实现Character Controller角色随移动平台同步移动的正确方案

我通过Character Controller组件实现了角色移动,现在需要添加移动平台功能,让角色跳上平台后能随平台一起移动。尝试过两种方法都失败了:

  • 将玩家设为移动平台的子物体:无效,推测是因为Character Controller的位置会在Update方法中被主动修改,覆盖了父物体的位置影响
  • 直接把平台速度加到Character Controller计算出的速度中:角色移动速度会快于平台,搞不清计算逻辑问题出在哪

核心解决思路

关键要区分角色相对平台的移动速度和平台自身的绝对速度,角色的最终绝对速度应该是这两者的叠加。同时要准确检测角色是否站在平台上,并实时计算平台的移动速度。

具体实现步骤

  1. 在角色脚本中添加变量,记录当前所在平台及平台的位置信息:
private Transform _currentPlatform;
private Vector3 _platformLastPosition;
private Vector3 _platformVelocity;
  1. 修改地面检测方法(GroundedCheck),检测角色是否站在移动平台上并记录平台:
private void GroundedCheck()
{
    // 保留你原有的地面检测逻辑(比如基于CharacterController.isGrounded)
    if (_controller.isGrounded)
    {
        // 向下发射射线检测脚下的平台
        RaycastHit hit;
        if (Physics.Raycast(transform.position, Vector3.down, out hit, _controller.height / 2 + 0.1f))
        {
            // 通过标签判断是否为移动平台(你可以根据实际情况调整判断条件)
            if (hit.transform.CompareTag("MovingPlatform"))
            {
                _currentPlatform = hit.transform;
                _platformLastPosition = _currentPlatform.position;
            }
            else
            {
                _currentPlatform = null;
            }
        }
        else
        {
            _currentPlatform = null;
        }
    }
    else
    {
        _currentPlatform = null;
    }
}
  1. 在Update方法中计算平台的实时速度,并调整最终移动速度:
private void Update()
{
    GravityControl();
    GroundedCheck();

    // 计算平台当前速度(每帧位置变化除以时间差)
    if (_currentPlatform != null)
    {
        _platformVelocity = (_currentPlatform.position - _platformLastPosition) / Time.deltaTime;
        _platformLastPosition = _currentPlatform.position;
    }
    else
    {
        _platformVelocity = Vector3.zero;
    }

    // 保留原有的超时重置逻辑
    if (_timeoutToResetVars <= 0)
    {
        _speed = 0;
        _animationBlend = 0;
        _animator.SetFloat(_animIDSpeed, 0);
        _timeoutToResetVars = 0;
    }
    else
        _timeoutToResetVars -= Time.deltaTime;

    if (_useRootMotion)
        return;

    if (!_controller.enabled) return;

    // 最终移动速度 = 角色相对平台的速度 + 平台自身的绝对速度
    Vector3 finalVelocity = _velocity + _platformVelocity;
    _controller.Move(finalVelocity * Time.deltaTime);
}
  1. 无需修改Move方法的现有逻辑:Move方法中计算的_velocity代表角色相对于平台的移动速度,后续叠加平台速度即可得到绝对速度,这样就不会出现重复叠加的问题。

为什么之前的方法无效?

  • 子物体方案失效:CharacterController.Move()是直接修改角色的世界空间位置,会覆盖父物体(平台)带来的位置偏移,因此子物体方式不适用。
  • 直接叠加速度出错:之前的currentHorizontalSpeed取的是角色的绝对速度大小,已经包含了平台的速度,导致计算出的_speed会重复叠加平台速度,最终角色速度=角色相对速度+平台速度+平台速度,自然比平台快。

内容的提问来源于stack exchange,提问作者Mansur Nashaev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 08:02:13