Unity角色控制器尝试实现平稳的移动和跳跃

时间:2019-06-08 12:40:47

标签: visual-studio unity3d game-physics platform

当玩家跌倒在地时,相机会晃动,而当他跳跃时,他会以不平稳的方式被传送起来

public class PlayerController : MonoBehaviour {

    CharacterController controller;
    Vector3 motion = Vector3.zero;

    #region Movement Variables
    public float walkingSpeed = 4f;
    public float runningSpeed = 6f;
    public float jumpSpeed = 5f;
    public float gravity = 9.8f;
    #endregion Movement Variables

    void Start () {
        controller = GetComponent<CharacterController>();
    }

    void Update () {
        motion = Vector3.zero;

        motion.x = Input.GetAxis("Horizontal");
        if (controller.isGrounded && Input.GetAxis("Vertical")>0) motion.y += jumpSpeed;
        if (Input.GetKey(KeyCode.LeftShift))
        {
            motion.x *= runningSpeed;
        }
        else
        {
            motion.x *= walkingSpeed;
        }
        motion.y -= gravity;
    }

    void FixedUpdate()
    {
        controller.Move(motion * Time.deltaTime);
    }
}

Character Controller Settings

我正在尝试创建平滑的运动,目前根本不可靠。谢谢你的帮忙

1 个答案:

答案 0 :(得分:0)

controller.Move(motion * Time.deltaTime);从FixedUpdate中取出,并将其放在Update方法的最后。

如果在摄像机上也有一些脚本,例如,在更新循环中要使用该摄像机的转换组件的跟随摄像机的某些实现,则应改为在LateUpdate中使用。

查看此https://learn.unity.com/tutorial/update-and-fixedupdate#5c8a4242edbc2a001f47cd63https://docs.unity3d.com/ScriptReference/MonoBehaviour.LateUpdate.html

这种具有角色控制器组件的GameObject玩家控制器的实现也可能会为您提供帮助。

void Update()
    {
        if (isDead) return;

        isWalking = Input.GetButton("Walk");
        isGrounded = characterController.isGrounded;

        if (isGrounded)
        {
            // Move
            float verticalAxis = Input.GetAxis("Vertical");

            moveDirection = new Vector3(0, 0, verticalAxis);
            moveDirection = transform.TransformDirection(moveDirection);

            if (verticalAxis > 0 && isWalking)
            {
                moveDirection *= walkingSpeed;
            }
            else if (verticalAxis > 0)
            {
                moveDirection *= runningSpeed;
            }

            // Jump
            if (Input.GetButtonDown("Jump"))
            {
                moveDirection.y = jumpSpeed;
                //moveDirection.z = jumpDistance; in case some forward boost is required
                moveDirection = transform.TransformDirection(moveDirection);
            }
        }
        // Gravity
        moveDirection.y -= gravity * Time.deltaTime;
        characterController.Move(moveDirection * Time.deltaTime);

        // Rotation
        float horizontalAxis = Input.GetAxis("Horizontal");
        transform.Rotate(0, horizontalAxis, 0);
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.FromToRotation(transform.up, GetHitNormal()) * transform.rotation, yRotationSpeed * Time.deltaTime);
    }

// To keep local up aligned with global up on a slope ground
    private Vector3 GetHitNormal()
    {
        RaycastHit hit;
        if (Physics.Raycast(transform.position, Vector3.down, out hit))
            return hit.normal;
        else
            return Vector3.zero;
    }