How can I align axis with quaternion.fromToRotation?

Hey folks, going somewhat crazy here. Trying to align two transforms, so that a prefab can be instantiated and made to stand at a particular parent empty, standing upwards along a particular axis of the parent empty.

In the following image, I have a basic tree whose Y axis should aligned to the parent transform’s -Z (minus z) axis.

I desire that the tree should be standing with the trunk in line with the blue axis of the parent transform, but ‘growing’ in the opposite direction to the blue arrow (the green ball of the ‘tree’ should be away from the transform’s origin in the opposite direction to the blue arrow).

When the tree is instantiated, it is assigned the rotation of its parent transform and all axis of both objects are aligned.

I identify the rotation between the axis and apply it to the tree’s transform, following the example on this page. While that code works on a simple test project, I can’t get it to work in my work scene. At the moment, my code reads as follows:

tempTree.rotation = Quaternion.FromToRotation(tempTree.up, -treeArray[i].transform.forward);

I have also attempted using the code so that the rotation from Quaternion.FromToRotation is applied to the transform.rotation through multiplication.

tempTree.rotation *= Quaternion.FromToRotation(tempTree.up, -treeArray[i].transform.forward);

In both cases, my result is as seen in the attached image - the tree is rotated to a seemingly arbitrary angle, entirely unsuitable for the project.

Please, if you can, help me out with this one. Time is short, and I’m going out of my tree. =D

Try

tempTree.rotation = Quaternion.FromToRotation(Vector3.up, -treeArray*.transform.forward);*
You are setting the tree’s rotation in world space, so you want the rotation that would move world up to point in a certain direction, not the tree’s current up (which you are overwriting).

@Antistone - You saved my bacon. Thank you so much.

Thanks also to @Owen-Reynolds - Honestly, I’m still really confused about quaternions. Up to just now I’d thought I knew enough to get through normal jobs, but this basically blew my mind.

@Owen-Reynolds in your post looks like it broke, probably because you tried to use an array index in square brackets and it got interpreted as a bbcode formatting tag.

I agree that the last code snippet from the OP (using the *= operator) looks like it could work as a general approach, but debugging it seemed harder than just working out a new answer from first principles. My guess is that the multiplication is being done in the wrong order (i.e. that it would need to be FromToRotation * currentRotation rather than currentRotation * FromToRotation–remember, multiplication of Quaternions is not commutative!).

1 Like

That’s the one thing Unity Answers still beats Forums on – underneath it gives you the “display” version of your reply, as you type it.

Yes, that seems exactly the problem. RS figured out = wasn’t correct, then figured out *= was the “add one rotation to another” command. That’s pretty impressive. But didn’t realize the entire approach of using tree.up wasn’t good.

To help out the OP, I’d rephrase that as “multiplication of ROTATIONS doesn’t commute”. Quaternions are the easiest way to handle rotations. But rotations themselves are a huge pain. I like to put it a different way: q1R applies q1 as a global spin. Rq1 applies q1 in R’s local axis. If you know how to use the Local/Global tool as a 3D modeler, you basically understand local vs. global rotations in a program.

Oh lord, I’d forgotten that order of multiplication was critical with Quaternions.

Thanks so much to both of you, lots to try to internalize here.

God, I spent so much time trying to get those trees to stand up straight…

–Rev

1 Like