Hi I’m trying to make my pathfinding agents prefer walking on paths in my game. I have a 2d top down game.
I made a Unity Tilemap where I added the paths as tiles. Then I made a custom GridGraphRule to read in that tilemap and if there’s a tile at that node location it will decrease the nodePenalties parameter. Unfortunately it doesn’t work and I’m getting some errors when the scene changes.
Am I at least on the right track here? Here is my code.
using Pathfinding.Graphs.Grid.Rules;
using UnityEngine;
using UnityEngine.Tilemaps;
// Mark with the Preserve attribute to ensure that this class is not removed when bytecode stripping is used. See https://docs.unity3d.com/Manual/IL2CPP-BytecodeStripping.html
[Pathfinding.Util.Preserve]
public class MyPathfindingWalkabilityRule : GridGraphRule
{
public Grid grid;
public Tilemap paths;
public override void Register (GridGraphRules rules) {
// The Register method will be called once the first time the rule is used
// and it will be called again if any settings for the rule changes in the inspector.
// Use this part to do any precalculations that you need later.
// Hook into the grid graph's calculation code
rules.AddMainThreadPass(Pass.BeforeConnections, context => {
// This callback is called when scanning the graph and during graph updates.
// Here you can modify the graph data as you wish.
// The context.data object contains all the node data as NativeArrays
// Not all data is valid for all passes since it may not have been calculated at that time.
// You can find more info about that on the documentation for the GridGraphScanData object.
// Get the data arrays we need
var nodesPenalties = context.data.nodes.penalties;
var nodePositions = context.data.nodes.positions;
// We iterate through all nodes and mark them as walkable or unwalkable based on some perlin noise
for (int i = 0; i < nodePositions.Length; i++) {
var position = nodePositions[i];
Vector3Int tilePos = grid.WorldToCell(position);
if (paths.GetTile(tilePos))
{
nodesPenalties[i] -= 50;
}
}
});
}
}
using Pathfinding.Graphs.Grid.Rules;
using UnityEditor;
using UnityEngine;
using UnityEngine.Tilemaps;
namespace Pathfinding {
[CustomGridGraphRuleEditor(typeof(MyPathfindingWalkabilityRule), "My Pathfinding Rule")]
public class RuleExampleNodesEditor : IGridGraphRuleEditor {
public void OnInspectorGUI (GridGraph graph, GridGraphRule rule)
{
var target = rule as MyPathfindingWalkabilityRule;
target.grid = EditorGUILayout.ObjectField("Grid", target.grid, typeof(Grid), true) as Grid;
target.paths = EditorGUILayout.ObjectField("Paths Tilemap", target.paths, typeof(Tilemap), true) as Tilemap;
}
public void OnSceneGUI (GridGraph graph, GridGraphRule rule) { }
}
}