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

Rigidbody玩家控制器在移动平台变向时滑动问题求助

玩家Rigidbody控制器随移动平台快速转向时滑动的问题

我基于Rigidbody实现了基础玩家控制器和移动平台脚本,玩家站在平台上可以随平台移动,但当平台快速改变运动方向时,玩家会向平台之前的运动方向滑动数帧。我希望无论平台速度如何变化,玩家都能保持在平台的同一位置。目前已给碰撞体应用了无摩擦的Physics Material,但当平台速度超过一定值后,滑动问题仍然存在。

备注:不使用CharacterController的原因是它存在无法让玩家绕X、Z轴旋转的缺陷,我计划后续添加重力井功能。

玩家控制器代码

using System;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
    private Rigidbody _rigidbody;
    private CapsuleCollider _capsule;

    private RaycastHit _ground;

    private bool _isGrounded = false;
    private Vector3 _direction = Vector3.zero;

    private Vector3 _velocity = Vector3.zero;
    private Vector3 _gravity = Vector3.zero;
    private Vector3 _platform = Vector3.zero;
    private Vector3 _lastPlatformVelocity = Vector3.zero;

    void Start()
    {
        _capsule = GetComponent<CapsuleCollider>();
        _rigidbody = GetComponent<Rigidbody>();
        _rigidbody.constraints = RigidbodyConstraints.FreezeRotation;
    }

    public void OnMove(InputAction.CallbackContext context)
    {
        var value = context.ReadValue<Vector2>();
        _direction.x = value.x;
        _direction.z = value.y;
    }

    public void OnJump(InputAction.CallbackContext context)
    {
        if (_isGrounded && context.performed)
        {
            _velocity.y = 10f;
        }
    }

    private void FixedUpdate()
    {
        _isGrounded = CheckGrounded();

        Gravity();
        Platform();
        Movement();


        _rigidbody.linearVelocity = _velocity + _platform;
    }


    private void Platform()
    {

        if (_isGrounded && _ground.rigidbody != null)
        {
            _platform = _ground.rigidbody.GetPointVelocity(_ground.point);
            // Shift _velocity into the new platform's reference frame.
            // This handles both landing AND mid-platform direction changes.
            _velocity -= Vector3.ProjectOnPlane(_platform - _lastPlatformVelocity, Vector3.up); ;
        }
        else
        {
            // Leaving the platform — eject any stored platform velocity into _velocity
            // so the player carries their momentum through the air correctly.
            _velocity += _lastPlatformVelocity;
            _platform = Vector3.zero;
        }

        _lastPlatformVelocity = _platform;
    }

    private void Movement()
    {
        var acceleration = 15f;
        const float baseSpeed = 10f;

        Vector3 facing = transform.TransformDirection(_direction);
        float verticalVelocity = _velocity.y;

        if (_isGrounded)
        {
            _velocity = Vector3.Lerp(_velocity, facing * baseSpeed, acceleration * Time.deltaTime);
        }
        else
        {
            Vector3 horizontalVelocity = Vector3.ProjectOnPlane(_velocity, Vector3.up);

            // Preserve inertia in air
            float speedCap = Mathf.Max(horizontalVelocity.magnitude, baseSpeed);

            horizontalVelocity += facing * acceleration * Time.deltaTime;

            _velocity = Vector3.ClampMagnitude(horizontalVelocity, speedCap);
        }

        Debug.Log(Vector3.ProjectOnPlane(_velocity, Vector3.up));

        _velocity.y = verticalVelocity;
    }

    private void Gravity()
    {
        if (!_isGrounded)
        {
            _velocity += Physics.gravity * 2f * Time.deltaTime;
        }
    }

    private bool CheckGrounded()
    {
        Vector3 center = transform.TransformPoint(_capsule.center);

        float radius = _capsule.radius * Mathf.Max(transform.lossyScale.x, transform.lossyScale.z);

        return Physics.SphereCast(
            center,
            radius * 0.95f,
            Vector3.down,
            out _ground,
            maxDistance: 0.55f
        );
    }
}

问题代码点

奇怪的是,Platform方法中的这段代码:

_velocity -= Vector3.ProjectOnPlane(_platform - _lastPlatformVelocity, Vector3.up); ;

虽然解决了玩家跳跃时平台速度的应用问题,但会加剧玩家的滑动情况。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 07:34:53