Search Unity

Make object stand up after thrown on the floor?

Discussion in 'Scripting' started by Ricks, Nov 11, 2012.

  1. Ricks

    Ricks

    Joined:
    Jun 17, 2010
    Posts:
    650
    Hello,

    I am currently trying to make an object stand up (rotate) from laying down on the floor. I tried to achieve that with the following rotations:

    Code (csharp):
    1.  
    2. public void standUp ()
    3.     {
    4.         Quaternion startRotation = transform.rotation;
    5.         Quaternion endRotation = Quaternion.Euler(0, startRotation.y, 0);      
    6.         transform.rotation = Quaternion.Slerp(startRotation, endRotation, Time.deltaTime*2.0F);    
    7.     }
    8.  
    While this works, the object always rotates into the default rotation which is that the Y (the Up-Axis) is rotated looking into the Z-direction (the default direction when an object is created). However, what I want to achieve is that when it stands up, it should keep the rotation of the Y-Axis. Any hints on that?
     
    Last edited: Nov 11, 2012
  2. Ricks

    Ricks

    Joined:
    Jun 17, 2010
    Posts:
    650
    Ok I think got it. For the record: the trick is to keep the specific values of the rotation before standing up (Y-Value and W-Value) and set the others to 0:

    Code (csharp):
    1.  
    2. Quaternion startRotation = transform.rotation;
    3. Quaternion endRotation = new Quaternion (0.0F,transform.rotation.y,0.0F,transform.rotation.w);
    4. transform.rotation = Quaternion.Slerp(startRotation, endRotation, Time.deltaTime*2.0F);
     

    Attached Files:

    Last edited: Nov 12, 2012
    GallChi and johnmcw like this.
  3. sheiro

    sheiro

    Joined:
    Mar 6, 2015
    Posts:
    7
    Hey thanks! I had exactly the same problem, and thanks to you i solved it!
     
  4. GallChi

    GallChi

    Joined:
    Jan 16, 2018
    Posts:
    4
    Thanks, that was the most clear answer.
     
  5. TheGreenCode

    TheGreenCode

    Joined:
    Nov 17, 2019
    Posts:
    1
    So, can i just put the code in a every update, and it will work?
     
  6. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,108
    There is absolutely no need to tweak the quat values if you don't know what you're doing.

    You should simply Slerp between two directions.
    First you save the original object's up direction with
    myObject.transform.up


    Then you can tween the rotation between this source direction to the target direction, which is Vector3.up
    Code (csharp):
    1. // this finds the shortest path between two directions
    2. currentDir = Vector3.Slerp(startDir, Vector3.up, t));
    3.  
    4. // then you use the computed direction and make a rotation quat from the currentDir
    5. Quaternion tweened = Quaternion.FromToRotation(myObject.transform.up, currentDir);
    6.  
    7. // finally you multiply the original rotation with the computed one, to make it rotate by little
    8. myObject.transform.localRotation *= tweened;
    edit:
    And in fact, you could use LookAt
    The main trick is to avoid Euler, because it will only fix the Y rotation to something arbitrary

    Code (csharp):
    1. currentDir = Vector3.Slerp(startDir, Vector3.up, t));
    2. myObject.transform.LookAt(myObject.transform.position + currentDir);
     
    Last edited: Mar 19, 2020