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
相关产品推荐
相关产品推荐

