Playing Random Animations via Array?

Godot Version

Godot_v4.2.1-stable_win64

Question

How can I randomize animations through an array? I saw from another thread that I could put animations in arrays like this (in script below) but I can’t figure out how to get it to choose an animation within the input event function. I tried using the “pick_random” function at one point but the game wouldn’t run because it had “play” in the array. I’m using it to make “crawl” animation play at random to give it a chance to give more variation to how the character looks when it moves. I’ll need to repeat this same process with a couple of other functions and animations he has on him too eventually.

image

Node Tree Setup for reference ^

Troubleshooting Attempt 1 (Directly referenced AnimationPlayer node, was unable to find the AnimationPlayer)

In this script I just used the variable name we set. When I run this script I get this error :

“Invalid call. Nonexistent function ‘play’ in base ‘Nil’.”

extends CharacterBody3D

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

#Animation Arrays
var IdleAnims = [AP.play("Idle"),AP.play("FreakOut"), AP.play("Stretch")]
var PetAnims = [AP.play("Pet"), AP.play("PetGLITCH")]

#Statuses
var moving = null
var idle = null

# Called when the node enters the scene tree for the first time.
func _ready():
	pass # Replace with function body.

func _unhandled_input(event: InputEvent) -> void:
	if event.is_action_pressed("Test"):
		var CrawlAnims = [AP.play("Crawl"), AP.play("CrawlGLITCH")]
		var CrawlAnimValue = 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)
		
		
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()


func _meat_idle():
	pass

func _meat_pet():
	pass

1° You don’t need to store the animations like you’re doing, that doesn’t work (the function return void so you’re storing nothing), just save the animation name:

var IdleAnims = ["Idle",  "FreakOut", "Stretch"]
var PetAnims = ["Pet",  "PetGLITCH"]

2° Show the character scene, without see how the scene is organized we can’t help indentify why you can’t get the AnimationPlayer

  1. Ok, I updated my script with what you said.
extends CharacterBody3D

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

#Animation Arrays
var IdleAnims = ["Idle","FreakOut","Stretch"]
var PetAnims = ["Pet", "PetGLITCH"]

#Statuses
var moving = null
var idle = null

# Called when the node enters the scene tree for the first time.
func _ready():
	pass # Replace with function body.

func _unhandled_input(event: InputEvent) -> void:
	if event.is_action_pressed("Test"):
		var CrawlAnims = ["Crawl", "CrawlGLITCH"]
  1. Here is my character scene.

In theory using the AP variable should work, the node path looks correct, now you can check if AP.play(the_list_you_want_get_the_anim.pick_random()) works now.

1 Like

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

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.