Path with complex conditions for 2D game

  • A* version: 5.25
  • Unity version: 2023 latest

Hello all

I am running into a complex situation in my top down 2d game!
These are the two scenarios:

  1. There are water tiles in the game. If the water tiles are 5 nodes or less, then the player can walk through it! If it is greater than 5 nodes, then that path should be restricted because the player would not be able to jump over it
  2. There are cliffs in the game. (again this is a 2d top down game). From one angle, the player should be able to move through the cliff (one-way). But from any other angle, it should be restricted!

I’ve worked on this all day with no success. If anyone has any advice for me, I would truly appreciate it. Thank you for taking the time to help me!

Im currently exploring ITraversalProvider but am unsure if this is the correct path. I also noticed the

path.path.Count is empty… and path.vectorCount is empty

It worked! Yes ITraversalProvider is definitely the way to do this!
I’ll share my results here :blush:
Thanks Aron for the awesome asset!
And God bless you all!

public class CustomTraverse : ITraversalProvider {
public Dictionary<GraphNode, int> dictWaterNodeCounter;
public float maxJumpDistance = 5f; // Maximum distance player can jump

public CustomTraverse() {
    dictWaterNodeCounter = new();
}

/**
 * 1. (0, 0) starts at bottom-left of graph
 * 2. fromNode starts at where the calling player is, with toNode being shifted all around that node
 * 3. fromNode then jumps to the next BEST route and go through its surrounding node again
 * 4. Continues until reach destination
 */
public bool CanTraverse(Path path, GraphNode fromNode, GraphNode toNode) {
    bool fromNodeIsWater = HasWaterTag(fromNode);
    bool toNodeIsWater = HasWaterTag(toNode);

    if (toNodeIsWater) {
        if (!fromNodeIsWater) {
            // Edge water
            dictWaterNodeCounter[toNode] = 0;
        } else if (!dictWaterNodeCounter.ContainsKey(toNode)) {
            if (!dictWaterNodeCounter.ContainsKey(fromNode)) {
                dictWaterNodeCounter[fromNode] = 0;
            }

            // Newly identified node
            dictWaterNodeCounter[toNode] = dictWaterNodeCounter[fromNode] + 1;
        }

        if (dictWaterNodeCounter[toNode] > maxJumpDistance) {
            return false;
        }
    }

    return CanTraverse(path, toNode);
}

public bool CanTraverse(Path path, GraphNode node) {
    // If the node is water, check if it's within jump distance
    return true;
}

bool HasWaterTag(GraphNode node) => node.Tag == waterTag;

}

2 Likes