• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Calculate unit movement path

Status
Not open for further replies.
Level 4
Joined
Nov 13, 2019
Messages
47
Is there a way to know how a unit will move ahead of time when you issue an order?

I'm creating a turn based map and would like to create a trail to where the unit is going to move before he does it.

Example

ijiocwqcr9lz.png



Here's my attempt at doing this:






  • CreateTrail
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • (Ordered unit) Not equal to PreviousTrailPoint
      • MoveOrderCooldown Equal to False
    • Actions
      • Unit - Move (Ordered unit) instantly to (Position of (Ordered unit)), facing (Target point of issued order)
      • Set VariableSet MoveOrderCooldown = True
      • Set VariableSet TargetTrailEnd = (Target point of issued order)
      • Set VariableSet OrderedHero = (Ordered unit)
      • Set VariableSet PreviousTrailPoint = (Ordered unit)
      • Unit Group - Pick every unit in TrailGroup and do (Unit - Remove (Picked unit) from the game)
      • Unit - Set OrderedHero movement speed to 0.00
      • Trigger - Add Create Trail Point <gen> to the trigger queue (Checking conditions)
      • Set VariableSet MoveOrderCooldown = False
  • Create Trail Point
    • Events
    • Conditions
    • Actions
      • Wait 0.10 seconds
      • Unit - Create 1.Trail Point for (Owner of (Ordered unit)) at ((Position of PreviousTrailPoint) offset by 300.00 towards (Facing of PreviousTrailPoint) degrees.) facing (Facing of PreviousTrailPoint) degrees
      • Animation - Change (Last created unit)'s vertex coloring to (100.00%, 0.00%, 0.00%) with 0.00% transparency
      • Set VariableSet PreviousTrailPoint = (Last created unit)
      • Unit - Order PreviousTrailPoint to Move To.TargetTrailEnd
      • Unit - Set PreviousTrailPoint movement speed to 0.00
      • Unit Group - Add PreviousTrailPoint to TrailGroup
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Distance between (Position of PreviousTrailPoint) and TargetTrailEnd) Greater than 350.00
        • Then - Actions
          • Trigger - Add (This trigger) to the trigger queue (Checking conditions)
        • Else - Actions
          • Unit - Create 1.Trail End for (Owner of (Ordered unit)) at TargetTrailEnd facing (Facing of PreviousTrailPoint) degrees
          • Animation - Change (Last created unit)'s vertex coloring to (100.00%, 0.00%, 0.00%) with 0.00% transparency
          • Unit Group - Add (Last created unit) to TrailGroup
      • Trigger - Remove (This trigger) from the trigger queue

Basically each trail point is its own unit which I order to move toward the targeted order point (without move speed it only turns and doesnt actually move), that way it faces more or less in the right direction and I create a new trail point unit 300 units in front of it. Rinse and repeat until the distance between the last point and the target order point is less than 300.

However, this way is limited by the turn speed of units in WC3 and I MUST wait at least 0.10 seconds in between for it to have enough time to turn. Also, without wait time the the loop crashes the game.

Are there any other/better ways of achieving the same thing? Any help appreciated.
 
Level 19
Joined
Aug 16, 2007
Messages
881
If possible, you could try to implement A*, there might already be a resource available for this.

A* search algorithm - Wikipedia

Example of how it works:
Astar_progress_animation.gif


If you plan on keeping your current system I'd do the following instead:

Instead of using waits, I'd use a periodic timer, running every 0.01s, updating the path.
The unit(s) might not be able to turn fast enough, so the timer might have to be increased.

I'd also only use 1 dummy unit for the trail and keep moving this unit towards the end location.
With the natives:
call SetUnitX(whichUnit, xPosition)
call SetUnitY(whichUnit, yPosition)
you can move the unit freely without interupting its current order. So it will move and turn on its own, while you move it via trigger. This way you may also move the unit faster than the maximum unit speed.

Keep in mind that pathing could be an issue when you move the unit this way as it ignores obstacles, so an external check will have to be made.

Your current system also leak several locations, you can learn how to remove them here: Things That Leak
 
Last edited:
Level 4
Joined
Nov 13, 2019
Messages
47
If possible, you could try to implement A*, there might already be a resource available for this.

A* search algorithm - Wikipedia

Example of how it works:
Astar_progress_animation.gif


If you plan on keeping your current system I'd do the following instead:

