I've come up with what I though was a good way to get a set of units of variable number to properly orbit my hero unit. So far, I have only made one of the five eventual types of units that will do this, which is why there's triggers there that don't do anything yet.
However in game the units seem to run around and back and forth with one of them occasionally moving out to the outer orbit for a few increments and then. Well, I'm hoping somebody can spot the problem.
FigmentsEventsTimer-Every5.0secondsofGameTimeLocalVariablesExistingFigments=0<Integer[10]>
PlayerLesserFigments = (Empty unit group) <UnitGroup[10]>
PlayerGreaterFigments = (Empty unit group) <UnitGroup[10]>
PlayerAllFigments = (Empty unit group) <UnitGroup[10]>
OrbitStep = 0 <Integer>
LesserOrbitOffset = 0.0 <Real[10]>
GreaterOrbitOffset = 0.0 <Real[10]>
OrbitOffsetMultiplier = 1 <Integer>
Conditions
Actions
------- Counts
Player Group - Pick each player in (Active Players) and do (Actions)
Actions
General - If (Conditions) then do (Actions) else do (Actions)
If
(Picked player) < 9(Pickedplayer)> 0
Then
Unit Group - Pick each unit in (Shadowy Figment units in (Entire map) owned by player (Picked player) matching Excluded: Missile, Dead, Hidden, with at most Any Amount) and do (Actions)
Actions
Unit Group - Add (Picked unit) to PlayerLesserFigments[(Pickedplayer)]
Variable - Set ExistingFigments[(Pickedplayer)] = ((Number of Living units in PlayerLesserFigments[(Pickedplayer)]) + (Number of Living units in PlayerGreaterFigments[(Pickedplayer)]))
General - If (Conditions) then do (Actions) else do (Actions)
If
(Number of Living units in PlayerLesserFigments[(Pickedplayer)]) > 1
Then
Variable - Set LesserOrbitOffset[(Pickedplayer)] = (360.0 / (Real((Number of Living units in PlayerLesserFigments[(Pickedplayer)]))))
Else
General - If (Conditions) then do (Actions) else do (Actions)
If
(Number of Living units in PlayerGreaterFigments[(Pickedplayer)]) > 1
Then
Variable - Set GreaterOrbitOffset[(Pickedplayer)] = (360.0 / (Real((Number of Living units in PlayerGreaterFigments[(Pickedplayer)]))))
Else
Else
------- Movement --------------------------------------------------------------------------------------------------------
General - For each integer OrbitStep from 1 to 10 with increment 1, do (Actions)
Actions
Player Group - Pick each player in (Active Players) and do (Actions)
Actions
Variable - Set OrbitOffsetMultiplier = 1
Unit Group - Pick each unit in PlayerLesserFigments[(Pickedplayer)] and do (Actions)
Actions
Unit - Order (Picked unit) to ( Move targeting ((Position of playerCharacter[(Pickedplayer)]) offset by 3.0 towards ((Real(OrbitStep)) * (FigmentOrbitSeed + (LesserOrbitOffset[(Pickedplayer)] * (Real(OrbitOffsetMultiplier))))) degrees)) (Replace Existing Orders)
Variable - Modify OrbitOffsetMultiplier: + 1
Variable - Set OrbitOffsetMultiplier = 1
Unit Group - Pick each unit in PlayerGreaterFigments[(Pickedplayer)] and do (Actions)
Actions
Unit - Order (Picked unit) to ( Move targeting ((Position of playerCharacter[(Pickedplayer)]) offset by 5.0 towards ((Real((OrbitStep * -1))) * (FigmentOrbitSeed + (GreaterOrbitOffset[(Pickedplayer)] * (Real(OrbitOffsetMultiplier))))) degrees)) (Replace Existing Orders)
Variable - Modify OrbitOffsetMultiplier: + 1
General - Wait 0.5 Game Time seconds
It's hard to spot a smoking gun in your problem, but a few comments:
1) You're going to have to take unit speed into account in your calculations. If the unit can't reach the targetted position by the time the loop continues and the next order is issued, it's going to get funky. He'll always be trying to catch up, and basically stay inside the circle. You could consider using the action 'move unit to point over X seconds', with X = your loop wait time (0.5 seconds.) This would take that variable out of the equation, but might give you other problems (ignores pathing? wouldn't animate?)
2) Every 5 seconds you consider the number of elements and do your calculations, then issue orders based off those for 5 seconds, and then after 5 seconds start another loop. Also I wonder if it's possible that at the end of the 5 seconds, a new trigger instance is created and starts doing this as the previous instance is still finishing? Their orders would conflict and you'd get random running.
Also when the loop starts over, there's no continuity between the instances, so the orders between the loops won't match up and you'll again get some random running. Maybe thats why you're getting back and forth?
I think if you switch the move order to 'move unit to position X over 0.5 seconds' it may help you more clearly see what's going on and debug this. I might limit this trigger to only have one instance - just start it on map initialization or hero selection complete or whatever is the right time, and then run it indefinately, and calculate your radius and number of units etc every update. Then you can keep your loop iterator always. You'll need to mod your values now and then once they cycle past 360 degrees (or rather reset the iterator once it passes the number of units in the circle.)
1) You're going to have to take unit speed into account in your calculations. If the unit can't reach the targetted position by the time the loop continues and the next order is issued, it's going to get funky.
I've already tested this with a single unit and much simpler version of the trigger, but essentially the same path, and the unit orbited perfectly.
Quote:
2) Every 5 seconds you consider the number of elements and do your calculations, then issue orders based off those for 5 seconds, and then after 5 seconds start another loop. Also I wonder if it's possible that at the end of the 5 seconds, a new trigger instance is created and starts doing this as the previous instance is still finishing? Their orders would conflict and you'd get random running.
I tested this too and its not the case. As with the much simpler version of the trigger, I confirmed that it runs and completes exactly .5 seconds before the next iteration of the trigger.
Quote:
Also when the loop starts over, there's no continuity between the instances, so the orders between the loops won't match up and you'll again get some random running. Maybe thats why you're getting back and forth?
As was proven with the simpler version of the trigger, the unit indeed makes one full revolution each time the trigger runs, and that is based off of an external global value. The orbits should only stutter when a unit is added in or taken out.
With the single unit version of the trigger, it worked perfectly with no complications or issues. So the issue being with the unit is pretty much ruled out. Therefore, there must be something wrong with my math.
Alright, I found one problem. I realized that FigmentOrbitSeed needed to be a fixed value based on the number of iterations in the loop. I took out the variable and replaced it with a flat value of 36.0 degrees.
Now, one of the units orbits properly, but for some reason, only one, no matter how many there are. That shouldn't be possible. Either they should all orbit, or none of them should, but after making that one change to the above trigger, one unit now orbits correctly while the rest run back and forth chaotically.
I've come up with what I though was a good way to get a set of units of variable number to properly orbit my hero unit. So far, I have only made one of the five eventual types of units that will do this, which is why there's triggers there that don't do anything yet.
However in game the units seem to run around and back and forth with one of them occasionally moving out to the outer orbit for a few increments and then. Well, I'm hoping somebody can spot the problem.
It's hard to spot a smoking gun in your problem, but a few comments:
1) You're going to have to take unit speed into account in your calculations. If the unit can't reach the targetted position by the time the loop continues and the next order is issued, it's going to get funky. He'll always be trying to catch up, and basically stay inside the circle. You could consider using the action 'move unit to point over X seconds', with X = your loop wait time (0.5 seconds.) This would take that variable out of the equation, but might give you other problems (ignores pathing? wouldn't animate?)
2) Every 5 seconds you consider the number of elements and do your calculations, then issue orders based off those for 5 seconds, and then after 5 seconds start another loop. Also I wonder if it's possible that at the end of the 5 seconds, a new trigger instance is created and starts doing this as the previous instance is still finishing? Their orders would conflict and you'd get random running.
Also when the loop starts over, there's no continuity between the instances, so the orders between the loops won't match up and you'll again get some random running. Maybe thats why you're getting back and forth?
I think if you switch the move order to 'move unit to position X over 0.5 seconds' it may help you more clearly see what's going on and debug this. I might limit this trigger to only have one instance - just start it on map initialization or hero selection complete or whatever is the right time, and then run it indefinately, and calculate your radius and number of units etc every update. Then you can keep your loop iterator always. You'll need to mod your values now and then once they cycle past 360 degrees (or rather reset the iterator once it passes the number of units in the circle.)
Hope this helps :)
I've already tested this with a single unit and much simpler version of the trigger, but essentially the same path, and the unit orbited perfectly.
I tested this too and its not the case. As with the much simpler version of the trigger, I confirmed that it runs and completes exactly .5 seconds before the next iteration of the trigger.
As was proven with the simpler version of the trigger, the unit indeed makes one full revolution each time the trigger runs, and that is based off of an external global value. The orbits should only stutter when a unit is added in or taken out.
With the single unit version of the trigger, it worked perfectly with no complications or issues. So the issue being with the unit is pretty much ruled out. Therefore, there must be something wrong with my math.
It doesn't, but thanks for trying.
Alright, I found one problem. I realized that FigmentOrbitSeed needed to be a fixed value based on the number of iterations in the loop. I took out the variable and replaced it with a flat value of 36.0 degrees.
Now, one of the units orbits properly, but for some reason, only one, no matter how many there are. That shouldn't be possible. Either they should all orbit, or none of them should, but after making that one change to the above trigger, one unit now orbits correctly while the rest run back and forth chaotically.
So, what's still wrong?