How to randomize frames in an animation

Godot Version

Godot_v4.2.1-stable_win64

Question

Hi there,

I have an AnimatedSprite2D and it has the default animation with a couple sprites. In the attatched .gif, you’ll see that the sprites are currently looping in the same order. If I wanted to randomize those sprites every time I press a button how would I do that? I already have the code to play the animation. Not sure how to get the randomizing part.

Bonus question. How would I do this for an AnimationPlayer?

func _button_pressed():
	
	var frames = []
	for i in range(10):
		#not sure how to get a random set of frames here and play it?
		frames.push_back(randi_range(1,6))
	print(frames)
	#insert generated frames here. 
        #element 0 is animation player. element 1 is AnimatedSprite2D
	get_child(0).play('dice_roll')
	get_child(1).play()

Animation

Doing this with an animation player is even simpler actually. You can use a “call method track” to run your own code during the animation.

Here’s a quick setup
image
I set up the animatedSprite with a “dice_roll” animation with 6 frames, one for each side. The speed doesn’t matter because I wont really be playing it.

First we need a function on the dice to call, here’s the whole dice script:

extends AnimatedSprite2D

func _ready():
	# Just to test it
	$AnimationPlayer.play("random_sides")

func random_frame() -> void:
	if animation != "dice_roll":
		animation = "dice_roll"
	
	# Don't want to linger on one side
	var last_frame = frame
	while frame == last_frame:
		frame = randi() % sprite_frames.get_frame_count("dice_roll") # Or just 'randi() % 6'

On the AnimationPlayer we just need to set up the “random_sides” animation, I set it to 2.2 seconds with the default frame snapping of 0.1
Now just make a call method track:
Godot_v4.2.1-stable_win64_xUodSQ7NGD
Select the AnimatedSprite2D as the target. Then right click at the start of the track and insert a key. Choose the random_frame() method

From there I just selected that keyframe and moved the animation cursor (the blue line) and used ctr+d to duplicate that keyframe (you can also box select multiple and then use right click → duplicate keys)

And it looks like this (I zoomed in a lot so you can see the method name)


One keyframe every 0.1 seconds, could move them around for some variation if you want.

And there you go, just play the $AnimationPlayer.play("random_sides") animation whenever you need it! you can also use the animation_finished signal from it.