- Home /
Vector3 of rotation comparison fails
Hi all,
I'm trying to create a rotation puzzle, where 4 objects need to be aligned to specific angles for the solution. There are 4 buttons that each rotate 2 objects 90 degrees clockwise.
Here's the code for the Manager:
class RotationPuzzleManager (MonoBehaviour):
public listOfTwisties as (GameObject)
public rotationSolution as (Vector3)
def Execute (clickedObject as GameObject):
currentTwistieRotations as List = []
for eachTwistie in listOfTwisties:
currentTwistieRotations.Add(eachTwistie.GetComponent[of RotationPuzzleTwistie]().GetTargetRotation())
currentTwistieVectors as (Vector3) = array(Vector3, currentTwistieRotations)
if currentTwistieVectors == rotationSolution:
print ("YOU WIN!!!")
Where `GetTargetRotation()` returns `Quaternion.Euler(targetRotation).eulerAngles` and `targetRotation` is where the Twisties are rotating to.
The angles are always right angles (0, 90, 180, 270) and the code above works... sometimes. Sometimes the comparison (`currentTwistieVectors == rotationSolution`) fails when the angle is 0 or 180, eg (`(0.0,0.0,0.0) == (0.0,0.0,0.0)`) OR (`(0.0,180.0,0.0) == (0.0,180.0,0.0)`).
What am I doing wrong? Any help would be greatly appreciated.
Answer by Oana · Oct 15, 2012 at 09:33 AM
Might be floating point errors... Try something like this: diff as (Vector3) = currentTwistieVectors - rotationSolution; if diff.magnitude<0.1f print("YOU WIN!!!");
You might also look at $$anonymous$$athf.Approximately and use Vector3.sqr$$anonymous$$agnitude.
Thanks very much for your input. I wish `currentTwistieVectors == rotationSolution` worked, as it's really elegant - but as Oana pointed out, it seems to be floating point errors.
$$anonymous$$evin Harris, thanks for your reference for better optimization - Vector3.sqr$$anonymous$$agnitude is meant to be faster, according to the documentation. $$anonymous$$athf.Approximately unfortunately doesn't work due to the clarification made by Owen Reynolds below - sometimes 0 is some huge negative number.
Answer by Owen-Reynolds · Oct 15, 2012 at 04:20 PM
Quaternions are a "double cover," which means there are two ways two store each rotation. In other words (0,180,0) is also (0,-180,0) but also something odd like (-90,270,90). Unity usually gives you the "obvious" one, but not always.
Maybe print out currentTwistyVectors and check. Lots of numbers, so maybe print all on one line with `w=""; w+=pieceName+curTwstVec;`. Or limit with `if(eachTwisty==middlePiece)` and just change middlePiece and watch the numbers.
If that is that problem, but there are too many combos (maybe sometimes it thinks (0,0,0) is (360,720,0)) you could instead use `Quaternion.Angle` to compare current/actual. It "knows" that 360==0, and so on.
Owen Reynolds, thanks for the clarification. I did have a printout but declined to put it here - effectively `180.0 != 180.0` (huh?). `Quaternion.Euler(targetRotation).eulerAngles` is meant to return understandable values (ie 0-360), but it doesn't seem consistent. I don't want to use Quaternions as a solution as they're already Vector3s and I'd prefer not to convert everything into Quaternions at every click. However, Oana's answer above works - it seems that doing a $$anonymous$$us operation with 2 Vector3s makes the values behave themselves.
Your answer
Follow this Question
Related Questions
How do you perform multiple rotations on the same object? - (in a single frame) 0 Answers
Rotating a direction Vector3 by Quaternion 2 Answers
Rotate Vector3 array around a point 1 Answer
Set rotation based on 1,1,1 style vector? How to convert vector3 to quaternion? 1 Answer
Play incorrect animations when is looking in other direction 0 Answers