Hi,
I have been having a lot of trouble with and I do not understand the math soundly enough to figure it out myself. What I am trying to make is a script to guarantee an object is aligned with its parent but rotated so that its bottom is towards world down. Basically, think of wall (the parent) with a ring (the child with this script) is affix so that its position on the wall will not change, but the rind can still freely rotate. Now, the ring has some weight attached such that gravity always pulls the ring into a consistent rotation. Now, as you rotate the wall along its Z-axis, the ring should move with its parent but rotate so that the weight is still on the bottom and to an observer the rotation of the ring never changed.
My first thought was to take the normal to this wall, namely the Z-axis, and use that as my ring’s z-axis as well. Then take Physics.gravity and cross it with my Z to make a new X axis, and use that cross Z to make my new Y. The problem thought is that I do not know how to turn these three vectors into a rotation for this object. I read somewhere that simply assigning the transform.up, forward or right actually causes the object to rotate and not just change the orientation. Preferably, I would love to use Quaternions but I have no idea what the next step might be.
Thanks for any help you can provide.
PS: I have read a lot about this sort of math and angles and rotations but I just don’t understand what to do or how to go from one to the other. I hope there is a simple method that I have not thought to use yet.
Reading through your description, I’m visualizing a Ferris wheel where the large wheel goes around on its axis, but the cars where people sit (as children of the Ferris wheel) stay oriented towards the ground. If this is the behavior you are looking for, then this code should work for you. It assumes that the child object starts out oriented correctly.
public class PulledDown : MonoBehaviour {
Quaternion qStart;
void Start() {
qStart = transform.rotation;
}
void Update () {
transform.rotation = qStart;
}
}
You should try something like
void LateUpdate()
{
transform.localRotation = Quaternion.FromToRotation(-transform.parent.up, Vector3.down);
}
Thank you for your quick response.
After extensive testing and trial/error I have a partial solution; I use the projection of the gravity’s direction onto my wall, and use the fromto method to rotate my ring’s Y axis to my new vector. I say partial solution because while this does work perfectly for what I want it for right now, a 2D side scroller with limited axis of rotation, this solution breaks when the wall is rotated in more than one direction. Below is a sample of my code, written in Javascript.
function FixedUpdate()
{
var newY:Vector3;
newY = -1 * Vector3.Cross(Vector3.Cross(transform.parent.forward, (Physics.gravity).normalized),transform.parent.forward);
transform.rotation = Quaternion.FromToRotation(Vector3.up,newY);
}
I also just realized that something is happening behind the scenes when I apply that my rotation to the transform.rotation because this is not compatible with rigidbody.MoveRotation(). Is there something I am missing? I thought the two were virtually interchangeable except the rigid body applies momentum and friction.