Hi, all,
I'm on my 2nd AC practice game, building my skills and trying to add more complexity.
I'm currently trying to build a custom action and am running into what I think is a small snag.
What I want to do is be able to rotate an object (with Action: Object Transform) 90 degrees and then check the rotation. This is part of a puzzle where the player rotates a few objects, and when they are all rotated the correct amount, the puzzle is solved.
The custom action seems to work fine in unit testing. I did this by rotating one object and having it give me a "Yes" or "No" message depending on whether the rotation matched the value entered. However, when I put it into the game for all the items, it isn't working.
I think the issue is that when I tell objects to rotate 90 degrees (ie 0 -> 90 -> 180 -> 270 -> 0), I notice in the Inspector that sometimes it is not exactly 90 (ie 0 -> 90.00001 -> 180 -> 270 -> 0). I can't figure out why this is happening, but I thought a good solution would be to round the Vector3 before the comparison. Then I can compare the rounded object to the entered value.
I've tried a bunch of different methods I found online, but can't find anything that works.
Any help either (1) rounding the Vector3 or (2) solving the comparison issue some other way.
Not sure best practice for sharing code, so I created a gist: https://gist.github.com/gaiusjaugustus/da50546f06d4970a158e7c9b9c5a5f04
Let me know what else I can provide to clarify what's going on.
Thanks in advance!
It looks like you're new here. If you want to get involved, click one of these buttons!
Comments
The rounding issue is a common problem with floats, or float-based variables like Vectors
You might want to try the Unity function Mathf.Approximately
It compares two floats and returns true if they're approximately equal. It can't be used to compare two Vectors, so you'd need to either compare all three component elements, or just the one you're interested in (I'd guess the y value)
P.S. As a small word of warning, after some idle testing I'm not sure that the function works as expected under all possible conditions. Someone's written an alternative function over at stackoverflow, which might be worth using instead, as it allows you to specify the tolerance of the comparison
Thanks for the help!
Going off of your suggestion, I converted both Vector3 Euler Angles to Quaternions and then used Quaternion.angle to get the angle between them. Then I was able to test whether that angle was below some tolerance.
Go me for starting with rotation, which seems to be much more complicated than...say...position. Maybe not the most elegant solution, but it works until I learn more about Unity's C# quirks.
Here's the updated code for the entire script:
i'm a big fan of "it works"!
(you may find that Chris comes up with a more elegant solution though. he usually does)
If it works, it works! It may be best to leave it at that.
Though, I wonder it you could compare a Dot product of the two vectors instead. The more similar they are, the closer the result will be to 1:
Also, I'm not sure of the exact context, but this may be a good situation to rely on Draggable objects. When attached to a Track (e.g. a Hinge Track, so that it can only rotate), you can create "Snap points" so that it can only rotate to certain values. Which value it's currently at can then be checked with the Moveable: Check track position Action.
Thanks for the help, Chris.
I played around with using Draggable objects in a 2D game in an earlier version of one of the puzzles for this game. Didn't work out for me (I just need to build up to it), but it's something I want to try again in my next project.
I'll see if the dotProduct code can work. Just throwing it into the script did not, but I didn't do any troubleshooting with it. All I know is that the puzzle never made it to "solved".
If I have a moment to play around with it and figure it out, I'll post that alternate code. I made a developer menu that spits out the rotation of the object, the rotation I want for the object, and the distance between them, which has been really helpful.
Really excited to be moving along with my gamedev goals, all thanks to your AC development.
Just to clarify: the Draggable system is for 3D only. To make a Draggable object in a 2D game, you'd have to override that scene's perspective when first creating the scene in the Scene Manager.