Home > Net >  Why is my Controller drifting with Slerp?
Why is my Controller drifting with Slerp?

Time:12-10

I've been working on this Controller, where I walk around a small planet. I'm using Quaternion.Slerp, and when I'm at certain points on the planet, the controller slowly drifts, rotating around the Y axis. My thought is that it is holding a value based on my starting position, and so when I move to different points, the Slerp function is trying to spin me toward that location? I've tried messing around with the script, moving different portions to their own custom methods to pinpoint the issue, but I'm a bit lost at this point. Any help would be appreciated!

I think the issue is going to be somewhere in the bottom two methods NewRotation, or 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);
        }
    }
}

`

CodePudding user response:

it might be because a slerp is not a lineair line so its velocity is less when you are close to the endpoint maybe try Quaternion.RotateTowards.

CodePudding user response:

I "Mostly" solved this issue, and it's an unexpected solution. The drift was solved by freezing rotation on the player in the inspector (Still don't know what was causing the player to spin though) However this caused extra jitter. I found two issues.

  1. If I've selected ANY game object in the hierarchy, and play the game, the game is jittery, but if I click off of it onto nothing, the game runs smoother (Not completely better, but much smoother).
  2. I'm using a Gravity script for the planet that applies gravity to the player's Rigidbody, and I believe with multiple things acting on the RB at the same time, it causes jitter. I'm thinkin of trying to greatly simplify the project, but putting the different methods from the scripts into different Update methods helps a good bit depending on the combination (Not as simple as Physics movement in FixedUpdate and camera in LateUpdate unfortunately).
  • Related