如何消除使用AddForce方法(Unity)跳跃后速度下降的问题?

问题描述 投票:0回答:2

我开始制作我的游戏,但遇到了移动问题。我的动作是基于新的输入系统和

.AddForce()
。问题是,当我跳跃时,角色的速度在落地后下降,然后又开始加速。

动态摩擦力为 2 的物理材质挂在玩家的胶囊碰撞器上(如果它影响问题)

如何让角色移动时不减速?


视频演示(希望你能看出问题所在)。 Rigidbody and Player Mover settings


代码(没有更多关联代码):

    using System;
    using UnityEngine;
    
    [RequireComponent(typeof(Rigidbody))]
    [RequireComponent(typeof(CapsuleCollider))]
    public class PlayerMover : MonoBehaviour
    {
        [SerializeField] private LayerMask _groundLayer = 6;
        [SerializeField] private float _moveForce;
        [SerializeField] private float _maxForce;
        [SerializeField] private float _jumpForce;
        [SerializeField] private float _mouseSensitivity;
    
        private PlayerInput _input;
        private Rigidbody _rb;
        private CapsuleCollider _collider;
        private Camera _camera;
        private float _rotationX;
        private const float MinAngle = -90f;
        private const float MaxAngle = 90f;
    
        private void Awake()
        {
            _input = new PlayerInput();
            _rb = GetComponent<Rigidbody>();
            _collider = GetComponent<CapsuleCollider>();
            _camera = GetComponentInChildren<Camera>();
    
            _rb.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationZ;
    
            if (_groundLayer == gameObject.layer)
            {
                Debug.LogError("Сортувальний рівень гравця повинен відрізнятися від сортувального рівня землі!");
            }
    
            _input.Player.Jump.performed += context => Jump();
        }
    
        private void OnEnable()
        {
            _input.Enable();
        }
    
        private void OnDisable()
        {
            _input.Disable();
        }
    
        private void FixedUpdate()
        {
            Move();
        }
    
        private void LateUpdate()
        {
            Look();
        }
    
        private bool IsGrounded
        {
            get
            {
                var bottomCenterPoint = new Vector3(_collider.bounds.center.x, _collider.bounds.center.y,
                    _collider.bounds.center.z);
    
                return Physics.CheckCapsule(_collider.bounds.center, bottomCenterPoint, _collider.bounds.size.x * 1.1f,
                    _groundLayer);
            }
        }
    
        private Vector3 MovementVector
        {
            get
            {
                var cameraDirectionF = _camera.transform.forward;
                var cameraDirectionR = _camera.transform.right;
    
                cameraDirectionF.y = 0;
                cameraDirectionR.y = 0;
                cameraDirectionF = cameraDirectionF.normalized;
                cameraDirectionR = cameraDirectionR.normalized;
    
                var direction = _input.Player.Move.ReadValue<Vector2>();
    
                return cameraDirectionF * direction.y + cameraDirectionR * direction.x;
            }
        }
    
        private Vector2 MouseVector => _input.Player.Look.ReadValue<Vector2>() * _mouseSensitivity * Time.deltaTime;
    
        private void Jump()
        {
            if (IsGrounded == false) return;
            _rb.AddForce(new Vector3(0, _jumpForce, 0), ForceMode.Impulse);
        }
    
        private void Move()
        {
            _rb.AddForce(MovementVector * _moveForce, ForceMode.Impulse);
    
            if (Math.Sqrt(Math.Pow(_rb.velocity.x, 2) + Math.Pow(_rb.velocity.z, 2)) < _maxForce) return;
    
            var maxVelocity = _rb.velocity.normalized * _maxForce;
            _rb.velocity = new Vector3(maxVelocity.x, _rb.velocity.y, maxVelocity.z);
        }
    
        private void Look()
        {
            _rotationX -= MouseVector.y;
            _rotationX = Math.Clamp(_rotationX, MinAngle, MaxAngle);
            _camera.transform.localEulerAngles = new Vector3(_rotationX, MouseVector.y, 0);
    
            transform.Rotate(Vector3.up * MouseVector.x);
        }
    }

我尝试更改

.AddForce()
.Move()
方法中不同的
.Jump()
值。更改了
Vector3
方法中将
_rb.velocity
分配给
.Move()
时的值,其中检查了最大允许速度(没有此检查,
.AddForce()
将不断增加移动速度)。

我还以为问题出在

MovementVector
属性上,但事实并非如此,它给出了正确的值。

(以下说法很可能是错误的)

我认为,跳跃后,在跳跃的最低点(几乎接近地面),角色垂直落下,从而速度完全消失,所以需要重新恢复。


编辑:我刚刚修改了代码以查看控制台中的最低速度值。添加了以下内容:两个变量和

.Update()
,一个检查
MovementVector
属性,并更改
_flag
方法中的
.Jump()

private bool _flag;
private double _min = double.MaxValue;

private void Update()
{
    if (!_flag) return;
    var current = Math.Sqrt(Math.Pow(_rb.velocity.x, 2) + Math.Pow(_rb.velocity.z, 2));
    if (current < _min) _min = current;
    Debug.Log(_min);
}

private Vector3 MovementVector
{
    get
    {
        ....

        var direction = _input.Player.Move.ReadValue<Vector2>();

        if (direction.magnitude == 0)
        {
            _flag = false;
        }

        return cameraDirectionF * direction.y + cameraDirectionR * direction.x;
    }
}

private void Jump()
{
    _flag = true;
    if (IsGrounded == false) return;
    //_rb.AddForce(new Vector3(0, _jumpForce, 0), ForceMode.Impulse);
    _rb.AddForce(transform.up * _jumpForce, ForceMode.Impulse);
}

现在,在着陆时,我将获得准确的速度值。由此,我注意到一些事情,当将 _maxForce 更改为更高的一侧时,着陆速度也会发生变化。如果 _maxForce 等于 5,则速度降至零,如果 _maxForce 等于 10,则速度已降至 4,如果 _maxForce 等于 15 - 到 9。

c# unity-game-engine game-physics game-development
2个回答
0
投票

在 Jump() 方法中,您添加 (0,_jumpforce,0) 的力,以便将当前运动归零。你应该用向量方向乘以jumpForce来addforce而不是零 示例:

_rb.AddForce(transform.up * _jumpForce, ForceMode.Impulse);

我希望这个修复能够按照您的要求正常工作。


0
投票

1年零3个月后。 我希望你花了这么长时间解决了问题并且没有放弃。 但我在我的项目中遇到了同样的问题,认为问题出在我的代码中或者是 Unity 物理中不可控的东西,但相信,它在物理中,但它是可控的。 我刚刚更改了下图中的参数

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.