How to get TileMapLayer single tile data

Godot Version

4.3

Question

I’m trying to get the tile data that the Player is standing on in a 2D top-down game. I have no idea how to do it, have spent days researching. Please help?

Here is my scene setup
image

First you need to get the tilemap you want the data from, then do the following:

var tile_data = tilemap.get_cell_tile_data(tilemap.local_to_map(global_position))

I tested some TileMapLayer

	[Export] TileMapLayer tileMapLayer;

obraz

obraz

obraz

obraz

			var tile = tileMapLayer.GetCellTileData(tileMapLayer.LocalToMap(GlobalPosition));
			if (IsInstanceValid(tile))
				GD.Print(tile.GetCustomData("CustomData"));

obraz

I tried this in C# and it doesn’t work:

var walkable = GetNode<TileMapLayer>("Walkable");

if (walkable != null)
GD.Print("walkable: " + walkable.LocalToMap(Position));

Error: Node not found: “Walkable” (relative to “/root/NoX/Game/Map/Player”).

Thanks, but I have no idea where to stick this code.
I’m working inside Player.cs → _PhysicsProcess()

Well the error says that it cant find this node. You might want to use the [export]-property to set it in the scene-inspector.

Also you are just callin LocalToMap and not GetCellTileData

Whatever you want <_<

using Godot;

namespace TileMapTest;
public partial class Player : CharacterBody2D
{
	[Export] TileMapLayer tileMapLayer;
	public const float Speed = 300.0f;

	public override void _PhysicsProcess(double delta)
	{
		if (Input.IsActionJustPressed("Use"))
		{
			var tile = tileMapLayer.GetCellTileData(tileMapLayer.LocalToMap(GlobalPosition));
			if (IsInstanceValid(tile))
				GD.Print(tile.GetCustomData("CustomData"));
		}

		Vector2 velocity = Velocity;

		Vector2 direction = Input.GetVector("Left", "Right", "Up", "Down");
		if (direction != Vector2.Zero)
		{
			velocity = direction * Speed;
		}
		else
		{
			velocity.X = Mathf.MoveToward(Velocity.X, 0, Speed);
			velocity.Y = Mathf.MoveToward(Velocity.Y, 0, Speed);
		}
		Velocity = velocity;
		MoveAndSlide();
	
}

Error: Node not found: “Walkable” (relative to “/root/NoX/Game/Map/Player”).
Walkable is not child of the player,
var walkable = GetNode<TileMapLayer>("../Walkable");

Putting a TileMapLayer inside of the player seems like the wrong thing to do.

Then why you look there?

this why I show how to select sibling, or just use [Export] and set manually in inspector.

Anyway why you needed Walkable?, what you planing do? @nanohard

I already tried to do "../Walkable" but it doesn’t work. I also tried with an absolute path. It all leads to the same error.

Cannot be Error: Node not found: “Walkable” (relative to “/root/NoX/Game/Map/Player”).
just use [Export]

Can be

Node not found: "../Walkable" (relative to "/root/NoX/Game/Map/Player")
and
Node not found: "Walkable" (relative to "/root/NoX/Game/Map/Player")
and
Node not found: "/root/NoX/Game/Map/Walkable" (absolute path attempted from "/root/NoX/Game/Map/Player").

Try get any sibling node?

That’s where the movement is done, inside _PhysicsProcess(). So I figure that’s the best place to check for where the player is standing and/or moving to. I just can’t figure out why it won’t let me look at the sibling node.

try this

			var children = GetNode("..").GetChildren();
			foreach (var item in children)
			GD.Print(item.Name);

you should have list of children’s in output.
to not get spammed use in ready

After changing the scene order to the following, I got it to work.

Game
    Map
        TIleMapLayer
    Player

var walkable = GetNode<TileMapLayer>("../Map/TileMapLayer");