Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question how do i get my player to rotate towards quaternion.identity? also how to fix walking up slopes

Discussion in 'Scripting' started by SpyderManToo, Sep 13, 2021.

  1. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    im making a 2d platformer game and currently, when the player sits on a slope, they face the direction the slope is. this means they are tilted. however, when you jump, it looks very awkward to jump at a 45 degree angle so i added this line of code
    Code (CSharp):
    1. if(!isGrounded)
    2.         {
    3.             transform.rotation = Quaternion.identity;
    4.         }
    the problem with this is that it is very sudden so now i am wondering, how can i get the player to rotate to quaternoin.identity smoother and not have an instant transition?
     
  2. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    also the problem with this is that if the slope is too steep, it wont register as being on the ground so it will rotate to quaternion.identity but then, the groundcheck will think that it is grounded and thus will be able to walk up slopes that they should not be able to. how can i ffix this?
     
  3. UncleanWizard

    UncleanWizard

    Joined:
    Jun 5, 2021
    Posts:
    38
    You can use the static lerp methods of Quaternion like Slerp or Lerp.


    Code (CSharp):
    1. float lerpWeight = 0.1; // Any value between 0 and 1, 0 being slow and 1 being sudden. Time.deltaTime should also work.
    2. transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, lerpWeight);
     
  4. UncleanWizard

    UncleanWizard

    Joined:
    Jun 5, 2021
    Posts:
    38
    How exactly do you determine if the player is on the ground?
     
  5. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    i use physics2d.overlapcircle
     
  6. UncleanWizard

    UncleanWizard

    Joined:
    Jun 5, 2021
    Posts:
    38
    Can you post a picture of how that slope thingy happens? A video would be better.
     
  7. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
  8. UncleanWizard

    UncleanWizard

    Joined:
    Jun 5, 2021
    Posts:
    38
    So you basically don't want the player to walk to slopes that are too steep.

    A. You can follow Sebastian Lague's tutorial on platformers:
    Playlist:

    Video where the slope was tackled:


    B. Get the dot product of the normal of the platform you hit and the Vector2/3.up and determine if that is a valid slope from that. I recommend using CircleCast instead to get the normal of the collision.
    Vector2.Dot: https://docs.unity3d.com/ScriptReference/Vector2.Dot.html
    CircleCast: https://docs.unity3d.com/ScriptReference/Physics2D.CircleCast.html

    Code (CSharp):
    1.  
    2. var hit = Physics2D.CircleCast(origin, radius, direction); // Note:
    3. // In my experience the "direction" argument
    4. // is not really important so you can leave that as Vector2.zero
    5.  
    6. float dot = Vector2.Dot(hit.normal, Vector2.up);
    7. float absDot = Mathf.Abs(dot); // Get the abs since dot product is -1 to 1
    8. const float limit = 0.5f;
    9. if (absDot > limit)
    10. {
    11.     // Stop or slow down the player
    12. }
    13.  
    14.  
    15.  
     
  9. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    how would i nessecarily stop the player? i dont want to add a force in the opposite direction cuz that might be buggy and seems kind of weird
     
  10. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    also i did this to my code
    Code (CSharp):
    1. var hit = Physics2D.CircleCast(groundCheckPos.position, groundRadius, Vector2.zero);
    2.         // Note:
    3.         // In my experience the "direction" argument
    4.         // is not really important so you can leave that as Vector2.zero
    5.  
    6.         float dot = Vector2.Dot(hit.normal, Vector2.up);
    7.         float absDot = Mathf.Abs(dot); // Get the abs since dot product is -1 to 1
    8.         const float limit = 0.5f;
    9.         if (absDot > limit)
    10.         {
    11.             // Stop or slow down the player
    12.             canWalk = false;
    13.         }
    14.         else
    15.         {
    16.             canWalk = true;
    17.         }
    Code (CSharp):
    1. private void FixedUpdate()
    2.     {
    3.         moveInput = Input.GetAxis("Horizontal");
    4.         if (canWalk)
    5.             rb.velocity = new Vector2(moveInput * moveSpeed, rb.velocity.y);
    6.         else
    7.             rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y);
    8.     }
    and now i cant walk
     
  11. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    i debugged the value of dot and it was constantly -1
     
  12. UncleanWizard

    UncleanWizard

    Joined:
    Jun 5, 2021
    Posts:
    38
    Can you debug the value of hit.normal?
     
  13. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    when in mid air, normal is (0, 0)
    when on flat ground normal is (0, 1)
    when on 45 degree slope, normal is (0.7, 0.7)

    upload_2021-9-14_15-24-47.png
     
  14. Stoicheia

    Stoicheia

    Joined:
    Jun 25, 2020
    Posts:
    27
    This is an interesting question. However, practically speaking, the vast majority of games do not tilt players which are in contact with a slope! It is far more natural to just fix the player's rotation. If you think to your favourite 2D platformers, chances are that the characters walk on slopes as if it were flat ground. At most they might slow you down, or make you slip down due to gravity.
     
  15. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    o, thanks, so should i just freeze rotation on rb?
     
  16. Stoicheia

    Stoicheia

    Joined:
    Jun 25, 2020
    Posts:
    27
    You probably don't need to freeze it, just remove the logic where you rotate the player on a slope. I know it probably feels bad to just remove something you've worked on for a long time, but ultimately this is a design problem.
     
  17. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    i dont have any code to rotate it xDDD its just a side affect from my script, i change the rb velocity and it just happens to rotate it onto the slope lol
     
  18. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    now thi s just looks weird
    upload_2021-9-14_19-19-9.png
     
  19. Stoicheia

    Stoicheia

    Joined:
    Jun 25, 2020
    Posts:
    27
    It looks weird because the sprite is literally a square. Replace it with a character sprite and it will look normal.
     
  20. SpyderManToo

    SpyderManToo

    Joined:
    Dec 8, 2020
    Posts:
    387
    oh, ok