Comments and answers for "Quaternion rotation with normals bug: Only works into one direction?"
http://answers.unity.com/questions/1040857/quaternion-rotation-with-normals-bug-only-works-in.html
The latest comments and answers for the question "Quaternion rotation with normals bug: Only works into one direction?"Comment by JoeStrout on JoeStrout's answer
http://answers.unity.com/comments/1040974/view.html
Oh, I think I see. 'rot' here is being calculated correctly, e.g., a +30° rotation around X would make an object with its up vector pointing straight up, point along the slope normal.
The problem is that you're then doing your object's Y rotation AFTER that rotation (remember that rotations are composed right to left). So, if you could see the intermediate steps, you would find that at rot * iniRot it's lined up with the slope perfectly, and then you rotate that 180° around Y, and get [this result][1].
So I think the solution is to do it in the other order, something like:
transform.rotation = rot * Quaternion.Euler(0, transform.rotation.eulerAngles.y, 0) * iniRot;
(Though I still recommend replacing transform.rotation.eulerAngles.y with some "yRotation" property you keep track of separately.)
[1]: http://snag.gy/SvknB.jpgThu, 03 Sep 2015 19:17:45 GMTJoeStroutComment by aleichert on aleichert's answer
http://answers.unity.com/comments/1040965/view.html
Hi @JoeStrout,
thanks for your reply.
I replaced my code with yours but sadly the problem still remains: The box rotates correctly when moving towards positive z, but the rotation is inversed when going towards negative z.
It's as if the karts transform.forward isn't recognized and it sticks to Vector3.forward.
Furthermore, I tried replacing Vector3.up with transform.up - that broke everything.
I don't understand - I even tried Quaternion.Inverse'ing rot and iniRot to no avail.Thu, 03 Sep 2015 19:00:12 GMTaleichertAnswer by JoeStrout
http://answers.unity.com/answers/1040957/view.html
You can't just take parts out of the x/y/z/w components of a Quaternion like that. When you do, you make an invalid quaternion that doesn't even represent a rotation. I'm amazed it works at all — Unity is clearly doing some error-trapping and recovery here. But you shouldn't rely on it.
Try instead working with the Euler angles... this is not ideal either, but will generally work except for extreme angles:
transform.rotation = Quaternion.Euler(0, transform.rotation.eulerAngles.y, 0) * rot * iniRot;
Even better would probably be to keep track of your desired Y rotation in a separate property, and use that in the Quaternion.Euler call above rather than using the Y component of whatever your current rotation happens to be.Thu, 03 Sep 2015 18:50:21 GMTJoeStrout