There is a way.
You would need Jass though.
In Jass the GUI Regions are actually Rects, and you can create local rects, and add them to a local region and then dynamically create a trigger that checks if a unit enters this region.
Only issue in that case would be to destroy the rect once not needed anymore.
Other possibility to simulate a movement in a direction with buildings using something like my build wall function i mentioned earlier. The only problem it has is the movement would be instant. To make it move at a normal speed following the cells, all we'd need is create a repeatable timer.When the timer expires, move the unit to the new position, then start the timer again, until the destination is reached.
This of course would require to save some values in a hashtable using the handle id of the timer as a parent key. But this would be doable.
EDIT :
If anyone is interested and can read Jass, here is my Build Wall ability trigger :
JASS:
function BuildTheWall takes nothing returns boolean
local unit blockingTower=null
local unit newTower=null
local player owner=null
local integer goldLeft
local real oX
local real oY
local real tX
local real tY
local real incX
local real incY
local real sX
local real sY
local real angle
if (GetSpellAbilityId() == BBTWID) then
set blockingTower=GetSpellAbilityUnit()
set owner=GetOwningPlayer(blockingTower)
set goldLeft=GetPlayerState(owner, PLAYER_STATE_RESOURCE_GOLD)
set oX=GetUnitX(blockingTower)
set oY=GetUnitY(blockingTower)
set blockingTower=null
set tX=GetSpellTargetX()
set tY=GetSpellTargetY()
loop
set angle=bj_RADTODEG*Atan2(tY-oY,tX-oX)
if (angle<0) then
set angle=angle+360.00
endif
set angle=Round(angle/22.50)*22.50
if (angle>=0.00) and (angle<=180.00) then
set sY=1.00
else
set sY=- 1.00
endif
if ((angle>=270.00) and (angle<=360.00)) or ((angle>=0) and (angle<=90.00)) then
set sX=1.00
else
set sX=- 1.00
endif
if (angle != 180.00) then
set angle=ModuloReal(angle, 180.00)
endif
if (angle==0.00) or (angle==180.00) then
set incX=WallSize
set incY=0
endif
if (angle==22.50) or (angle==157.50) then
set incX=WallSize
set incY=WallSize / 2.00
endif
if (angle==45.00) or (angle==135.00) then
set incX=WallSize
set incY=WallSize
endif
if (angle==67.5) or (angle==112.50) then
set incX=WallSize / 2.00
set incY=WallSize
endif
if (angle==90) then
set incX=0
set incY=WallSize
endif
exitwhen ((tX-oX)*(tX-oX)+(tY-oY)*(tY-oY)<WallSize*WallSize) or (goldLeft<1)
set oX=oX+sX*incX
set oY=oY+sY*incY
set newTower=null
set newTower=CreateUnit(owner, BlockingID, oX, oY, 270.00)
call AddUnitToStock(newTower, SellID, 1, 1)
call LinkAround(newTower , true)
if (Abs(oX-GetUnitX(newTower))>16.00) or (Abs(oY-GetUnitY(newTower))>16.00) then
call LinkAround(newTower , false)
call KillUnit(newTower)
call RemoveUnit(newTower)
else
set goldLeft=goldLeft-1
endif
set newTower=null
endloop
call SetPlayerState(owner, PLAYER_STATE_RESOURCE_GOLD, goldLeft)
set owner=null
endif
return false
endfunction
function BuildBlockingTowersWall takes nothing returns nothing
local integer i=0
local trigger buildBlockingTowersWall=CreateTrigger()
loop
if ((GetPlayerSlotState(Player(i))==PLAYER_SLOT_STATE_PLAYING)) then
call TriggerRegisterPlayerUnitEvent(buildBlockingTowersWall, Player(i), EVENT_PLAYER_UNIT_SPELL_CAST, null)
endif
set i=i+1
exitwhen i>3
endloop
call TriggerAddCondition(buildBlockingTowersWall, function BuildTheWall)
set buildBlockingTowersWall=null
endfunction
Notes :
- BBTWID is the global storing my wall ability ID, it could be replaced with a dummy "move" ability
- WallSize is a global real, I have set this value to 128.0
Note it stops building when the distance with the target is low enough or when the gold is zero, so that gold part needs to be removed.
So if instead of placing a tower at each new position, one could just store the positions in two local arrays for the coordinates like MoveX and MoveY, and putting 0 as last value when the target is reached, then create a repeatable timer, store the 2 arrays in a hashtable with the timer handle id as parent key and 0 & 1 as child keys, you can also store the unit with the child key 2.
Then have a trigger that reacts to the expiration o that timer, get the parent key back using the expired timer handle id, and as the child keys for the 2 arrays and the unit are 0, 1 and 2, you can retrieve them from the hashtable and move the unit to the next position at MovX
, MoveY.
I just realized that for this we would also need to save the index of the current move too.
Once unit is moved, we restart the timer until the coordinates are 0 (we could chose other values outside of the map in case there would be a risk to conflict with map center.
Anyways, I know this sounds really complicated, but I know it would work.
IF anyone has clever ideas for simpler ways to simulate a movement that would allow units to remain buildings, feel free to suggest it.