I have been working on this project for awhile now, and while there is always other stuff to work on, I keep coming back to this problem trying to fix it and I keep getting stuck. It's very important to the gameplay that it functions properly and it's been about a week now and I can't seem to figure it out so I've decided to see if anyone can help solve this one for me.
Now what I want is to make my units turn to the Angle I choose at a constant rate using triggers.
I am using this action to make the turns:
Unit-MakeUnitfaceAngleoverXseconds
So ideally if tell the unit to turn 180 degrees, it should take say, 3 seconds. And if I tell it to turn 60 degrees it should take 1 second.
My first attempt at modifying the action looked like this:
The problem I am running into with this: If say the Angle is say -90 and the unit is facing 90. It takes the absolute of both, and 90 - 90 = 0, and turns it instantly.
If I remove the absolute, then I run into other problems like: (-90degrees - 90degrees) / 60 = -3. Often times the game doesn't enjoy turning units in a negative amount of time. Or (180 - -180) / 60 = 6. So if you are slightly to the left it takes 6 seconds to turn, but if you are slightly to the right, it's instantly.
My other variation that seems like it has promise is instead of controlling the time it takes to make a turn, I am limiting the distance it is allowed to turn per interval.
That idea looks like this:
With Turn Speed being the number of degrees at which it should increment toward the Angle I want.
This works pretty well, it adds Turn Speed to the direction it's facing in increments of .1 seconds. Making the turn rate consistent.
However it has it's own issues.
If say, my unit is facing -175 degrees, and I want it to face the Angle of 170. In-game that is only appears 15 degree's apart, however mathematically -175degrees is less then 170degrees. So instead of going the 15 degrees I want, it goes the full 345 degrees in the opposite direction. Which is not awesome.
And for this variation, if I use absolute to solve the above problem, then it can't tell if the Angle I want is on the right or the left side since they both return positive and it usually ends up only making left turns.
If anyone can offer up a fix to either of these, or has a different suggestion entirely it would be great. As I said, I have been coming back to this problem for awhile and it's becoming apparent hat I can't get it to function on my own. Any help would be very much appreciated.
You were close with your first method. As SoulTaker said, rather than taking the difference of the absolute values, you should take the absolute value of the difference. There's a couple more things to add before it works correctly in all situations, though.
When you first obtain the difference between angles, it should be a number between -360 and 360. If either of the two angles used were not between -180 and 180, then it's possible that this difference is out of bounds. It is, however, still a valid angle. You can get it back in bounds by performing a modulo with this number as the dividend and 360 as the divisor. The result will be a number between -360 and 360 that represents exactly the same angle.
Then you can take the absolute value of that to obtain the magnitude of the turn.
However, there are two possible ways your unit can turn and we're not sure yet whether we found the long way or the short way. Fortunately, this is easy to solve for two reasons:
The correct angle you're looking for is 180 or less, as a unit cannot possibly need to turn more than 180 degrees to reach any facing.
The two possible angles are explementary (they add up to 360); if your unit can turn 270 degrees counterclockwise, it also could have turned (360 - 270) 90 degrees clockwise.
Therefore, all you have to do is check if the result is greater than 180.
If so, then you have the larger angle, and the correct smaller angle is (360 - result).
Otherwise, you already have the correct angle and nothing else needs to be done.
At this point, you can just divide the result by your turn rate to obtain the correct duration.
I've attached an example map that implements the method described. Left click anywhere and the baneling will turn to face it at 60 degrees per second. Alternatively, type any angle in chat and it will turn to face the typed angle at 120 degrees per second.
Thank you CorruptionOfLOL. I doubt anyone would have explained it any better. This could even have potential to become a tutorial for all those people who are working on vehicle-type maps, where turning rate and direction a significant role.
@SoulTaker916: Go
Yup, I was taking the absolute wrong, I think at one point I had it setup this way but I had changed it back because it still wasn't working exactly right.
@CorruptionOfLOL: Go
Looking at your attached map really helped a lot.I had never used Modulo before, I doubt I would have came up with this solution on my own.
Also the description of how each part works was very useful in understanding what was going on. I was able to make it on my own because of that rather then just copy/paste your code. Thank you very much.
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
I have been working on this project for awhile now, and while there is always other stuff to work on, I keep coming back to this problem trying to fix it and I keep getting stuck. It's very important to the gameplay that it functions properly and it's been about a week now and I can't seem to figure it out so I've decided to see if anyone can help solve this one for me.
Now what I want is to make my units turn to the Angle I choose at a constant rate using triggers.
I am using this action to make the turns:
So ideally if tell the unit to turn 180 degrees, it should take say, 3 seconds. And if I tell it to turn 60 degrees it should take 1 second.
My first attempt at modifying the action looked like this:
The problem I am running into with this: If say the Angle is say -90 and the unit is facing 90. It takes the absolute of both, and 90 - 90 = 0, and turns it instantly.
If I remove the absolute, then I run into other problems like: (-90degrees - 90degrees) / 60 = -3. Often times the game doesn't enjoy turning units in a negative amount of time. Or (180 - -180) / 60 = 6. So if you are slightly to the left it takes 6 seconds to turn, but if you are slightly to the right, it's instantly.
My other variation that seems like it has promise is instead of controlling the time it takes to make a turn, I am limiting the distance it is allowed to turn per interval. That idea looks like this:
With Turn Speed being the number of degrees at which it should increment toward the Angle I want.
This works pretty well, it adds Turn Speed to the direction it's facing in increments of .1 seconds. Making the turn rate consistent. However it has it's own issues. If say, my unit is facing -175 degrees, and I want it to face the Angle of 170. In-game that is only appears 15 degree's apart, however mathematically -175degrees is less then 170degrees. So instead of going the 15 degrees I want, it goes the full 345 degrees in the opposite direction. Which is not awesome.
And for this variation, if I use absolute to solve the above problem, then it can't tell if the Angle I want is on the right or the left side since they both return positive and it usually ends up only making left turns.
If anyone can offer up a fix to either of these, or has a different suggestion entirely it would be great. As I said, I have been coming back to this problem for awhile and it's becoming apparent hat I can't get it to function on my own. Any help would be very much appreciated.
put Absolute(angle - Angle)/60 cause all u want is the absolute value of the difference.
not abs(angle)-abs(angle)/60 which is the difference of the absolute values
@AstralCV: Go
You were close with your first method. As SoulTaker said, rather than taking the difference of the absolute values, you should take the absolute value of the difference. There's a couple more things to add before it works correctly in all situations, though.
When you first obtain the difference between angles, it should be a number between -360 and 360. If either of the two angles used were not between -180 and 180, then it's possible that this difference is out of bounds. It is, however, still a valid angle. You can get it back in bounds by performing a modulo with this number as the dividend and 360 as the divisor. The result will be a number between -360 and 360 that represents exactly the same angle.
Then you can take the absolute value of that to obtain the magnitude of the turn.
However, there are two possible ways your unit can turn and we're not sure yet whether we found the long way or the short way. Fortunately, this is easy to solve for two reasons:
Therefore, all you have to do is check if the result is greater than 180. If so, then you have the larger angle, and the correct smaller angle is (360 - result). Otherwise, you already have the correct angle and nothing else needs to be done.
At this point, you can just divide the result by your turn rate to obtain the correct duration.
I've attached an example map that implements the method described. Left click anywhere and the baneling will turn to face it at 60 degrees per second. Alternatively, type any angle in chat and it will turn to face the typed angle at 120 degrees per second.
Thank you CorruptionOfLOL. I doubt anyone would have explained it any better. This could even have potential to become a tutorial for all those people who are working on vehicle-type maps, where turning rate and direction a significant role.
@SoulTaker916: Go Yup, I was taking the absolute wrong, I think at one point I had it setup this way but I had changed it back because it still wasn't working exactly right.
@CorruptionOfLOL: Go Looking at your attached map really helped a lot.I had never used Modulo before, I doubt I would have came up with this solution on my own.
Also the description of how each part works was very useful in understanding what was going on. I was able to make it on my own because of that rather then just copy/paste your code. Thank you very much.