Instead of using waits, I'd use a periodic timer, running every 0.01s, updating the path.
The unit(s) might not be able to turn fast enough, so the timer might have to be increased.

I'd also only use 1 dummy unit for the trail and keep moving this unit towards the end location.
With the natives:
call SetUnitX(whichUnit, xPosition)
call SetUnitY(whichUnit, yPosition)
you can move the unit freely without interupting its current order. So it will move and turn on its own, while you move it via trigger. This way you may also move the unit faster than the maximum unit speed.

Keep in mind that pathing could be an issue when you move the unit this way as it ignores obstacles, so an external check will have to be made.

Your current system also leak several locations, you can learn how to remove them here: Things That Leak
Thanks for the tips. I think A* is way beyond my skill level both in math and triggering though.

I tried running it on a periodic timer like you suggested, but for whatever reason it doesn't spawn the units, or it does, but they are invisible and they end up at the center of the map.

  • CreateTrail
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • (Ordered unit) Not equal to PreviousTrailPoint
      • MoveOrderCooldown Equal to False
    • Actions
      • Set VariableSet MoveOrderCooldown = True
      • Unit - Move (Ordered unit) instantly to (Position of (Ordered unit)), facing (Target point of issued order)
      • Set VariableSet TargetTrailEnd = (Target point of issued order)
      • Set VariableSet OrderedHero = (Ordered unit)
      • Set VariableSet PreviousTrailPoint = (Ordered unit)
      • Unit Group - Pick every unit in TrailGroup and do (Unit - Remove (Picked unit) from the game)
      • Unit - Set OrderedHero movement speed to 0.00
      • Trigger - Turn on Create Trail Point <gen>
      • Set VariableSet MoveOrderCooldown = False
  • Create Trail Point
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Game - Display to (All players) the text: created trail
      • Unit - Create 1.Trail Point for (Owner of (Ordered unit)) at ((Position of PreviousTrailPoint) offset by 300.00 towards (Facing of PreviousTrailPoint) degrees.) facing (Facing of PreviousTrailPoint) degrees
      • Animation - Change (Last created unit)'s vertex coloring to (100.00%, 0.00%, 0.00%) with 0.00% transparency
      • Set VariableSet PreviousTrailPoint = (Last created unit)
      • Unit - Order PreviousTrailPoint to Move To.TargetTrailEnd
      • Unit - Set PreviousTrailPoint movement speed to 0.00
      • Unit Group - Add PreviousTrailPoint to TrailGroup
      • Camera - Pan camera for Player 1 (Red) to (Position of (Last created unit)) over 0.00 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Distance between (Position of PreviousTrailPoint) and TargetTrailEnd) Greater than 350.00
        • Then - Actions
        • Else - Actions
          • Unit - Create 1.Trail End for (Owner of (Ordered unit)) at TargetTrailEnd facing (Facing of PreviousTrailPoint) degrees
          • Animation - Change (Last created unit)'s vertex coloring to (100.00%, 0.00%, 0.00%) with 0.00% transparency
          • Unit Group - Add (Last created unit) to TrailGroup
          • Trigger - Turn off (This trigger)
The camera panning was added just so I could see where they spawned, which is nowhere (center of map). Am I doing something wrong?
 
Level 7
Joined
Jul 4, 2007
Messages
249
I order to move toward the targeted order point (without move speed it only turns and doesnt actually move)
I didn't really look through your triggers but if all you want it to do is turn instantly just use this?
  • Unit - Make unit face point over 0.00 seconds
However, this way is limited by the turn speed of units in WC3 and I MUST wait at least 0.10 seconds in between for it to have enough time to turn.
You should be able to set turn rate to extremely high from what I've experienced.

Off-topic: Really cool that you're making a HoMM map, I love this game and I look forward to playing your map when it's done :D It actually fits very well with this engine, keep it up man!
 
Last edited:
Level 19
Joined
Aug 16, 2007
Messages
881
Thanks for the tips. I think A* is way beyond my skill level both in math and triggering though.

