2D/3D Tile Grid. Moving Agents & occupying a Tile

Hi,

UPDATE:
How I could check if a Tile is occupied or not if the agents attempt to move? One Agent should move 1 Tile in a second for example. So this is kinda priority thing. So if two agents attempt to move on the same tile, the one with the higher priority is allowed to step on the tile. The other agent is forced to search for another free tile.

Blue: Enemy Spawning Position
Pink: Enemy/Agent with Seeker&AI
Red: Player (target)

I try to achieve something like this https://www.youtube.com/watch?v=4FAza7MjkQ0

The system just uses orthogonal non diagonal movement and its import that the agent follows excatly the path.
I use the AISimpleLerp for that scenario. http://pastebin.com/DvjRLQLV I changed the AISimpleLerp Class a bit to fit my needs. http://pastebin.com/x03n4rGJ
(Move and Rotation with iTween)

Do I need pro for this, I would buy it…

Regards Kevin.

I am doing this in my game as well. The simplest solution is just to create an array or List of all the occupied nodes. When something starts to move into a node, add it too the list, and after it has left, remove it. Don’t wait until the thing has fully moved into the node before adding it to the list - do it as soon as it decides it is going to (so others won’t decide to go there before it’s finished moving).
Then just check against this list whenever something is about to move or create a path somewhere.

To implement priority, the simplest solution there is to make all your higher-priority units complete their search for where they want to go before lower-priority units.

Hi,

thank you for your response. Yeah I know an array would be the proper solution to this
but I was wondering if there is a built in solution for this issue.

I read through the forums and read about GraphUpdateObjects, MovingObstacles and Penalties.
This is a thing which isn’t very well described in the docs.

First I added a Seeker, DynamicGridObstacle, and AlternatePath Script to every enemy AI.

Notice: The AlternatePath Script ist just for one of the 2 enemies active. So the second enemy will
search for a slightly different path, which looks nicer ingame.

Then in my Enemy class I will set the valid Tags for the node the enemy stands on:

public class Enemy : MonoBehaviour
 {
 // Uses AlternatePath Script yes/no
 public bool AlternatePath = false;

   public void SetTags(int tag)
   {
       var seeker = GetComponent<Seeker>();
       var dgo = GetComponent<DynamicGridObstacle>();

       // allowed Tags are 0 (==Ground) and self
       seeker.traversableTags = (1 << 0) | (1 << tag);
       dgo.myGUO.setTag = tag;
   }
}

Here is an example of my EnemyManager Script

private void SpawnEnemies()
{
	// start tag
    var tag = 5;
    foreach(var espawn in spawner) {
        var e = espawn.SpawnEnemy();

        // set different unique Tags for the ai
        e.SetTags(tag);
        tag++;
    }
}

EnemySpawner Script with Method

public Enemy SpawnEnemy()
{
  var eclone = Instantiate(enemy, transform.position + Grid.GetInstance().up, Quaternion.Euler(0, -180, 0)) as Enemy;

  if (!AlternatePath)
  {
      var ap = eclone.gameObject.GetComponent<AlternativePath>();
      ap.enabled = false;
  }
  else
  {
      eclone.AlternatePath = true;
  }

  return eclone;
}

And finally a new EnemyGuo Class to allow the modification of the GraphUpdateObject
(I also replaced the EnemyGuo with the default Guo in DynamicGridObstacle Class)

public class EnemyGuo : GraphUpdateObject {

public EnemyGuo () {
    Init();
}

/** Creates a new GUO with the specified bounds */
public EnemyGuo(Bounds b) : base(b) {
    Init();
}

private void Init()
{
    updatePhysics = false;
    modifyTag = true;
}

}

Conclusion:
The solutions above works but the way to achieve such an task with A* Project is really complex (for Tile Grid based Games), so finally I decided to move to another easier solutions (probably without A* Project).

Regards Kevin

Hi

Sorry, there is no built in solution to this (at least not one that would be robust, you do not want them to sometimes be able to step on the same square just because there was a 1 or 2 frame delay until a graph update was applied for example).

The solution that @dasbin mentioned is probably the easiest solution to build. If you use the AISimpleLerp script you can check if the node that it is about to enter is occupied, and if it is not, then mark it as occupied, if it is, stop immediately and replan. I have been working on some turn based utilities which are similar to what is needed here, however I need some more time to make sure that they are stable (mostly multithreading race conditions that need to be prevented which still keeping performance high).

If you have a small number of agents (< 32) then you can assign a tag to the node(s) which it occupies and set the Seeker to disable traversing all tags except the default one and the tag which that agent uses.

@aron_granberg Hi Aron, any update on the turn-based utilities you mentioned? I imagine a number of users would be interested in them, myself included.

Hi

I have uploaded a beta version of them.
Use this link http://arongranberg.com/astar/downloads/0/turnbased_Pro_dev
But you will have to change the 0. Go to http://arongranberg.com/astar/download and enter your invoice number, copy the link of one of the pro downloads. You will see that it contains a long alphanumeric string. Replace the 0 in the above link with that string and then you can use the link to download it.

Note that this version does not include all of the new features and fixes from the 3.8.2 version.

Check out the new hexagon example scene.

Hi @dasbin & @aron_granberg,I’ve been trying to replicate this technique, but I’m not having much luck figuring out the best parts of the code to hook into.

Could you post an example of how to do this? Is there a way to do it using existing functions? I’m using AILerp for what it’s worth.

e.g.

How do you define ‘starting to move into a node’ to get this to work properly? I’ve been trying with CalculateNextPosition, which looks promising, but I’m not 100% sure.

I guess this could be tested in AILerp’s update function?

This makes me think that I could get this working by writing some AstarPath.active.GetNearest tests in AILerp.Update, but I’d rather it was deterministic using existing functions…

I’d really appreciate the help. Thanks!

Hi

Wasn’t there an example scene called ‘Hexagon’ or something in that package? That example scene uses the turn based utilities.

There is - I’ll check that more thoroughly. Thanks!

The new utilities stuff looks pretty cool - any ETA on when they might make into a new version of the project, and should they work with a point graph & AILerp?

@aron_granberg I’ll add any more questions/responses related to this to the ‘add feature’ thread

The tools to not care about which graph they are used on or which movement script is used, it’s up to you to block the relevant nodes when necessary.

1 Like