Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Smooth Rotation that uses Raycast

Discussion in 'Editor & General Support' started by girlinorbit, Mar 13, 2021.

  1. girlinorbit

    girlinorbit

    Joined:
    Apr 27, 2019
    Posts:
    114
    I'm rotating my player with the slope of my terrain by using a raycast. My problem is that the rotation is really choppy. How would I smooth it out?

    Here's my code:

    Code (CSharp):
    1. void FixedUpdate()
    2.     {
    3.         RaycastHit hit;
    4.  
    5.         if (Physics.Raycast(transform.position, -Vector3.up, out hit)){
    6.             transform.rotation = Quaternion.LookRotation(Vector3.Cross(transform.right, hit.normal));
    7.         }
    8.     }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    Instead of using hit.normal instantly and directly, average it over time by keeping an "accumulated" hit.normal and slowly moving it towards the hit.normal of this frame's raycast.

    This is just such a simple low-pass filter:

    Code (csharp):
    1. private Vector3 normalAccumulator;
    2. const float Snappiness = 1.0f; // larger is faster response
    Then when you hit:

    Code (csharp):
    1. normalAccumulator = Vector3.Lerp( normalAccumulator, hit.normal, Snappiness * Time.deltaTime);
    Now use normalAccumulator in your rotate thing above.
     
    Cooo_oooper likes this.
  3. girlinorbit

    girlinorbit

    Joined:
    Apr 27, 2019
    Posts:
    114
    That did the trick!

    Here's what I ended up with:

    Code (CSharp):
    1. private Vector3 normalAccumulator;
    2. const float Snappiness = 1.0f; // larger is faster response
    3.  
    4. void FixedUpdate()
    5.     {
    6.         RaycastHit hit;
    7.  
    8.         if (Physics.Raycast(transform.position, -Vector3.up, out hit)){
    9.             Vector3 insert = new Vector3(0,0,0);
    10.             normalAccumulator = Vector3.Lerp( normalAccumulator, hit.normal, Snappiness * Time.deltaTime);
    11.  
    12.             transform.rotation = Quaternion.LookRotation(Vector3.Cross(transform.right, normalAccumulator));
    13.         }
    14.     }
     
    Parokonnyy and Kurt-Dekker like this.