Godot Version
4.4.1 stable
Question
Hi, how can I play an animation that’s on a different scene?
I have an animation that shows an enemy taking damage. I want to play that animation once I hit the enemy. So the script that reduces the enemy’s health is on the Bullet script, that works without a problem, the enemy takes damage and then is ‘queued free’. The animation of the enemy taking damage is on a different scene. What would be the best way to access the animation and play it when the enemy gets hit?
This is the Bullet script where I attempt to call and play the enemy hurt animation in the _ready() function:
class_name Bullet extends Area2D
@export var speed := 750
@export var damage:= 1
var max_range := 1000.0
var _traveled_distance = 0.0
func _ready() -> void:
body_entered.connect(func (body: Node) -> void:
if body is Sword:
body.health -= damage
var animation_player: AnimationPlayer = get_node("HurtSwordAnimation")
animation_player.play("hurt_sword")
_destroy()
)
func _physics_process(delta: float) -> void:
var distance := speed * delta
var motion := Vector2.RIGHT.rotated(rotation) * distance
position += motion
_traveled_distance += distance
if _traveled_distance > max_range:
_destroy()
func _destroy():
queue_free()
I’m getting an error that states: Cannot call method ‘play’ on a null value.
It is probably better to make a take_damage
function on the body that handles the hurt animation.
To use get_node
you must specify which node you are starting from, otherwise it assumes self
. Try body.get_node
instead.
Hey, thanks for your reply. I made the suggested changes but I’m still getting the same error:
Cannot call method ‘play’ on a null value.
I’m a bit confused by this since I have a reference to the animation player in the bullet script
@onready var hurt_sword_animation: HurtSword = $HurtSwordAnimation
here’s the ready function:
func _ready() -> void:
body_entered.connect(func (body: Node) -> void:
body.get_node("/root/SwordFollow/HurtSwordAnimation")
if body is Sword:
body.health -= damage
hurt_sword_animation.play("hurt_sword")
_destroy()
)
I’m also experimenting with your suggestion of adding a take_damage
function on the body that handles the hurt animation. If I do that, how can I call that function from a different script?
Not sure why you would be using a /root/
path now, Did you set “SwordFollow” as a global? If so, use the global name, otherwise do not use a root path.
To call a function or use other properties, you can use the detected body
reference. is the “Sword” class a enemy with health?
if body is Sword:
body.take_damage(damage)
1 Like
The reason I used /root/
is because I was experimenting. I’m still new to writing code and more times than not I don’t know how to write the syntax correctly.
So I realized that I had created the damaged_sword()
function in a script attached to the AnimationPlayer Node, which is a child of the CharacterBody2D
(The Sword Enemy). I moved the function damaged_sword()
to the Enemy’s script.
Then I implemented your method: In the Bullet script → In the _ready() function:
func _ready() -> void:
body_entered.connect(func (body: Node) -> void:
body.get_node("HurtSwordAnimation")
if body is Sword:
body.damaged_sword()
It seems to be working as it should. Thanks a lot for your help. Believe it or not, the fact that you gave me those hints helped me see what I was doing incorrectly so thanks again 
1 Like