Player Movement Relative to up_direction property

Godot 4.4.1

In my game, the player (CharacterBody3d) should be able to walk on walls. The way I plan to do this is by having the vectors associated with controls change relative to the player’s up_direction, which is essentially its orientation. Unfortunately, I haven’t been able to come up with any solutions using the Godot docs, and I’d prefer not to hard code the directions, since that could make the code a little messy for me.

In the rough sketch above, the circle represents the player (for the middle one, assume that the up_direction property is set to Vector3.UP). The arrows correspond to specific arrow keys( red for the ↑ key, green for the ↓ key, yellow for the ← key, and purple for the → key)

Also here’s my code if it helps (note that ‘hopping’ just refers to changing which surface the player will walk on, and I will eventually put code that uses the raycast_down to change the up_direction):

extends CharacterBody3D

@onready var raycast_left: RayCast3D = $RaycastLeft
@onready var raycast_right: RayCast3D = $RaycastRight
@onready var raycast_down: RayCast3D = $RaycastDown

var is_hopping := false

func _physics_process(delta: float) -> void:
	if is_hopping:
		return

	if Input.is_action_just_pressed("hop_right"):
		hop(raycast_right, 90)
	elif Input.is_action_just_pressed("hop_left"):
		hop(raycast_left, -90)

func hop(raycast: RayCast3D, angle: float) -> void:
	var collider = raycast.get_collider()
	if collider == null or not collider.is_in_group("walkable_surfaces"):
		return

	is_hopping = true

	var target_rotation = Vector3(rotation.x, rotation.y, deg_to_rad(rotation_degrees.z + angle))
	var tween = get_tree().create_tween().set_parallel(true)

	tween.tween_property(self, "rotation", target_rotation, 0.75).set_trans(Tween.TRANS_SINE)
	tween.tween_property(self, "position", raycast.get_collision_point(), 0.75).set_trans(Tween.TRANS_SINE)
	
	
	tween.finished.connect(func(): is_hopping = false)

Move along body’s global basis vectors. map x input to basis x and, y input to basis z.