To start, I’m unsure how to even ask this which of course made it difficult for me to search for…
…I’m effectively trying to smoothly lerp a float, which represents an angle from 0 to 360, to a target float, taking the ‘shortest route’ there.
Think virtual joystick controlling a character, where up is 0, rotating clockwise to 90, then down to 180, left to 270 finally back up to 360, which is also effectively 0 again.
So my question:
I’ve tried Mathf.Lerp, LerpAngle, MoveTowardsAngle, SmoothStep, SmoothDampAngle…I’ve attempted to figure out some tests I could maybe do with DeltaAngle…all with mixed results.
If I just Lerp, it kinda-sorta works, but doesn’t like crossing over the 0/360 barrier without the character ‘twitching’ badly. If I use MoveTowardsAngle I end up with negative numbers for some reason unknown to me.
It’s entirely possibly I’m not even asking this question correctly but I have to start somewhere, at wits end.
Quaternions! Take a look at the standard assets that come with Unity; there are several sample joystick options that do this. Might just be in the mobile assets, though.
Hey Razor, yea I thought about that but ultimately I need the end result to be a float from 0 - 360. From what I’m gathering, trying to use quaternions (which I use elsewhere btw) in this instance would not work.
I’m effectively converting my X and Y (-1 to 1) outputs to an angle, which I feed into Mecanim to drive the animations which are blended based on the a 360’ float (i.e. 0 is forward, 90 is right, 180 is backwards, 270 left and 360 also forward). Works great, I just need some dampening somewhere.
So, your actually asking the same question that another person did yesterday, just in a different context. I took the time to throw out some script that would do this. It was applied to ai steering of a vehicle, but the math is the same.
Basically, you convert the enemies position to a local position on the same y plane. get the angle from forward to the target, then use a dot on the right to determine which side the enemy is on. This always gives you the least angle as you simply “Lerp” the angle to the target angle every frame. (It works because every frame it assumes the current angle is zero, then you lerp zero to whatever angle you need.)
it has nothing to do with that. It has to do with 1) Vector3.angle, which returns a result between 0 and 180, not 360. All you then have to know is it on hte left or right side. One side is negative, the other positive.