- Home /
Get X normal of collider below object regardless of rotation
I have a character moving along a spline. That works great, and is used to rotate the Y coordinate of the rotation. Now, the game has hills and such, and the character needs to rotate their X to match those hills. As long as the character's Y rotation is 0, the following code works beautifully. However, once the Y has changed to face another direction - the following code results in returning 0f for the X.
Ray downRay = new Ray(headNode.position, -transform.up);
RaycastHit[] hits = Physics.RaycastAll(downRay, characterHeight * 2);
foreach(RaycastHit thisHit in hits)
{
if(thisHit.collider.tag == "GroundCollider")
{
Quaternion targRot = Quaternion.FromToRotation(Vector3.up, thisHit.normal);
Quaternion rotatedQuat = Quaternion.Euler(targRot.eulerAngles);
eulerAngles.x = rotatedQuat.eulerAngles.x;
break;
}
}
I'm guessing for this to work right I need to normalize the direction of the normal to always be the same direction, so that I can always get a normalized X. Any tips or pointers here would be fantastic! Thank you!!
Are you working with local or parent coordinates? You set some variable eulerAngles.x value there, but I don't see what you set to that variable (transform.eulerAngles or transform.localEulerAngles or something else?) One trick is to make the character a child of a parent game object, then rotate that parent game object in one axis and rotate the child game object in the other axis (using eulerAngles), kind of like a gyroscope.
Answer by RedVonix · May 29, 2014 at 05:43 PM
These are all parent coordinates / world coordinates. The eulerAngles gets applied to transform.eulerAngles. Putting the object inside of another and rotating the child doesn't work in this case as the data I need to rotate is actually the result of the raycast.
I've assembled an image that attempts to describe the issue in more detail. Essentially the player moves along a rail, or track, and they rotate with the track to always point in the direction the track is moving. The track is just a spline. That works fine. However, if the player's rotation is not exactly 0,0,0 and they are on a hill, the value of the RaycastHit.normal is of course to the location rotation. Since the X value of the player is always facing to its local forward, I need to either rotate the value of RaycastHit.normal to a standardized rotation to grab the proper X to apply to the player's rotaion - or I need to always rotate the value of RaycastHit.normal to match the player's rotation so the X will be correct. And that is what I'm not sure how to do. :)
I got it to work! The answer was in this thread here: Correcting hit.normal when hit.transform is rotated. To make it work, I had to change my code above to the following, which properly rotates everything into a standard rotation allowing access to normalized x.
Ray downRay = new Ray(headNode.position, Vector3.down);
RaycastHit[] hits = Physics.RaycastAll(downRay, characterHeight * 2);
foreach(RaycastHit thisHit in hits)
{
if(thisHit.collider.tag == "GroundCollider")
{
Quaternion targRot = Quaternion.FromToRotation(transform.up, thisHit.normal) * transform.rotation;
eulerAngles.x = targRot.eulerAngles.x;
break;
}
}
Your answer
Follow this Question
Related Questions
Rotate Player to Match Surface Normal While Still Maintaining Y Rotation 0 Answers
Using Raycast Normal to match surface rotation to instantiated gameobject? EXAMPLE GIF Included 0 Answers
hit.normal rotation problem, help please really confused 1 Answer
Comparing a quaternion to a contact point normal 0 Answers
Rotation Transform to face character AND normal to terrain 2 Answers