Can I store functions in an array somehow?

Godot Version

Godot_v4.2.1-stable_win64

Question

Can I store functions in an array so that my CharacterBody3D can randomly either become idle or move?

This script might be a little messy, as I’m trying to figure out the best way for this to work. I tried having the ready function make move active by default, but this didn’t play nicely with the navigation agent, so instead I supposed I could try to run a function to randomly choose if the character model, named “Meat”, would start being idle or move, and then from there keep looping these ‘decisions’. I tried storing the functions in an array, but after testing it realized it you can’t really directly reference the functions within an array as is. After reading about it online I saw you could reference them as strings, but I’m thinking I didn’t type it out right.

It would be nice if it could just move, then stop, and repeat. I could be overthinking it methinks… :sweat_smile:

[Reference Images Below Script]

extends CharacterBody3D

#Node references
@onready var navigation_agent_3D: NavigationAgent3D = $NavigationAgent3D
@onready var AP = $AnimationPlayer

#Function references 
var MoveFunc = Callable(self, "_meat_move()")
var IdleFunc = Callable(self, "_meat_idle()")

#Statuses
var moving = true
var idle = false

# Called when the node enters the scene tree for the first time.
func _ready():
	_choose_action()

#Meat chooses whether to Move or Stay Idle
func _choose_action():
	print("Meat is thinking about what to do next!")
	var FunctionArray = [MoveFunc, IdleFunc]
	FunctionArray.pick_random()


#Crawl and move along navigation mesh
func meat_move():
		print("Meat is moving!")
		var CrawlAnims = ["Crawl", "CrawlGLITCH"]
		AP.play(CrawlAnims.pick_random())
		moving = true
		var random_pos = Vector3.ZERO
		random_pos.x = randf_range(-5.0, 5.0)
		random_pos.y = randf_range(-5.0, 5.0)
		navigation_agent_3D.set_target_position(random_pos)
		
		if idle:
			_meat_idle()
			
		

func _on_navigation_agent_3d_target_reached():
	_choose_action()


func _physics_process(delta: float) -> void:
	var destination = navigation_agent_3D.get_next_path_position()
	var local_destination = destination - global_position
	var direction = local_destination.normalized()
	
	velocity = direction * 5.0
	move_and_slide()

#Stop moving along navigation mesh and play idle animations until next action
func _meat_idle():
		print("Meat is Idle!")
		moving = false
		idle = true
		navigation_agent_3D.max_speed = 0
		var IdleAnims = ["Idle","FreakOut","Stretch"]
		AP.play(IdleAnims.pick_random())

Meat Scene :

Main Scene (NavigationRegion on the petbed that he can move around on) :

Test within Main Scene with Debugger, fires off choose action signal, but neither move or idle is going off :

Can`t test it right now, but this should work

	var func_array: Array[Callable] = [ meat_move, _meat_idle ]
	func_array.pick_random().call()

No need to create those Callable variables. Important is the call()method to actually execute the function. Also, you added a _ in your Callable for the move method where it wasn’t needed.

1 Like

Works like a charm, thank you so much! :grinning: