Godot Version
4.7
I want to have a wall crawler who just moves alongside the world (like in mario world or this one of Zelda Oracle of Ages)
. He should only move in the direction he faces and turn at corners, so his feet always touch a surface.
Right now he just moves right (he´s facing right), ignores corners and passes through walls.
(The rays correctly detect ground and walls) Here he should turn. But he doesnt)
extends AnimatableBody2D
@exportexport var speed :=@onready30.0
@onready var ground_ray: RayCast2D = %RayCast2D
@onready var wall_ray: RayCast2D = %RayCast2Dforward
func _ready() → void:
ground_ray.hit_from_inside = true
wall_ray.hit_from_inside = true
func _physics_process(delta: float) → void:
wall_ray.force_raycast_update()
ground_ray.force_raycast_update()
if wall_ray.is_colliding():
print(">>> turning +90 (wall)")
turn(90)
elif not ground_ray.is_colliding():
print(">>> turning -90 (edge)")
turn(-90)
position += transform.x * speed * delta
func turn(angle_deg: float) → void:
var pivot := wall_ray.global_position if angle_deg > 0 else ground_ray.global_position
rotation_degrees += angle_deg
global_position = pivot + (global_position - pivot).rotated(deg_to_rad(angle_deg))
wall_ray.force_raycast_update()
ground_ray.force_raycast_update()
In the forum post editor you can select your block of code and hit the </>button to format it all real nice.
I think you need to another wall_ray that’s offset into the tile that the wall crawler would move to next.
Hey thank you Ananasblau
I edited the formatting.
So the issue with the wall crawler is, that he ignores the corner (at the bottom-right) and just moves to the right.
Can you see a logic issue with my code?
If you’re using a tilemap, you don’t need raycasts. Just move tile by tile, check the configuration of adjacent tiles and proceed accordingly.
Thanks for your hint normalized
I really appreciate that.
It works a little, but I cant fully solve it. This is where he goes now and where he stops.
I feel like I´m overcomplicating. Can you tell me a simple solution?
extends AnimatableBody2D
@export var speed := 30.0
var tilemaplayer: TileMapLayer
var got_tilemap := false
var cell
var data : TileData
var check_which_side := 3 #left right up down
func _ready() -> void:
#check_for_special_tiles(Vector2(0,8))
pass
func _process(delta: float) -> void:
if got_tilemap == false:
if GlobalSignals.tilemap_is_ready:
tilemaplayer = get_tree().get_first_node_in_group("tilemap")
#check_for_special_tiles(Vector2(0,8))
got_tilemap = true
else:
if check_which_side == 0:
check_for_special_tiles(Vector2(-16, -8)) #check left
if data != null:
global_position += Vector2(0, 16)
else:
#rotation_degrees += 90
global_position += Vector2(-16, 32) #why does 32 work and not 0?
check_which_side = 2
if check_which_side == 2:
check_for_special_tiles(Vector2(0, -24)) #check upwards
if data != null:
global_position += Vector2(-16, 0)
else:
#rotation_degrees += 90
#global_position += Vector2(-16, 32)
check_which_side = 1
pass
if check_which_side == 3:
check_for_special_tiles(Vector2(0, 8)) #check underneath
if data != null:
global_position += Vector2(16, 0)
else:
#rotation_degrees += 90
global_position += Vector2(0, 16)
check_which_side = 0
func check_for_special_tiles(extra_coords: Vector2): #extra coords to look at a shifted place
if tilemaplayer != null:
var cell := tilemaplayer.local_to_map(tilemaplayer.to_local(global_position + extra_coords))
data = tilemaplayer.get_cell_tile_data(cell)
return data
You’ll need to devise a simple algorithm.
Think about it from the perspective of the character. It can make only three moves: turn clockwise, turn counterclockwise or continue forward. Which move will it make depends on the tile configuration in front of it:
- if the forward tile is occupied - it’s an inner corner - turn 90 deg counterclockwise
- if the below tile is empty - it’s an outer corner - turn 90 deg clockwise
- otherwise - continue forward.
To determine forward and down directions you can use node’s global basis axes. If you take global_transform.x to be forward, then global_transform.y will be down.