Making an ai that randomly moves

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By CatRass

I want to add a roomba to my game that randomly moves around, but I’m not sure how to do that, since all the AI movement tutorials require an end position, but since I just want it to move around randomly, there is no end position.

you need to generate a random vector for the end position, and then when it gets there, generate another random vector.

Millard | 2020-06-24 02:59

Why not setting a random endpoint, if the last point was reached?

whiteshampoo | 2020-06-24 07:01

that’s what i mean by random vector. (unless i’m misunderstanding the term endpoint.)

Millard | 2020-06-25 16:29

:bust_in_silhouette: Reply From: Christian Tietze

To move around randomly, you will switch between two states:

  1. Idle, the Roomba is staying in place
  2. Move to position

While moving, the Roomba advances towards its target but does not much else. Once it reaches the target, it goes back to idling.

When idle, the Roomba will figure out a new target position randomly. It then changes to the move-towards-position state.

Heartbeast/Benjamin has a free YouTube tutorial series for this. Here’s the resources:

You can ignore the player chasing in the script. Here’s the gist of the state transitions:

enum {
    IDLE,
    WANDER
}

var velocity = Vector2.ZERO
var state = IDLE

const ACCELERATION = 300
const MAX_SPEED = 50
const TOLERANCE = 4.0

onready var start_position = global_position
onready var target_position = global_position

func update_target_position():
    var target_vector = Vector2(rand_range(-32, 32), rand_range(-32, 32))
    target_position = start_position + target_vector

func is_at_target_position(): 
    # Stop moving when at target +/- tolerance
    return (target_position - global_position).length() < TOLERANCE

func _physics_process(delta):
    match state:
        IDLE:
            state = WANDER
            # Maybe wait for X seconds with a timer before moving on
            update_target_position()
    
        WANDER:
            accelerate_to_point(target_position, ACCELERATION * delta)
            
            if is_at_target_position():
                state = IDLE

    velocity = move_and_slide(velocity)

func accelerate_to_point(point, acceleration_scalar):
    var direction = (point - global_position).normalized()
    var acceleration_vector = direction * acceleration_scalar
    accelerate(acceleration_vector)

func accelerate(acceleration_vector):
    velocity += acceleration_vector
    velocity = velocity.clamped(MAX_SPEED)