- Home /
Quaternion Equivalent of restricting an axes rotation to zero
Hi I have a setup where a turret is made up of two gameobjects, one being the base that should only rotate on the Y axis and a head which is a child of the base which should only rotate in the X axis.. The problem im experiencing is that to restrict the base to the y axis i convert the Quterion rotation of the head into euler angles which seams to either cause a loss of accuracy or for some other reason instead of facing a moving target it aims just to one side then next frame just a little to the other side
turrethead.rotation = Quaternion.RotateTowards (turrethead.rotation, Quaternion.LookRotation (gooddirection, transform.up), turnspeed * Time.deltaTime);
Vector3 rot = turrethead.localEulerAngles;
rot.x = 0;
rot.z = 0;
turretbase.localEulerAngles = rot; [commenting out this line fixes things]
what I think I need is instead of using Euler angles is to restrict the rotation using pure quaternion maths but cant seam to find anything on how to remove the "x and z" rotation from a quaternion Any help would be appreciated
Answer by Lord Simpson · Aug 22, 2011 at 10:37 PM
OK simplified things...was thinking to much in reality. The Most important thing is the head faces the target and really the base is just graphical fluff so removed the parenting and used
turrethead.rotation = Quaternion.RotateTowards(turrethead.rotation,Quaternion.LookRotation(gooddirection,transform.up),turnspeed*Time.deltaTime);
turretbase.localEulerAngles = new Vector3(0,turrethead.localEulerAngles.y,0);
Works Perfectly :D
Of course that would work as well ;) I was thinking about that but a lot people won't get it so i posted a real world example :D
Answer by Bunny83 · Aug 22, 2011 at 05:34 PM
Quaternions don't work in 3 axis like the eulerangles representation. It's more a combination of an internal vector3 that specifies a rotation axis and the rotation around this axis.
Your problem is that you rotate the head before the base and you rotate both objects in worldspace. So rotating the head towards the target in worldspace and after that rotating the base would also rotate the head since it's a child of the base. Therefore your head points into the wrong direction which causes the procedure to repeat each frame.
I guess i would do it like this:
vector3 xzDirection = gooddirection; xzDirection.y = 0.0f;
turretbase.rotation = Quaternion.RotateTowards (turretbase.rotation, Quaternion.LookRotation (xzDirection, Vector3.up), turnspeed * Time.deltaTime);
float pitchAngle = Mathf.Acos() * Mathf.Rad2Deg; turrethead.localRotation = Quaternion.Euler(pitchAngle,0,0);
Not tested! Maybe you need to invert the pitchAngle
[EDIT] Ah found a problem
Thank you very much!! just needed A little tweaking but I think this is the correct version of what you proposed as it hasent gone wrong yet :D
Vector3 xzDirection = gooddirection; xzDirection.y = 0.0f;
turretbase.rotation = Quaternion.RotateTowards (turretbase.rotation, Quaternion.LookRotation (xzDirection, Vector3.up), turnspeed * Time.deltaTime);
float pitchAngle = -$$anonymous$$athf.Asin((gooddirection).y/gooddirection.magnitude)*$$anonymous$$athf.Rad2Deg;
pitchAngle = $$anonymous$$athf.$$anonymous$$oveTowardsAngle(turrethead.localEulerAngles.x,pitchAngle,turnspeed*Time.deltaTime);
turrethead.localRotation = Quaternion.Euler(pitchAngle,0,0);
Ok just one problem that i cant seam to fix..The turret is actually the child of an object that can rotate in any direction..everything works fine BUT the turret base keeps its up pointed to world up and not its parents up...cant seam to sort this problem either :@
Answer by daniellasry · Aug 22, 2011 at 05:05 PM
Why not use one of the Transform.Rotate() variants to rotate around just one axis?
Say for example:
//This will rotate the turrethead by 90 degrees around the x axis
turrethead.Rotate(90.0f, 0.0f, 0.0f);
//This will rotate the turret base by 45 degrees around the y axis
turretbase.Rotate(0.0f, 45.0f, 0.0f);
Rotate() rotates the transform relative to the current rotation. He wants the turret to aim at a specific target ;)