-
-
Notifications
You must be signed in to change notification settings - Fork 8
Using pathfindax with duality tilemaps
This tutorial was updated to work with pathfindax 2.2.1 on 2018-05-27. Using newer versions is possible but there might be slight changes.
The tutorial assumes the following things:
- You have followed the tilemap tutorial which can be found here
- You know how to install a duality plugin. This is also covered in the tilemaps tutorial.
- You have some basic knowledge of how to use duality such as adding gameobjects or components.
The first step is to install Duality.Plugins.Pathfindax.Tilemaps.core
and Tilemaps (Editor)
through the duality package manager.
Now the plugins are installed we first need to create a Tilemap
. You can use a similar setup as in the tilemaps tutorial for this.
Note: for pathfinding to work the tilemap must have a tileset assigned
Before adding the pathfinder to the tilemap we need to convert the tilemap data into something the pathfinder can understand. The TilemapNodeGridGenerator
can do this for us. It will search for any TilemapCollider
components on its gameobject or in a child of its gameobject and will use that as a input to generate a nodegrid. This means that any collisions you defined in the Tileset
of the Tilemap
will automatically be used when generating the nodegrid. The TilemapNodeGridGenerator
can be found here:
The next step is to add a pathfinder component to the tilemap. For this tutorial we will use the AstarPathfinderComponent
. Like the name already says this pathfinder uses the A* algorithm. You can find the AstarPathfinderComponent
here:
Note: Adding a AstarPathfinderComponent
before you added a TilemapNodeGridGenerator
can cause a exception
Now we have the basic scene setup we can move on to some coding. First thing you have to do when you open your project in visual studio is to add references to Pathfindax. You can do this by with nuget or by adding it as a dll reference.
After the references are installed create a new class named 'PathFollowerComponent' and paste in the following code:
using Duality;
using Duality.Components;
using Duality.Editor;
using Duality.Input;
using Duality.Plugins.Pathfindax.Components;
using Pathfindax.Nodes;
using Pathfindax.Paths;
using Pathfindax.Utils;
namespace Duality_
{
public class PathFollowerComponent : Component, ICmpUpdatable, ICmpInitializable, IPathProvider
{
[EditorHintRange(0, float.MaxValue)]
public float MovementSpeed { get; set; } = 1f;
[EditorHintRange(1, byte.MaxValue)]
public byte AgentSize { get; set; }
public PathfindaxCollisionCategory CollisionCategory { get; set; }
public Camera Camera { get; set; }
public IPath Path
{
get => _path;
private set => _path = value;
}
[DontSerialize]
private IPath _path;
public AstarPathfinderComponent PathfinderComponent { get; set; }
void ICmpInitializable.OnInit(InitContext context)
{
if (context == InitContext.Activate && DualityApp.ExecContext == DualityApp.ExecutionContext.Game)
{
DualityApp.Mouse.ButtonDown += Mouse_ButtonDown;
}
}
void ICmpInitializable.OnShutdown(ShutdownContext context)
{
DualityApp.Mouse.ButtonDown -= Mouse_ButtonDown;
}
void ICmpUpdatable.OnUpdate()
{
if (Path != null)
{
var heading = Path.GetHeading(GameObj.Transform.Pos);
if (heading.Length <= MovementSpeed)
Path.NextWaypoint();
GameObj.Transform.MoveBy(PathfindaxMathF.Clamp(heading.Normalized * Time.TimeMult * MovementSpeed, heading.Length));
}
}
private async void Mouse_ButtonDown(object sender, MouseButtonEventArgs e)
{
var targetPos = Camera.GetSpaceCoord(e.Position);
var request = PathfinderComponent.Pathfinder.RequestPath(GameObj.Transform.Pos, targetPos, CollisionCategory, AgentSize);
Path = await request;
}
}
}
This will request a path when you click with the mouse button and when that path is solved it will start following it. The AgentSize
property will determine the size of the agent so a AgentSize
of 3 would mean the agent occupies 3 nodes and wont fit in a gap thats just 1 node big. Finally we have a CollisionCategory
which will determine what our agent would collide with.
Note: leaving CollisionCategory
on 'None' will make the pathfinding to ignore all collisions.
Rebuild the project and add the PathFollowerComponent
we just coded to a new gameobject:
We still need to do some things to make the 'PathFollower' component actually work:
- Make sure you have a 'Camera' component in your scene and set the 'Camera' property of the 'PathFollower' component. When you run the game and click somewhere it uses this 'Camera' component for transforming the click position to a position in the world.
- Set the 'PathfinderComponent' property by giving it a reference to the 'AstarPathfinderComponent' we added earlier.
- Currently the gameobject we just added is invisible. To make it visible add a
SpriteRenderer
component to it. This will also add a 'Transform' component.
Now run the game and click somewhere. It will calculate a path to the place you clicked and use that path to move to that position (if possible).
A similar setup can also be found in the source here: https://github.com/Barsonax/Pathfindax/tree/master/Data/PathFollowerExample
Introduction
Tutorials