Hi all,
I have seen in Unity’s third person tutorial (and in other scripts) the
multiplication of quaternion by vector, that is quaternionvector3.
I don’t understand what it means multiply quaternion by vevtor?
After all to rotate a point via quaternion one need to do quaternion*vector3inverse quaternion
In the quaternion world, multiplication is the way to apply the rotation to something - when you multiply quaternion by vector3, you’re actually rotating the vector. For instance:
var rot = Quaternion.Euler(0, 45, 0); // rot = 45 degrees rotation around Y
var v45 = rot * Vector3.forward; // rotate vector forward 45 degrees around Y
I didn’t understand your question about point rotation - maybe a typo, but what we can read is a quaternion *** vector3 * Quaternion.Inverse(quaternion), what makes no sense (this sequence isn’t even allowed: Vector3 must be at the right of the quaternions).
In practice, multiplying a quaternion by a point rotates this point relative to the origin (0,0,0).
Finally, Quaternion.Inverse(quaternion) returns the inverse rotation (same rotation, but to the opposite side).
Hi, I had the same problem too. I figured out that notation quaternion * vector uses overloaded multiply operator which incapsulate mathematical multiplying quaternion * vector * quaternion^(-1)similar question
I know this is quite old post but I believe this visualisation might help a lot to those who are still struggling, just play with it a bit, it’s intuitive.
I had similar problems with Quaternions and then hpjohn sent me his sample code (https://forum.unity.com/threads/compare-rotation-of-matrix-with-initial-direction.572440/#post-3811600) I played with a bit and added local rotations, now I can understand that much better:
using UnityEngine;
public class RotationTest : MonoBehaviour
{
Quaternion currentState;
private void Start()
{
//store initial state
currentState = Quaternion.identity;
}
private void Update()
{
//draw axes tripod in viewport for demo
Debug.DrawRay(Vector3.zero, currentState * Vector3.up, Color.green);
Debug.DrawRay(Vector3.zero, currentState * Vector3.right, Color.red);
Debug.DrawRay(Vector3.zero, currentState * Vector3.forward, Color.blue);
}
private void OnGUI()
{
RotateOnGlobalAxis();
RotateOnLocalAxis();
CompareCurrentPositionWithInitialState();
}
private void RotateOnGlobalAxis()
{
GUILayout.BeginArea(new Rect(100, 100, 200, 100));
if (GUILayout.Button("Rotate around global X"))
{
currentState = Quaternion.Euler(90, 0, 0) * currentState;
}
if (GUILayout.Button("Rotate around global Y"))
{
currentState = Quaternion.Euler(0, 90, 0) * currentState;
}
if (GUILayout.Button("Rotate around global Z"))
{
currentState = Quaternion.Euler(0, 0, 90) * currentState;
}
GUILayout.EndArea();
}
private void RotateOnLocalAxis()
{
GUILayout.BeginArea(new Rect(350, 100, 200, 100));
if (GUILayout.Button("Rotate around local X"))
{
currentState = currentState * Quaternion.Euler(90, 0, 0);
}
if (GUILayout.Button("Rotate around local Y"))
{
currentState = currentState * Quaternion.Euler(0, 90, 0);
}
if (GUILayout.Button("Rotate around local Z"))
{
currentState = currentState * Quaternion.Euler(0, 0, 90);
}
GUILayout.EndArea();
}
private void CompareCurrentPositionWithInitialState()
{
GUILayout.BeginArea(new Rect(225, 200, 200, 20));
if (GUILayout.Button("Check State"))
{
Vector3 currentUp = currentState * Vector3.up;
if (Vector3.Dot(currentUp, Vector3.up) > 0.9f)
{
Debug.Log("Current State has up pointing up");
}
else
{
Debug.Log("Current State has up pointing somewhere else");
}
}
GUILayout.EndArea();
}
}