This project demonstrates 2D scene construction using tilemaps and pathfinding algorithms in Unity. It builds on concepts from Unity Week 5: Two-dimensional Scene-building and Pathfinding.
๐ Foundational text explanations are available here in folder 07.
You can play the game directly from our Itch.io page.
- ๐ฏ Goal: Navigate the tilemap and collect items to unlock movement on specific tiles.
- ๐ ๏ธ Power-Ups:
- ๐ถ Boat: Allows movement across water tiles.
- ๐ Goat: Enables traversal of mountain tiles.
- โ๏ธ Pickaxe: Transforms mountain tiles into grass.
โ ๏ธ Rules:- Without power-ups, the player can only walk on grass and swamp tiles.
- Stepping on an invalid tile ends the game and transitions to the next part.
- ๐ฏ Goal: Click on a valid target tile to navigate the map using the fastest path.
- ๐ ๏ธ Features:
- Each tile type has a specific movement cost.
- The game uses Dijkstraโs algorithm to calculate the least-cost path.
- Invalid clicks display a warning but do not end the game.
Purpose: Manages the tiles the player is allowed to walk on.
void Awake()
{
InitializeAllowedTiles();
}
private void InitializeAllowedTiles()
{
allowedTileSet = new HashSet<TileBase>(defaultAllowedTiles);
Debug.Log("Initial allowed tiles: " + string.Join(", ", allowedTileSet));
}
public void AddTile(TileBase tile)
{
if (tile != null && !allowedTileSet.Contains(tile))
{
allowedTileSet.Add(tile);
Debug.Log($"Tile '{tile.name}' added to allowed tiles.");
}
}
Purpose: Detects when the player interacts with item tiles and updates allowed movement.
switch (tileName)
{
case "BoatTile":
allowedTiles.AddTile(TileManager.Instance.GetDeepSeaTile());
Debug.Log("Boat collected! You can now sail on water.");
break;
case "GoatTile":
allowedTiles.AddTile(TileManager.Instance.GetMountainTile());
Debug.Log("Goat collected! Mountains are now passable.");
break;
case "PickaxeTile":
PlayerInteraction.Instance.EnableTileModification(
TileManager.Instance.GetMountainTile(),
TileManager.Instance.GetGrassTile()
);
Debug.Log("Pickaxe collected! You can now transform mountains into grass.");
break;
}
Purpose: Represents the tilemap as a graph for pathfinding. Provides neighbors and edge weights for Dijkstra's Algorithm.
public float GetEdgeWeight(Vector3Int from, Vector3Int to)
{
TileBase tile = tilemap.GetTile(to);
if (tile != null && tileWeights.ContainsKey(tile))
{
return tileWeights[tile];
}
return float.MaxValue; // Treat unknown tiles as impassable
}
public IEnumerable<Vector3Int> Neighbors(Vector3Int node)
{
foreach (var direction in directions)
{
Vector3Int neighborPos = node + direction;
TileBase neighborTile = tilemap.GetTile(neighborPos);
if (neighborTile != null)
yield return neighborPos;
}
}
Purpose: Calculates the least-cost path for click-based navigation.
public static List<NodeType> GetPath<NodeType>(
IGraph<NodeType> graph,
NodeType startNode,
NodeType endNode,
Func<NodeType, NodeType, float> getEdgeWeight,
int maxIterations = 1000
)
{
var distances = new Dictionary<NodeType, float>();
var previousNodes = new Dictionary<NodeType, NodeType>();
var visited = new HashSet<NodeType>();
// Implementation continues
}
Purpose: Handles click-based movement on the tilemap. Ensures that clicks are valid and calculates the least-cost path to the target using Dijkstra's Algorithm.
public void SetTarget(Vector3 newTarget)
{
Vector3Int gridPosition = tilemap.WorldToCell(newTarget);
if (!tilemap.HasTile(gridPosition))
{
Debug.LogWarning("Invalid Target: Clicked outside the tilemap.");
return;
}
if (gridPosition == tilemap.WorldToCell(transform.position))
{
Debug.LogWarning("Invalid Target: You are already on this tile.");
return;
}
targetInWorld = tilemap.GetCellCenterWorld(gridPosition);
targetInGrid = gridPosition;
atTarget = false;
StartCoroutine(MoveTowardsTheTarget());
}
- Use the arrow keys to move the player.
- Collect items to unlock movement across specific tiles:
- ๐ถ Boat: Sail on water.
- ๐ Goat: Climb mountains.
- โ๏ธ Pickaxe: Transform mountains into grass.
- Step on an invalid tile to transition to the next part.
- Click on a valid target tile.
- The player will move to the target using the fastest path based on tile weights.
- Invalid clicks display a warning but do not end the game.