I'm looking through the documentation every now and then and checking Godot 4 tilemap stuff out finally and it all looks really interesting, a lot more features ( and hopefully fixes ) than in Godot 3.5. the problem is all the things I keep finding about tiles in Godot 4 are about setup. Which is fine, but now I want to learn about simple things like how to do click to move and have a path calculate along my walkable tiles. I know there's technically demos available, but I like playing with things from scratch and not having to dig through a ton of code just to find something that needs a few lines.
Godot 4 tilemap navigation tutorials/examples?
- Edited
- Best Answerset by Lethn
Did a classic and ended up working it out after poking around some tutorials and experimenting by myself.
For the TileMap problem, I hadn't realised that by default you need to setup the collision and the navigation manually, to do this click on the TileMap node, then click on the TileSet tab at the bottom of the editor which should pop up once you click the TileMap node. Make sure the tile you want to select is also clicked. Then click the paint tab and select a property editor, go to navigation layer and physics layer. Click the green button which should be called Add Polygon Tool if you hover the mouse over it.
Once this is done, then the TileMap behaviour should be set up correctly for you, after that, it's a matter of setting up your code as you would in 3D but just for 2D scripting, here's how I did mine.
func _physics_process(delta):
if Input.is_action_just_pressed("RightClick"):
var clickPosition = get_global_mouse_position()
if selectedUnits.size() > 0:
for selection in selectedUnits:
if selection.collider.is_in_group("Selectable"):
selection.collider.beanSoldierAgent.target_position = clickPosition
selection.collider.speed = 300
extends CharacterBody2D
@onready var selected = $Selected
@onready var beanSoldierAgent = $NavigationAgent2D
@export var player = 0
@export var speed = 300
func _physics_process(delta):
var currentLocation = global_position
var nextLocation = beanSoldierAgent.get_next_path_position()
var newVelocity = (nextLocation - currentLocation).normalized() * speed
beanSoldierAgent.set_velocity(newVelocity)
func _on_navigation_agent_2d_velocity_computed(safe_velocity):
velocity = velocity.move_toward(safe_velocity, 100)
move_and_slide()
func _on_navigation_agent_2d_navigation_finished():
speed = 0
By the way, this is so much easier to do in Godot 4 than Godot 3.5 LOL, might even poke around the isometric tiles now if I'm interested enough.
- Edited
Lethn
Thanks for sharing this. I want to post a improvement: set_velocity
must be used only if avoidance_enabled == true
, otherwise you can just force velocity_computed
and move.
I also added click to move (you must add an Input Action move_to
):
extends CharacterBody2D
@onready var beanSoldierAgent : NavigationAgent2D = $NavigationAgent2D
@export var speed := 0
func _physics_process(delta):
var currentLocation = global_position
var nextLocation = beanSoldierAgent.get_next_path_position()
var newVelocity = (nextLocation - currentLocation).normalized() * speed
if beanSoldierAgent.avoidance_enabled:
beanSoldierAgent.set_velocity(newVelocity)
else:
_on_navigation_agent_2d_velocity_computed(newVelocity)
func _on_navigation_agent_2d_velocity_computed(safe_velocity):
velocity = velocity.move_toward(safe_velocity, 100)
move_and_slide()
func _on_navigation_agent_2d_navigation_finished():
speed = 0
func _unhandled_input(event):
if event.is_action_pressed(&"move_to"):
speed = 200
beanSoldierAgent.set_target_position(get_global_mouse_position())