How to transition two animation smoothly

Godot Version

ver4.3

Question

`Im trying to make a 2 platformer like mega man where player can only shoot two directions. I made 6 different movement animations without shooting and with shooting. Im using node based state machine. While handling all movement in each state, I decided to handle shooting mechanic in player script. The problem is I have no idea how to smoothly transition two animation (eg, regular idle animation and idle shooting animation).

As you can see in this gif, player run animation wont return to regular run animation after run shoot animation.

extends PlayerState

@export var _animation_player: NodePath
@onready var animation_player:AnimationPlayer = get_node(_animation_player)

var anim_finished = false

# Called when the node enters the scene tree for the first time.
func enter(_msg := {}) -> void:
	animation_player.play("player_run")
	player.coyote_jump_counter = player.coyote_jump_time
	player.slide_counter = player.slide_time
	pass # Replace with function body.


# Called every frame. 'delta' is the elapsed time since the previous frame.
func physics_update(delta: float) -> void:
	player.flip_sprite()

	if not is_zero_approx(player.get_input_direction()): #If Player is moving, calculate Player's velocity.x
		player.velocity.x = lerpf(player.velocity.x, player.get_input_direction() * player.speed, player.acceleration * delta)

	player.velocity.y += player.set_gravity() * delta
	player.move_and_slide()

	if Input.is_action_just_pressed("shoot"):
		animation_player.play("run_shoot")
	else:
		if anim_finished:
			animation_player.play("player_run")
			anim_finished = false

	if player.is_on_floor():
		if is_zero_approx(player.get_input_direction()):	#If Player is Not Moving, IDLE STATE
			state_machine.transition_to("Idle")

		if Input.is_action_just_pressed("jump"):
			state_machine.transition_to("Jump")

		if Input.is_action_just_pressed("slide"):
			state_machine.transition_to("Slide")

	else:
		player.coyote_jump_counter -= delta

		if Input.is_action_just_pressed("jump") and player.coyote_jump_counter > 0.0:
			state_machine.transition_to("Jump")

		if player.coyote_jump_counter <= 0.0:
			state_machine.transition_to("Fall")
	pass


func _on_animation_player_animation_finished(anim_name):
	if anim_name == "run_shoot":
		anim_finished = true
	pass # Replace with function body.

I think you would have to get the frame being currently played using something like:

var current_frame = animated_sprite.frame

Then use that to be your starting frame in your run-shoot animation.

If you add exit_state and enter_state as part of your state machine code, you can set the current frame in exit function and read it in enter function.

The other method is to have two sprites, one for your legs, and one for your body, that together make up your player. Your legs can then keep running like normal while your body changes from not shooting to shooting.

I think I prefer the second method, but they both have pros and cons.

Hope that helps in some way. There may be other ways.

Paul

PS I just reread your question and I may not have answered your question. Did you mean how to go from run-shooting back to just running or did you mean to stop the frame jump of the legs when you go from one to the other? Sorry.

Thank you for the reply. Id like to solve both problem 1. go back from run-shooting back to just running 2. frame jump of the legs.