I’m trying to read the rotation values of three objects, compare them each to a known value, then output an “on” when all of them equal their respective constants, to then trigger something else (Imagine the claw doors from Skyrim, that’s what I’m trying to replicate)
I can read the values just fine, the issue comes in comparing them, I can’t find a node that will accept two “quaternions” to compare. I only need to compare one value (see what I’m trying to replicate), so is there a way to only read one value?
Is there a better way to do this? Is there even a way to do this? I’m stuck and on a little bit of a time crunch for a competition, so any help would be greatly appreciated!
Since Quaternion math can get quite complex.
I think you’re best off using udon# for this since it allows you to simply do ==
or you can use the angle in case you want them to roughly match
I have absolutely no knowledge of actual programming, It doesn’t make sense to me, I can barely wrap my head around the drag and drop node programming.
Could you please try to explain what I have to do here?
@Luna_Delrey, You can do the same operators in Graph as you can in Udon#, you don’t need Udon# to do ==. Also, telling people to just switch to Udon# is not helpful.
The node, Quaternion.Equals allows you to compare two quaternions and it will return True if they hold the same values, and false if they don’t.
Quaternions can get a bit confusing math wise, so I’d advise if you’re doing anything more than simply comparing them, get the Euler angles of the Quaternion instead. It will return a Vector3 X,Y,Z value instead of a Vector4 X,Y,Z,W value. You can then do whatever operations you need on the Vector3.
Ok, I tried using that, both with the comparing quaternions, and just the z angle, and it didn’t seem to do anything. I remember reading that quaternions can go up to 720, so I put in two possible equal statements…
Is there anything horrendously wrong with my code?
(Currently what I have in there is the angle comparison thing, but I did try the quaternions)
Quaternions are quite a bit complex. The values they return are between -1 to 1:
Comparing them like them like this requires a more in depth understanding of Quaternion math. I would advise you convert the Transform Rotation to Euler angles and compare against that, as the values they return are between 0 to 360 degrees. Even if the object’s rotation surpasses 360, it will loop around to 0 again when getting the Euler angles. However be careful, as changes to another axis of rotation may change the rotation of the axis you’re comparing against.
So- Something more like this?
Because this didn’t work…
Is there something else I’m missing?
That looks like it would be correct. I’d suggest using Debug.Log and ToString the values you’re checking to debug and see what’s going wrong. Maybe you have a different Euler Angle than you’re expecting on your rotations. This is how you can print a value to the console.
You can build and test the world and open the console with (Right Shift + ~ + 3) to see the values getting printed. Or if you’d like to operate a bit more efficiently, you can install CyanEmu to allow Udon Behaviours to run directly in Unity Editor when you enter Play Mode:
So I did what you suggested, and I figured out that the actual equality is coming back false, even if the rotation does match the set value (I also figured out that the y-rotation had to be 180 to match)
The rotation string is reported as (0.0, 180.0, 0.0) and the last number increases by 120 when I interact with the ring, as I’ve programmed elsewhere.
So, I don’t know what’s up now.
The inner ring is what I’m currently testing, however, it’s being weird
It doesn’t need to move, so its reference is 0, 180, 0
And the output is true when the scene first loads, but if it goes around (Even if it still reports 0, 180, 0) it will no longer give a true output
And the same thing happens to the other rings, the first time it lands, it’s fine, but if there is more than exactly that rotation ((Needed value)+360n) then the output won’t ever be true
I built a test to see what would be going wrong. I realized quickly that using floats to measure precise values was the issue. Sometimes a float might have a few trailing decimals that makes it so asking if it equals an exact value, will return false. Instead you should be casting the rotation value to an Int to get a round number and compare against that instead. You can use the Mathf.RoundToInt() node to do this consistently, and then you can compare against a round value.
Here’s how to set something like that up;
I actually figured out my own way around it
What I ended up doing is changing up the object rotation code so that it cycles through 3 pos-tions, tied to another body with known rotations, that are also used in the comparison, instead of simply adding 120 degrees to the object’s rotation
Lock comparison code
Ring rotation code