- Home /
Rotating an Object to its Original Angles after certain distance from ground
So a brief explanation of the project that I am working on is a simple scene where a First Person Controller is standing on a platform that raises them into the sky. When they are at the peak of the lift, about 10 seconds passes and then the lift drops out beneath them and they start rotating as if free falling towards the ground. My problem isn't this, I have this working quite nicely but my problem comes when I want to correct the controllers X rotation so that it is standing straight up again, it doesn't matter what direction they are facing as long as they land on their feet. I have been trying to work with Quaternions to get this to work but it hasn't worked for me at all.. I figured out that I can make the controller 'snap' back into the rotation angle I want but it isn't smooth like I would like (think a cat landing on its feet).
Here is the code snippit I am working with:
public float RotY = Random.Range (50.0f,150.0f);
public float RotX = Random.Range (50.0f,150.0f);
public float RotZ = Random.Range (50.0f,150.0f);
public float ReturnTo = 10.0f;
private bool grounded = true;
private bool straight = true;
private bool corrected = true;
private float distToGround;
public float stability = 0.3f;
public Quaternion origRot;
private float currentAng;
public bool isRotateX = false;
public bool isRotateY = false;
public bool isRotateZ = false;
// Initialization & Detecting if on ground
void Start ()
{
origRot = transform.rotation;
distToGround = collider.bounds.extents.y;
collider.isTrigger = true;
}
//Boolean if on ground
bool IsGrounded(){
return Physics.Raycast(transform.position, -Vector3.up, distToGround + 2.0f);
}
bool Straighten(){
return Physics.Raycast (transform.position, -Vector3.up, distToGround + 10.0f);
}
// Update is called once per frame
void Update ()
{ grounded = IsGrounded ();
straight=Straighten ();
if(!grounded){
corrected = false;
// Toggles X Rotation
if(isRotateX)
{
transform.Rotate(RotX * Time.deltaTime*-1, 0, 0);
}
// Toggles Y Rotation
if(isRotateY)
{
transform.Rotate(0, RotY * Time.deltaTime*-1, 0);
}
// Toggles Z Rotation
if(isRotateZ)
{
transform.Rotate(0, 0, RotZ * Time.deltaTime*-1);
}
}
//Rotate back to original angle
if(straight && !corrected){
float step = stability * Time.deltaTime;
transform.rotation = Quaternion.RotateTowards(transform.rotation,origRot,step);
corrected = true;
}
}
But this doesn't seem to do anything because I always just land and sit on my side.. Am I using Quaternions wrong or does my code just have errors? Any help would be greatly appreciated.
Answer by robertbu · Apr 28, 2014 at 04:01 PM
Assuming 'origRot' is an upright rotation, then your RotateTowards() looks right. Try changing line 39 to:
if(!grounded && !straight){
I guessing that your tumble code and your straighten code are fighting.
Note you may want to experiment with changing 'Quaternion.RotateTowards() to 'Quaternion.Lerp()' and adjusting 'step'. It might give you a more natural alignment.
Thanks for your quick response robertbu. When I change line 39 it makes it so that when straight is activated it stops my rotation and doesn't correct it.. The few tests I just ran all ended with me being ~15 feet from the falling head first and my rotation just stops making me crash headfirst into the ground.. $$anonymous$$y origRot at the beginning of the scene is straight up and down. I also tried this using Lerp and RotateTowards.
Second problem found. Remove line 62. You are setting corrected to true the first time this code is executed, so it never executes for the rest of the frames necessary to do the alignment. If you really need corrected, you can do something like:
if (Quaternion.Angle(transform.rotation, origRot) < someThreshold)
corrected = true;
This definitely fixed my issue. Now I have the issue of it always correcting itself (even before it lifts off the ground) but this is something I am sure I can work out by myself with a little bit of time and effort. Thank you very much for your help!
Your answer
Follow this Question
Related Questions
Get slerp to work just as LookAt(,Vector3.right) does 1 Answer
Boids for 2D 0 Answers
How to use quaternion.lerp 2 Answers
Rotate object without storing facing 1 Answer
Player forward in Kinect 1 Answer