- Joined
- Apr 12, 2019
- Messages
- 699
I would like a question, when a hero uses Shockwave ability, the hero charges forward to a designated location. Is there any solution?
ThanksYou need to trigger it. You will have to check the hero's location and update it every frame to a new location. You can either stop when the hero reaches the designated location or when the hero has traveled for X distance.
The basic functional trigger with the most barebone logic will look like this:
Charge
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Charge
Actions
-------- Store the caster --------
Set Charge_Caster = (Triggering unit)
-------- Store the location where he's currently at --------
Set Charge_CasterLocation = (Position of Charge_Caster)
-------- Store the location where the ability is casted at --------
Set Charge_TargetLocation = (Target point of ability being cast)
-------- Store the angle between these two locations --------
Set Charge_Angle = (Angle from Charge_CasterLocation to Charge_TargetLocation)
-------- Continue to the next trigger (Charge Loop is initially off) --------
Trigger - Turn on Charge Loop <gen>
But this is not MUI, meaning if you have multiple units casting this ability, it will not work properly. This is due to how the variables are being overwritten whenever the trigger runs.
Charge Loop
Events
Time - Every 0.03 seconds of game time
Conditions
Actions
-------- Store the location where he's currently at --------
Set Charge_CasterLocation = (Position of Charge_Caster)
-------- Store the location where he's going to be in the next frame --------
Set Charge_CasterNewLocation = (Charge_Location1 offset by 33.00 towards Charge_Angle degrees)
-------- Move the guy --------
Unit - Move Charge_Caster instantly to Charge_CasterNewLocation
-------- Check if he's getting close to the designated location --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Distance between Charge_CasterNewLocation and Charge_TargetLocation) Less than or equal to 100.00
Then - Actions
-------- When he does get close, turn off this trigger to stop the movement --------
Trigger - Turn off (This trigger)
Else - Actions
To make this MUI, we need to organize the data flow with multiple units in mind. The most beginner friendly and probably easiest method to understand is a technique known as Dynamic Indexing, the tutorial can be found here: Visualize: Dynamic Indexing
Charge MUI
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Charge MUI
Actions
-------- Everytime the ability is casted, we increase the index by 1 --------
Set Charge_MaxIndex = (Charge_MaxIndex + 1)
-------- We assign the index to the caster variable so each caster will have different indexes --------
Set Charge_CasterArray[Charge_MaxIndex] = (Triggering unit)
-------- Store the location where he's currently at, just like before --------
Set Charge_CasterLocation = (Position of Charge_CasterArray[Charge_MaxIndex])
-------- Store the location where the ability is casted at, each caster could have different target location --------
Set Charge_TargetLocationArray[Charge_MaxIndex] = (Target point of ability being cast)
-------- Store the angle between these two locations --------
Set Charge_AngleArray[Charge_MaxIndex] = (Angle from Charge_CasterLocation to Charge_TargetLocationArray[Charge_MaxIndex])
-------- If it is the first index then --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Charge_MaxIndex Equal to 1
Then - Actions
-------- Continue to the next trigger (Charge Loop is initially off) --------
Trigger - Turn on Charge MUI Loop <gen>
Else - Actions
When you store a location into a variable, you're creating a new location object. This will consume memory. When you store another location into that same variable (overwriting it) without destroying the previous location object, you will lose reference to the previous location but that previous location is still being kept in the memory, thus causing a memory leak.
Charge MUI Loop
Events
Time - Every 0.03 seconds of game time
Conditions
Actions
-------- Loop through all the indexes --------
For each (Integer Charge_CurrentIndex) from 1 to Charge_MaxIndex, do (Actions)
Loop - Actions
-------- Store the location where he's currently at --------
Set Charge_CasterLocation = (Position of Charge_CasterArray[Charge_CurrentIndex])
-------- Store the location where he's going to be in the next frame --------
Set Charge_CasterNewLocation = (Charge_CasterLocation offset by 33.00 towards Charge_AngleArray[Charge_CurrentIndex] degrees)
-------- Move the guy --------
Unit - Move Charge_CasterArray[Charge_CurrentIndex] instantly to Charge_CasterNewLocation
-------- Check if he's getting close to the designated location --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Distance between Charge_CasterLocation and Charge_TargetLocationArray[Charge_CurrentIndex]) Less than or equal to 100.00
Then - Actions
-------- When he does get close, we recycle the index --------
Set Charge_TargetLocationArray[Charge_CurrentIndex] = Charge_TargetLocationArray[Charge_MaxIndex]
Set Charge_CasterArray[Charge_CurrentIndex] = Charge_CasterArray[Charge_MaxIndex]
Set Charge_CasterArray[Charge_MaxIndex] = No unit
Set Charge_AngleArray[Charge_CurrentIndex] = Charge_AngleArray[Charge_MaxIndex]
Set Charge_AngleArray[Charge_MaxIndex] = 0.00
Set Charge_CurrentIndex = (Charge_CurrentIndex - 1)
Set Charge_MaxIndex = (Charge_MaxIndex - 1)
-------- Turn the trigger off when there is no more active indexes --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Charge_MaxIndex Equal to 0
Then - Actions
Trigger - Turn off (This trigger)
Else - Actions
Else - Actions
Read more about Memory Leak here: Memory Leaks
You need to prevent this by using a custom script like this
call RemoveLocation will destroy the previous location object. Don't forget the prefix udg_ before your variable name.
Custom script: call RemoveLocation(udg_YourLocationVariableName)
So we will end up with this trigger:
Charge MUI
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Charge MUI
Actions
-------- Everytime the ability is casted, we increase the index by 1 --------
Set Charge_MaxIndex = (Charge_MaxIndex + 1)
-------- We assign the index to the caster variable so each caster will have different indexes --------
Set Charge_CasterArray[Charge_MaxIndex] = (Triggering unit)
-------- Store the location where he's currently at, just like before --------
Set Charge_CasterLocation = (Position of Charge_CasterArray[Charge_MaxIndex])
-------- Store the location where the ability is casted at, each caster could have different target location --------
Set Charge_TargetLocationArray[Charge_MaxIndex] = (Target point of ability being cast)
-------- Store the angle between these two locations --------
Set Charge_AngleArray[Charge_MaxIndex] = (Angle from Charge_CasterLocation to Charge_TargetLocationArray[Charge_MaxIndex])
-------- If it is the first index then --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Charge_MaxIndex Equal to 1
Then - Actions
-------- Continue to the next trigger (Charge Loop is initially off) --------
Trigger - Turn on Charge MUI Loop <gen>
Else - Actions
-------- Prevent memory leaks --------
Custom script: call RemoveLocation(udg_Charge_CasterLocation)
Charge MUI Loop
Events
Time - Every 0.03 seconds of game time
Conditions
Actions
-------- Loop through all the indexes --------
For each (Integer Charge_CurrentIndex) from 1 to Charge_MaxIndex, do (Actions)
Loop - Actions
-------- Store the location where he's currently at --------
Set Charge_CasterLocation = (Position of Charge_CasterArray[Charge_CurrentIndex])
-------- Store the location where he's going to be in the next frame --------
Set Charge_CasterNewLocation = (Charge_CasterLocation offset by 33.00 towards Charge_AngleArray[Charge_CurrentIndex] degrees)
-------- Move the guy --------
Unit - Move Charge_CasterArray[Charge_CurrentIndex] instantly to Charge_CasterNewLocation
-------- Check if he's getting close to the designated location --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Distance between Charge_CasterLocation and Charge_TargetLocationArray[Charge_CurrentIndex]) Less than or equal to 100.00
Then - Actions
-------- Prevent memory leak --------
Custom script: call RemoveLocation(udg_Charge_TargetLocationArray[udg_Charge_CurrentIndex])
-------- When he does get close, we recycle the index --------
Set Charge_TargetLocationArray[Charge_CurrentIndex] = Charge_TargetLocationArray[Charge_MaxIndex]
Set Charge_CasterArray[Charge_CurrentIndex] = Charge_CasterArray[Charge_MaxIndex]
Set Charge_CasterArray[Charge_MaxIndex] = No unit
Set Charge_AngleArray[Charge_CurrentIndex] = Charge_AngleArray[Charge_MaxIndex]
Set Charge_AngleArray[Charge_MaxIndex] = 0.00
Set Charge_CurrentIndex = (Charge_CurrentIndex - 1)
Set Charge_MaxIndex = (Charge_MaxIndex - 1)
-------- Turn the trigger off when there is no more active indexes --------
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Charge_MaxIndex Equal to 0
Then - Actions
Trigger - Turn off (This trigger)
Else - Actions
Else - Actions
-------- Prevent memory leaks --------
Custom script: call RemoveLocation(udg_Charge_CasterLocation)
Custom script: call RemoveLocation(udg_Charge_CasterNewLocation)