Skip to content
GodotComponents
← Back to components
A green capsule character following a winding dashed path between orange blocks.

Random Wander

Type: 3D

Makes a CharacterBody3D wander around: walk in a random direction, pause, repeat. Instant life for critters and idle NPCs.

Setup

  1. Save the script as random_wander.gd.
  2. Add a Node as a child of a CharacterBody3D and attach the script.
  3. Set Speed (in metres per second) and the walk and idle times in the Inspector.
  4. Remove any other script that also calls move_and_slide() on the same body.

Code

GDScript
class_name RandomWander
extends Node
## Makes its parent CharacterBody3D walk in a random direction, pause, and repeat.

@export var speed: float = 2.0
@export var min_walk_time: float = 0.5
@export var max_walk_time: float = 1.5
@export var min_idle_time: float = 0.5
@export var max_idle_time: float = 2.0

var _direction: Vector3 = Vector3.ZERO
var _time_left: float = 0.0

@onready var body: CharacterBody3D = get_parent() as CharacterBody3D


func _physics_process(delta: float) -> void:
	_time_left -= delta
	if _time_left <= 0.0:
		_pick_next_state()
	# Walk along the ground; leave the vertical speed to gravity.
	body.velocity.x = _direction.x * speed
	body.velocity.z = _direction.z * speed
	if not body.is_on_floor():
		body.velocity += body.get_gravity() * delta
	body.move_and_slide()


func _pick_next_state() -> void:
	if _direction == Vector3.ZERO:
		var angle := randf_range(0.0, TAU)
		_direction = Vector3(cos(angle), 0.0, sin(angle))
		_time_left = randf_range(min_walk_time, max_walk_time)
	else:
		_direction = Vector3.ZERO
		_time_left = randf_range(min_idle_time, max_idle_time)