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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Question Smoothly Rotating Transform to Ground Normal in 2D

Discussion in 'Editor & General Support' started by Poisonx_3, Aug 31, 2022.

  1. Poisonx_3

    Poisonx_3

    Joined:
    Dec 5, 2020
    Posts:
    9
    So I have this working rather well but one part of it bugs me and I'd like to get rid of that. The gif shows this but incase the quality is bad what is basically happening is that the transform's z rotation is being set to match the angle of the ground they are on. I have a "circle" I made for testing that is a bunch of rectangles with collision each rotated 10 degrees to make about 25% of a circle, then copy pasted to make a full circle. The character works great except what bugs me is that it snaps to each new rotation which makes it look not great. Here is my code:
    Code (CSharp):
    1.             if (m_collisionCheck.IsOnSLope())
    2.             {
    3.                 m_parentScript.transform.rotation = Quaternion.FromToRotation(Vector3.up, m_collisionCheck.GetGroundNorm());
    4.                
    5.             }
    6.             else
    7.             {
    8.                 if (m_parentScript.transform.rotation.z != 0)
    9.                     m_parentScript.transform.rotation = Quaternion.identity;
    10.             }
    Fairly straight forward and I know that it's so snappy because that's how I'm setting it but I scoured the internet for this solution since I barely understand Quaternion and how the functions should be used. I attempted to use Quaternion.Lerp to no avail and Quaternion.RotateTowards with Time.fixedDeltaTime (I have this code in FixedUpdate), which almost worked but I couldn't get a good speed to rotate since it was either too fast or too slow. Here is that code:
    Code (CSharp):
    1. if(//Angle of the difference of current transform rotation and ground rotation is greater than 20)
    2.     m_parentScript.transform.rotation = Quaternion.FromToRotation(Vector3.up, m_collisionCheck.GetGroundNorm());
    3. else//atempt at smooth rotate
    4. {
    5.     float rotateSpeed = 1000f;
    6.     if (m_moveInfo.directionNormal != 0f)
    7.         rotateSpeed = m_moveComponent.GetVelocity().magnitude * 11f;
    8.  
    9.     Quaternion rot = Quaternion.FromToRotation(Vector3.up, m_collisionCheck.GetGroundNorm());
    10.     m_parentScript.transform.rotation = Quaternion.RotateTowards(m_parentScript.transform.rotation, rot, rotateSpeed * Time.fixedDeltaTime);
    11. }
    This code was in line 3 of the last block.

    The idea was that if the angle that needed to be rotated was large enough to just snap to it, otherwise smoothly rotate so it didn't look bad going across small angle changes. The if statement is also a comment since I couldn't find a good way to compare the normal to a rotation.

    I'm wondering if there are any good solutions to this of if this is the best way and I just need to find a good way to match the speed of rotation to the movement speed of the player since the speed of the player changes which could cause too slow of rotation if they are moving quickly across a multi-angled surface, like the one in the gif. Any help or guidance is appreciated.
     

    Attached Files:

  2. Poisonx_3

    Poisonx_3

    Joined:
    Dec 5, 2020
    Posts:
    9
    I found an answer to the issue but its more of a way around it I think. So for anyone curious I have 3 rays that get me ground normals and angles and all that. What I use to do was get the angle of the ground to rotate the player but now I get the average (add the normals together then divide by the amount added) and this seems to smooth out some of those acute edges and make it a smoother rotation.