Joystick and Angular Rotation SLERPing

I was able to get a generic quasi-working  proof of the joystick rotation code as you saw in the last post.  I was able to move towards the joystick location via one direction or another depending on the “moveDirection” variable I created…

One thing that needed to be done was to come up with an algorithm about which way to rotate depending on how close the ship is to the current joystick location.  This is tricky, because a circle “resets” itself.  You can’t just say “if the ship angle is less than joystick, move left; if it’s greater, move right (from the ship’s perspective).  Because if the ship is at 350 degrees (10 degrees “south-east” of pure “east” (which is 0 degrees)) and your joystick is 5 degrees (5 degrees “north east” of the pure 0 degrees east), you would think “oh, it’s greater than 5, so move to the right (i.e. clockwise)… But that’s the long way around; You actually need to determine not merely whether it is greater or lesser, but how close it is to you, and that can be tricky when you have a value that is less than in some instances and more than in others (for example, 356 degrees on the joystick position (instead of 10 as above) would still require my ship to move counterclockwise…  You have to figure out whether the item is within the left or right semicircle from your position first then set your move direction based upon that information.

With the help of a friend we got that fairly simple algorithm figured out…

Then, however…

However, due to the need for a given speed of rotation, I may overshoot the location of the joystick.  That is to say, if I move, say, 4 units of rotation, it’s obvious I may end up going from 3->7 degrees, when the joystick is located at, say, 5 degrees.

One way I could resolve that would be to compensate by going backwards after overshooting, but that’s clearly dumb.  How would you feel if you move forward, overshoot your position and the game automatically “corrects” it for you…  Nope, no dice on that one.

OK, so my next train of thought was to figure out how close I’m getting to the end position then try to reduce my move speed by a certain amount and make sure not to overshoot it.  That’s potentially doable, and in fact, what I’m ultimately going for is a more proper variant.

In fact, there’s this wonderful resource about the technique called “easing”, which is a way to take a stop and end point and apply various functions to determine how an object speeds up/slows down (i.e. easing it’s motion toward the end).  You can do some fancy effects such as bouncing with this.

Unfortunately the code to do this is very linear.  You have point A and point B and you transition between them and apply certain modifiers if you’re at the beginning or ending of the process to reflect the particular effect you’re after.  That’s great and dandy, however, rotation (in particular, rotating around an object) isn’t as clean cut as this page and it’s resources would lead you to believe.  It does provide the basics, but you need to figure out more details about the angles and directions.

Thankfully, someone else had a similar problem/question and the Unity forums provided a starting point to resolve this problem.  “Easing a rotation of RotateAround” gives a couple different ways to attempt to ease a rotation from one point to another.

The problem with that code is that it takes a rotateAmount and a rotateTime.  This will require me to calculate the rotateamount as derived from the position of the ship and the joystick.  The time will necessarily be the total amount of time I want a complete circle’s revolution to be divided by 360.  I will then multiply that value by the total difference between the ship and joystick location to give me the proper amount of time to complete that number of degrees of movement.

I have yet to do this, but I believe one issue that will come up is due to that split  between 359° and 0°.  In addition to merely checking for which direction is the shorter path  to take to the given joystick location, I believe I will have to account for the shift in greater than or lesser than comparisons when shifting between those two values.  I am not sure that is the case, but it’s something I’m preparing myself for in case the need arises.

In the meantime I’m going to figure out the code to determine the amount of  and time for the turn and try to apply it to my joystick/ship positioning code, and see if it gives me a solid approximation of what I’m going for.

One thing I’m not quite certain of right now is what the value of “rotateAmount” is in that rotateAround easing code above.  It may just be 1.0 = 1 full rotation around the circle…  Though thinking about it now, it seems when I played with it, that was related to the “speed” of the rotating object.  Working on code after coming back from a holiday weekend and a few hour drive doesn’t make for the clearest focus on the code, but I think I’m getting there.

Leave a Reply

Your email address will not be published. Required fields are marked *