簡體   English   中英

為什么我的 Controller 會隨着 Slerp 漂移?

[英]Why is my Controller drifting with Slerp?

我一直在研究這個 Controller,在那里我走遍了一個小的 pl.net。 我正在使用 Quaternion.Slerp,當我在 pl.net 上的某些點時,controller 緩慢漂移,繞 Y 軸旋轉。 我的想法是它持有一個基於我的起始 position 的值,所以當我移動到不同的點時,Slerp function 試圖將我旋轉到那個位置? 我試過弄亂腳本,將不同的部分移動到他們自己的自定義方法來查明問題,但此時我有點迷茫。 任何幫助,將不勝感激!

我認為問題出在底部的兩個方法 NewRotation 或 RunWalkStand 中。

`

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField] private LayerMask _groundMask;
    [SerializeField] private Transform _groundCheck;
    [SerializeField] private Transform cam;
    
    public float jumpCooldown = 1f;
    public float groundCheckRadius = 0.3f;
    private float speed = 8;
    private float runSpeed = 2;
    private float turnSpeed = 800f;
    private float jumpForce = 500f;

    private Rigidbody rb;
    private Vector3 direction;
    private GravityBody _gravityBody;

    private Animator playerAnimator;
    private GameObject planetRecall;

    void Start()
    {
        _gravityBody = transform.GetComponent<GravityBody>();

        playerAnimator = GetComponent<Animator>();
        planetRecall = GameObject.FindGameObjectWithTag("Planet Recall");
    }

    void Update()
    {
        bool isCloseToGround = Physics.CheckSphere(_groundCheck.position, groundCheckRadius, _groundMask);

        NewRotation();

        if (Input.GetKeyDown(KeyCode.Space) && isCloseToGround)
        {
            Jump();
        }
    }
    
    void FixedUpdate()
    {
        RunWalkStand();
    }

    private void OnCollisionEnter(Collision collision) 
    {
        if(collision.gameObject == planetRecall)
        {
            playerAnimator.SetBool("Grounded", true);
        }
    }

    private void Jump()
    {
        rb.AddForce(-_gravityBody.GravityDirection * jumpForce, ForceMode.Impulse);
        playerAnimator.SetTrigger("Fly_trig");
        playerAnimator.SetBool("Grounded", false);
    }

    private void NewRotation()
    {
        rb = transform.GetComponent<Rigidbody>();
        Vector3 mouseRotationY = new Vector3(0f, Input.GetAxisRaw("Mouse X"), 0f);
        Quaternion rightDirection = Quaternion.Euler(0f,  mouseRotationY.y * (turnSpeed * Time.deltaTime), 0f).normalized;
        Quaternion newRotation = Quaternion.Slerp(rb.rotation, rb.rotation * rightDirection, Time.deltaTime * 1000f);
        rb.MoveRotation(newRotation);

        //Move Side to Side
        Vector3 sideToSide = transform.right * Input.GetAxisRaw("Horizontal");
        rb.MovePosition(rb.position + sideToSide * (speed * Time.deltaTime));
    }

    private void RunWalkStand()
    {
        direction = new Vector3(0f, 0f, Input.GetAxisRaw("Vertical")).normalized;
        Vector3 forwardDirection = transform.forward * direction.z;
        bool isRunning = direction.magnitude > 0.1f;
        
        //Walking
        if (isRunning && !Input.GetKey(KeyCode.LeftShift))
        {
            rb.MovePosition(rb.position + forwardDirection * (speed * Time.deltaTime));
            playerAnimator.SetFloat("Speed_f", 0.5f);
        }
        //Running
        else if(isRunning && Input.GetKey(KeyCode.LeftShift))
        {
            rb.MovePosition(rb.position + forwardDirection * (speed * runSpeed * Time.deltaTime));
            playerAnimator.SetFloat("Speed_f", 1f);
        }
        //Standing
        else if(isRunning == false)
        {
            playerAnimator.SetFloat("Speed_f", 0f);
        }
    }
}

`

可能是因為 slerp 不是直線,所以當您靠近端點時它的速度較小,可以嘗試 Quaternion.RotateTowards。

我“大部分”解決了這個問題,這是一個意想不到的解決方案。 通過在檢查器中凍結播放器的旋轉來解決漂移(雖然仍然不知道是什么導致播放器旋轉)但是這導致了額外的抖動。 我發現了兩個問題。

  1. 如果我在層次結構中選擇了任何游戲 object 並開始玩游戲,游戲會很緊張,但如果我什么都不點擊它,游戲就會運行得更流暢(不是完全好,但更流暢)。
  2. 我正在為 pl.net 使用 Gravity 腳本,該腳本將重力應用於玩家的 Rigidbody,我相信同時有多個東西作用在 RB 上,它會導致抖動。 我正在考慮嘗試大大簡化項目,但是將腳本中的不同方法放入不同的更新方法中會有所幫助,具體取決於組合(不幸的是,不如 FixedUpdate 中的物理運動和 LateUpdate 中的相機那么簡單)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM