How to change body of a character using animationplayer?

Godot Version

4.1

Question

EDIT: extra thing
hi, im trying to change the body of another ghost of my pac-man clone
however, im not sure how to do it

like how do i make it so a ghost’s default animation has their own textures and that the body script allows the said ghost’s default animation? it could be on the script file each ghost is assigned to

here are the scripts incase you need it:

the script file each ghost is assigned to

extends Area2D

class_name Ghost

enum GhostState {
	SCATTER,
	CHASE,
	RUN_AWAY,
	EATEN,
	STARTING_AT_HOME
}

signal direction_change(current_direction: String)

var current_scatter_index = 0
var direction = null
var current_state: GhostState
var is_blinking = false


@export var speed = 65
@export var movement_targets: Resource
@export var tile_map: MazeTileMap
@export var image: CompressedTexture2D
@export var chasing_target: Node2D
@export var points_manager: PointsManager
@export var at_home_targets = Resource
@onready var update_chasing_target_position_timer = $updateChasingTargetPositionTimer
@onready var body_sprite = $theghost as BodySprite
@onready var eyes_sprite = $ghosteyes as EyesSprite
@onready var navigation_area_2d = $NavigationAgent2D
@onready var scatter_timer = $scatterTimer
@onready var run_away_timer = $runAwayTimer
@onready var points_label = $pointsLabel
@onready var at_home_timer = $atHomeTimer
@export var is_starting_at_home = false




func _ready():
	navigation_area_2d.path_desired_distance = 4.0
	navigation_area_2d.target_desired_distance = 4.0
	navigation_area_2d.target_reached.connect(on_position_reached)
	
	call_deferred("setup")
 



 
func _process(delta):
	if !run_away_timer.is_stopped() && run_away_timer.time_left < run_away_timer.wait_time / 4 && !is_blinking:
		start_blinking()
	move_ghost(navigation_area_2d.get_next_path_position(), delta)
 

func move_ghost(next_position: Vector2, delta: float):
	var current_ghost_position = global_position
	var new_velocity = (next_position - current_ghost_position).normalized() * speed * delta
	
	caculate_direction(new_velocity)
	position += new_velocity

func caculate_direction(new_velocity: Vector2):
	var current_direction
	
	if new_velocity.x > 1:
		current_direction = "right"
	elif new_velocity.x < -1:
		current_direction = "left"
	elif new_velocity.y > 1:
		current_direction = "up"
	elif new_velocity.y < -1:
		current_direction = "down"
		
	if current_direction != direction:
	
		direction = current_direction
		direction_change.emit(direction)


func setup():
	print(tile_map.get_navigation_map(0))
	navigation_area_2d.set_navigation_map(tile_map.get_navigation_map(0))
	NavigationServer2D.agent_set_map(navigation_area_2d.get_rid(), tile_map.get_navigation_map(0))
	scatter()
 
 
func scatter():
	scatter_timer.start()
	current_state = GhostState.SCATTER
	navigation_area_2d.target_position = movement_targets.scatter_targets[current_scatter_index].position
 
func on_position_reached():
	if current_state == GhostState.SCATTER:
		scatter_position_reached()
		speed = 65
	elif current_state == GhostState.CHASE:
		chase_position_reached()
		
	elif current_state == GhostState.RUN_AWAY:
		run_away_from_pacman()
	elif current_state == GhostState.EATEN:
		start_chasing_pacman_after_eaten()
		
		


func chase_position_reached():
	print("kill pacman")


func scatter_position_reached():
	if current_scatter_index < 3:
		current_scatter_index += 1
	else:
		current_scatter_index = 0
	navigation_area_2d.target_position = movement_targets.scatter_targets[current_scatter_index].position
	
	

func start_chasing_pacman_after_eaten():
	starting_chasing_pacman()
	body_sprite.move()
	body_sprite.show()
	speed = 74






func _on_scatter_timer_timeout():
	starting_chasing_pacman()

func starting_chasing_pacman():
	if chasing_target == null:
		print("no chasing target, chasing wont work obviously lol")
	current_state = GhostState.CHASE
	update_chasing_target_position_timer.start()
	navigation_area_2d.target_position = chasing_target.position


func _on_update_chasing_target_position_timer_timeout():
	navigation_area_2d.target_position = chasing_target.position


func run_away_from_pacman():
	if run_away_timer.is_stopped():
		body_sprite.run_away()
		eyes_sprite.hide_eyes()
		run_away_timer.start()
		speed = 55
	current_state = GhostState.RUN_AWAY
	
	# stop timers
	update_chasing_target_position_timer.stop()
	scatter_timer.stop()
	
	var empty_cell_position = tile_map.get_random_empty_cell_position()
	navigation_area_2d.target_position = empty_cell_position

func start_blinking():
	body_sprite.start_blinking()




func _on_run_away_timer_timeout():
	is_blinking = false
	eyes_sprite.show_eyes()
	body_sprite.move()
	starting_chasing_pacman()
	speed = 74
	

func get_eaten():
	body_sprite.hide()
	eyes_sprite.hide_eyes()
	points_label.show()
	await points_manager.pause_ghost()
	points_label.hide()
	eyes_sprite.show_eyes()
	run_away_timer.stop()
	current_state = GhostState.EATEN
	navigation_area_2d.target_position = movement_targets.at_home_targets[0].position
	speed = 100


func _on_body_entered(body):
	var player = body as Player
	if current_state == GhostState.RUN_AWAY:
		get_eaten()
	elif current_state == GhostState.CHASE || current_state == GhostState.SCATTER:
		set_collision_mask_value(1, false)
		update_chasing_target_position_timer.stop()
		await points_manager.pause_ghost()
		player.die()
		body_sprite.hide()
		eyes_sprite.hide_eyes()
		scatter_timer.wait_time = 20
		scatter()
	

the body script:

extends Sprite2D

class_name BodySprite


@onready var animation_player = $"../AnimationPlayer"




func _ready():
	move()


func move():
	self.texture = (get_parent() as Ghost).image
	animation_player.play("ghost_moving")

func run_away():
	animation_player.play("thetwostates")
	animation_player.play("frightened_moving")

func start_blinking():
	animation_player.play("blinking")

oh yeah and the body also has an image thing attached to the 2nd ghost, here is it incase you need it to convert it to like an animationplayer:
Captura de tela 2024-10-09 210533

thank you

waiting for a reply to this post

Does an animation player not work in this case? The scene tree might be more helpful than the scripts, but what are you trying to achieve? This is hard to understand, I think you want to change the texture of the ghost, which an AnimationPlayer node can do.

an animation player still works, btw what i want to achieve is to change the image into an animationplayer node

btw here is the scene tree (its the ghost character node):
Captura de tela 2024-10-10 194445

waiting for a reply

The AnimationPlayer can change textures (and any other property) as part of an animation track.

You’ve used the AnimationPlayer in your scripts, so I’m assuming this isn’t working for you for some reason. What have you tried? Why didn’t it work? I still don’t understand what visuals you are trying to achieve either.

i see
but what i need is to replace the image (as seen in the node bar) with an animationplayer and select another animation to play

what ive tried is to make a new variable for the other ghost and try to make it so it plays another animation for the other ghost

btw the animationplayer in both scripts are working, its just that i need another animationplayer for the other ghost

I think you would have a better time with a AnimatedSprite2D and a SpriteFrames resource. The SpriteFrames can hold the same name for each animation, but use different images.

i could use these
but now im kinda reconsidering to use the regular modulate thingy where you can change the color but ill see what i can do