当玩家 运行 时如何使跳跃更快?

How to make jump faster when player is running?

我有一个角色控制器动作,玩家可以在其中行走、运行 和跳跃。但是,我面临着跳跃的问题。边走边跳的时候,跳跃速度看起来不错。但是在运行ning的时候跳跃,相对于运行的速度来说跳跃速度太慢了。我该如何解决这个问题?

这是我的代码:

public class PlayerMovement : MonoBehaviour
{
    [SerializeField] Transform playerCamera = null;
    [SerializeField] float mouseSensitivity = 3.5f;
    [SerializeField] float walkSpeed = 10.0f;
    [SerializeField] float RunSpeed = 12.0f;
    [SerializeField] float gravity = 9.81f;
    [SerializeField] bool lockCursor = true;
    [SerializeField] [Range(0.0f, 0.5f)] float moveSmoothTime = 0.3f;
    public float jumpHeight = 3f;

    Vector3 velocity;
    public float verticalVelocity;
    float cameraPitch = 0.0f;

    CharacterController controller = null;
    Vector2 currentDir = Vector2.zero;
    Vector2 currentDirVelocity = Vector2.zero;
    Vector2 currentMouseDelta = Vector2.zero;
    Vector2 currentMouseDeltaVelocity = Vector2.zero;

    void Start()
    {
        controller = GetComponent<CharacterController>();
        if (lockCursor)
        {
            Cursor.lockState = CursorLockMode.Locked;
            Cursor.visible = false;
        }
    }
    void Update()
    {
        UpdateMouseLook();
        UpdateMovement();
    }
    void UpdateMouseLook()
    {
        Vector2 targetMouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));

        currentMouseDelta = Vector2.SmoothDamp(currentMouseDelta, targetMouseDelta, ref currentMouseDeltaVelocity, mouseSmoothTime);

        cameraPitch -= currentMouseDelta.y * mouseSensitivity;

        cameraPitch = Mathf.Clamp(cameraPitch, -90.0f, 90.0f);

        playerCamera.localEulerAngles = Vector3.right * cameraPitch;

        transform.Rotate(Vector3.up * currentMouseDelta.x * mouseSensitivity);
    }
    void UpdateMovement()
    {
        Vector2 targetDir = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
        targetDir.Normalize();

        currentDir = Vector2.SmoothDamp(currentDir, targetDir, ref currentDirVelocity, moveSmoothTime);

        if (controller.isGrounded)
            velocity.y = 0.0f;
        velocity += (velocity.y < 0 ? Physics.gravity * 2 : Physics.gravity) * Time.deltaTime;

        velocity = (transform.forward * currentDir.y + transform.right * currentDir.x) * walkSpeed + Vector3.up * velocity.y;
          if (Input.GetKeyDown(KeyCode.J) && controller.isGrounded)
        {
           velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
           velocity += (velocity.y < 0 ? Physics.gravity * 2 : Physics.gravity) * Time.deltaTime;
        }
        controller.Move(velocity * Time.deltaTime);
        if ((Input.GetKey("left shift") || Input.GetKey("right shift")) && controller.isGrounded && !Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.DownArrow))
        {
            velocity = (transform.forward * currentDir.y + transform.right * currentDir.x) * RunSpeed + Vector3.up * velocity.y;
            controller.Move(velocity * Time.deltaTime);
        }

      
    

}

当您使用角色控制器时,您需要针对所有情况进行所有计算。 要获得您正在寻找的结果,您可以在跳跃和步行速度之间进行计算。

另一种方法是使用刚体(锁定旋转)并为跳跃和移动添加力。

这里的两个例子:https://www.youtube.com/watch?v=b1uoLBp2I1w

我优化了上面的代码并删除了一些重复的。我还注意到速度问题是由于 运行 条件的主体中存在 isGrounded,这使得 运行 依赖于在地面上。这是播放器脚本:

   public class Player : MonoBehaviour
    {
        [SerializeField] Transform playerCamera = null;
        [SerializeField] float mouseSensitivity = 3.5f;
        [SerializeField] float walkSpeed = 10.0f;
        [SerializeField] float runSpeed = 12.0f;
        [SerializeField] float gravity = 9.81f;
        [SerializeField] bool lockCursor = true;
        [SerializeField] [Range(0.0f, 0.5f)] float moveSmoothTime = 0.3f;
        public float jumpHeight = 3f;
    
        Vector3 velocity;
        private float verticalVelocity;

        private Vector3 inputVector;
        float cameraPitch = 0.0f;
    
        CharacterController controller = null;
        Vector2 currentDir = Vector2.zero;
        Vector3 currentDirVelocity = Vector3.zero;
        Vector2 currentMouseDelta = Vector2.zero;
        Vector2 currentMouseDeltaVelocity = Vector2.zero;

        void Start()
        {
            controller = GetComponent<CharacterController>();
            
            if (lockCursor)
            {
                Cursor.lockState = CursorLockMode.Locked;
                Cursor.visible = false;
            }
        }
        void Update()
        {
            UpdateMouseLook();
            UpdateMovement();
        }
        void UpdateMouseLook()
        {
            var targetMouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
    
            currentMouseDelta = Vector2.SmoothDamp(currentMouseDelta, targetMouseDelta, ref currentMouseDeltaVelocity, moveSmoothTime);
    
            cameraPitch -= currentMouseDelta.y * mouseSensitivity;
    
            cameraPitch = Mathf.Clamp(cameraPitch, -90.0f, 90.0f);
    
            playerCamera.localEulerAngles = Vector3.right * cameraPitch;
    
            transform.Rotate(Vector3.up * currentMouseDelta.x * mouseSensitivity);
        }

        void UpdateMovement()
        {
            // jumping
            var isGrounded = Physics.Raycast(transform.position, Vector3.down, 1.1f) && velocity.y <= 0;

            if (isGrounded) 
            {
                velocity.y = Input.GetKeyDown(KeyCode.Space) ? Mathf.Sqrt(jumpHeight) : 0f;
            }
            else
            {
                velocity += (velocity.y < 0 ? Physics.gravity * 2 : Physics.gravity) * Time.deltaTime;
            }
            
            controller.Move(velocity);
            
            // movement
            inputVector = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical")).normalized;

            var smoothDamp = Vector3.SmoothDamp(inputVector, inputVector, ref currentDirVelocity, moveSmoothTime);

            var runKey = (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) &&
                         !Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.DownArrow);

            controller.Move(smoothDamp * (runKey ? runSpeed : walkSpeed) * Time.deltaTime);
        }
    }

此外,这些设置适用于高度为 2 的胶囊:

如果你的字符大于2,相应地调整地面检测的长度raycast,因为controller.isGrounded条件并不总是有效。