- Home /
Determine sprite facing
I am working with a top down 2d game, and I am having some trouble determining the facing of sprites. The transform object exposes rotation properties, but they are quaternions, and not simple floats indicating how many degrees an object is rotated around a particular axis.
Quaternions are vectors, and rotations around said vector, so if I take the z-vector quaternion, and use the rotation property, isn't that going to be equivalent to just a rotation around the z-axis?
Alternately, is there some better or simpler way to just get a vector or rotation indicating the sprites facing? (And all my sprites are aligned to face right).
Update: I tried this bound the the up arrow key, but it always moves me right.
Vector2 facing = cMathFunctions.RotationToVector(transform.rotation.z * Mathf.Deg2Rad);
transform.position += (new Vector3(facing.x, facing.y,0) * Time.deltaTime * Thrust);
Answer by calmcarrots · Aug 31, 2014 at 05:50 AM
http://docs.unity3d.com/ScriptReference/Transform-eulerAngles.html http://docs.unity3d.com/ScriptReference/Quaternion-eulerAngles.html http://answers.unity3d.com/questions/462073/how-to-use-euler-angles-to-rotate-an-object-.html http://en.wikibooks.org/wiki/Cg_Programming/Unity/Rotations
So it looks like you are suggestion that the best way of managing rotation is to store it locally, and then use that value to manipulate the transform object. That would work if you didn't use physics modeling. The problem is, because a collision with another object could impart a torque on the sprite/object, wouldn't that cause your local heading variable to get out of sync with the actual heading being displayed? I would think that you need to read heading off of something tied to the physics engine output to get a correct value.
I have no idea what you are talking about. Euler angles just converts Quaternions to a Vector3. That way you can say
transform.rotation = Quaternion.Euler(Vector3.down);
You can grab the rotation every second so that you can have it updated every frame.
Vector3 curRot = transform.localEulerAngles;
Vector3 curRot = transform.eulerAngles;
Quaternion curRot = transform.localRotation;
Quaternion curRot = transform.localRotation;
etc.
Then you can modify it like:
transform.rotation = Quaternion.Euler(new Vector3(0f, 38f, 56f));
transform.eulerAngles = new Vector3(0f, 38f, 56f);
//Or like this
Quaternion curRot = transform.rotation;
curRot = Quaternion.Euler(new Vector3(0f, 38f, 56f));
Those are some examples of how to use a Quaternion with a transform. For your game, if you would like to see the rotation, you could try
Debug.Log(transform.eulerAngles);
Vector3 rightDir = new Vector3(0f, 90f, 0f);
Vector3 upDir = Vector3.up;
Vector3 leftDir = new Vector3(0f, 270f, 0f);
Vector3 downDir = new Vector3(0f, 180f, 0f);
Vector3 curRot = transform.eulerAngles;
if (curRot == rightDir)
Debug.Log(transform.name + " is facing right");
else if (curRot == upDir)
Debug.Log(transform.name + " is facing up");
else if (curRot == leftDir)
Debug.Log(transform.name + " is facing left");
else if (curRot == downDir)
Debug.Log(transform.name + " is facing down");
Try to play around with rotations to get used to them.
I sorta understand what you are saying. If you collide with the object, the physics engine directly changes the object's rotation THROUGH the transform. It does not save the rotation in a separate value so if you collide with something, then the variable that you stored the rotation in will be up to date (as long as you update the variable every second).
After reading and playing with your suggestions, I came up with this:
Vector2 facing = c$$anonymous$$athFunctions.RotationToVector(transform.eulerAngles.z * $$anonymous$$athf.Deg2Rad);
transform.position += (new Vector3(facing.x, facing.y,0) * Time.deltaTime * Thrust);
...which worked very nicely to move a player along the current heading. Thanks for the info about the eulerAngles property.