I tried running it on a periodic timer like you suggested, but for whatever reason it doesn't spawn the units, or it does, but they are invisible and they end up at the center of the map.

  • CreateTrail
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • (Ordered unit) Not equal to PreviousTrailPoint
      • MoveOrderCooldown Equal to False
    • Actions
      • Set VariableSet MoveOrderCooldown = True
      • Unit - Move (Ordered unit) instantly to (Position of (Ordered unit)), facing (Target point of issued order)
      • Set VariableSet TargetTrailEnd = (Target point of issued order)
      • Set VariableSet OrderedHero = (Ordered unit)
      • Set VariableSet PreviousTrailPoint = (Ordered unit)
      • Unit Group - Pick every unit in TrailGroup and do (Unit - Remove (Picked unit) from the game)
      • Unit - Set OrderedHero movement speed to 0.00
      • Trigger - Turn on Create Trail Point <gen>
      • Set VariableSet MoveOrderCooldown = False
  • Create Trail Point
    • Events
      • Time - Every 1.00 seconds of game time
    • Conditions
    • Actions
      • Game - Display to (All players) the text: created trail
      • Unit - Create 1.Trail Point for (Owner of (Ordered unit)) at ((Position of PreviousTrailPoint) offset by 300.00 towards (Facing of PreviousTrailPoint) degrees.) facing (Facing of PreviousTrailPoint) degrees
      • Animation - Change (Last created unit)'s vertex coloring to (100.00%, 0.00%, 0.00%) with 0.00% transparency
      • Set VariableSet PreviousTrailPoint = (Last created unit)
      • Unit - Order PreviousTrailPoint to Move To.TargetTrailEnd
      • Unit - Set PreviousTrailPoint movement speed to 0.00
      • Unit Group - Add PreviousTrailPoint to TrailGroup
      • Camera - Pan camera for Player 1 (Red) to (Position of (Last created unit)) over 0.00 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Distance between (Position of PreviousTrailPoint) and TargetTrailEnd) Greater than 350.00
        • Then - Actions
        • Else - Actions
          • Unit - Create 1.Trail End for (Owner of (Ordered unit)) at TargetTrailEnd facing (Facing of PreviousTrailPoint) degrees
          • Animation - Change (Last created unit)'s vertex coloring to (100.00%, 0.00%, 0.00%) with 0.00% transparency
          • Unit Group - Add (Last created unit) to TrailGroup
          • Trigger - Turn off (This trigger)
The camera panning was added just so I could see where they spawned, which is nowhere (center of map). Am I doing something wrong?

I think the issue is that the owner you attempt to create the unit for is null as you reference "(Owner of (Ordered unit))", not the variable you have set for the ordered unit, "OrderedHero".
 
Level 4
Joined
Nov 13, 2019
Messages
47
I didn't really look through your triggers but if all you want it to do is turn instantly just use this?
  • Unit - Make unit face point over 0.00 seconds
You should be able to set turn rate to extremely high from what I've experienced.

Off-topic: Really cool that you're making a HoMM map, I love this game and I look forward to playing your map when it's done :D It actually fits very well with this engine, keep it up man!

I can't turn them manually because I want the unit it self to decide where to turn, that's what makes it work. I don't know what the right turn direction is at any given moment so the AI decides for me.
As far as my research goes 3.00 turn rate is the quickest, but if there are any other ways please share :p

Here is A* implemented in wc3 (ignore the 'unsafe site' warning if you get one, it's from wc3c's customized vB code): PAS (Pathing Algorithm System) - Wc3C.net

Thanks, I'll check that one out if I can get my browser let me download it.
Edit: Downloaded it but WC3R beta doesnt want to run it. (Stuck on the Lion head screen)
 
Last edited:
Level 4
Joined
Nov 13, 2019
Messages
47
I think the issue is that the owner you attempt to create the unit for is null as you reference "(Owner of (Ordered unit))", not the variable you have set for the ordered unit, "OrderedHero".
Ah nice, that was it. It works now and it feels a bit smoother, but I still needed to set the periodic timer to 0.15 to give the points time to turn.
 
Level 7
Joined
Jul 4, 2007
Messages
249
I can't turn them manually because I want the unit it self to decide where to turn, that's what makes it work. I don't know what the right turn direction is at any given moment so the AI decides for me.
As far as my research goes 3.00 turn rate is the quickest, but if there are any other ways please share :p
I see. Maybe there's a way of speeding the turn rate up by "helping it out", for example:
Every 0.01 seconds you check in which way the last turn was, you first add a great amount to that direction and order the unit to move again, if it changes direction turn down the change amount and repeat the action. This way it will always get closer to the desired angle, and when the change amount gets under a certain value (close to +-0 of desired angle) you let the unit turn by itself.
 
Status
Not open for further replies.
Top