I am attempting to implement a multi-elevation tilemap in Godot, nevertheless I am can not appear to resolve an issue associated to stairs/ramps. These tiles appear to take up multiple tile area (about 4) and I can not discover a method to constantly map the mouse place to thei actual coordinates. This can even have an effect on my path discovering, as I might count on the steps to be neighbours to my common flat tiles.
I am utilizing Tile Map Layers.
TileSet settings:
- Tile Form: Isometric
- Tile Structure: Diamond Down
- Tile Offset Axis: Vertical Offset
- Tile Dimension: 32px – 16px
Here is my code:
public partial class MapManager : Node
{
non-public const int TileWidth = 32;
non-public const int TileHeight = 32;
non-public readonly Dictionary _tilemaps = new();
non-public readonly Dictionary _elevations = new();
non-public readonly Dictionary _coordinatesToPoints = new();
non-public readonly Dictionary _pointsToCoordinates = new();
non-public readonly Vector2 _tileSize = new(TileWidth, TileHeight);
non-public readonly AStar3D _astar = new();
public override void _Ready()
{
SetupTilemaps();
SetupAStar();
}
public override void _Process(double delta)
{
var tile = GetHoveredTile();
if (tile != null)
{
var tilemap = _tilemaps[tile.Value.Z];
var knowledge = tilemap.GetCellTileData(tile.Worth.ToVector2I());
GD.Print((string)knowledge.GetCustomData("tile-name"));
}
}
non-public Vector3I[] GetNeighbours(Vector3I level)
=> _astar.GetPointConnections(_coordinatesToPoints[point]).Choose(p => _pointsToCoordinates[p]).ToArray();
non-public lengthy CoordsToId(Vector3I coords)
=> _coordinatesToPoints[coords];
non-public Vector3I IdToCoords(int id)
=> _pointsToCoordinateshttps://gamedev.stackexchange.com/q/212964;
non-public void SetupTilemaps()
{
var tilemaps = this.GetChildrenOfType();
var elevation = 0;
foreach (var tilemap in tilemaps.Reverse())
{
_tilemaps[elevation--] = tilemap;
}
}
non-public void SetupAStar()
{
_astar.Clear();
foreach (var (elevation, tilemap) in _tilemaps)
{
foreach (var coords in tilemap.GetUsedCells())
{
var coords3D = new Vector3I(coords.X, coords.Y, elevation);
var id = _astar.GetAvailablePointId();
_coordinatesToPoints[coords3D] = id;
_pointsToCoordinateshttps://gamedev.stackexchange.com/q/212964 = coords3D;
_elevations[coords3D] = elevation;
_astar.AddPoint(id, coords3D);
}
}
foreach (var (elevation, tilemap) in _tilemaps)
{
foreach (var coords in tilemap.GetUsedCells())
{
ConnectNeighbors(new Vector3I(coords.X, coords.Y, elevation));
}
}
}
non-public void ConnectNeighbors(Vector3I coords)
{
var coords2d = new Vector2I(coords.X, coords.Y);
var currentId = CoordsToId(coords);
Vector3I[] neighbors = {
// Identical elevation
new(1, 0, 0), new(-1, 0, 0),
new(0, 1, 0), new(0, -1, 0),
// Beneath
new(1, 0, -1), new(-1, 0, -1),
new(0, 1, -1), new(0, -1, -1)
};
foreach (var offset in neighbors)
{
var neighborCoords = coords + offset;
if (!_tilemaps.TryGetValue(neighborCoords.Z, out var tilemap))
{
proceed;
}
var neighbourCellId = tilemap.GetCellSourceId(new Vector2I(coords2d.X + offset.X, coords2d.Y + offset.Y));
if (neighbourCellId == -1)
{
proceed;
}
if (IsValidConnection(coords, neighborCoords))
{
_astar.ConnectPoints(currentId, CoordsToId(neighborCoords), false);
}
}
}
non-public bool IsValidConnection(Vector3I currentCoords, Vector3I potentialNeighborCoords)
{
return true;
}
public Vector3I? GetHoveredTile()
{
// PROBLEM HERE
foreach (var (elevation, tilemap) in _tilemaps)
{
var tileCoords = tilemap.LocalToMap(tilemap.GetLocalMousePosition());
if (tilemap.CellExistsAtCoordinates(tileCoords))
{
return new Vector3I(tileCoords.X, tileCoords.Y, elevation);
}
}
return null;
}
public Vector3[] FindAStarPath(Vector3I begin, Vector3I aim)
{
var startId = CoordsToId(begin);
var goalId = CoordsToId(aim);
if (!_astar.HasPoint(startId) || !_astar.HasPoint(goalId))
{
GD.PrintErr("No factors discovered for begin/aim");
return Array.Empty();
}
return _astar.GetPointPath(startId, goalId);
}
}