Godot Version
4.3
Question
I have a problem with the same animation playing on all the instances of a scene.
The instances are of type OrcBase
shown below. It has a component AnimationPlayerController
circled in red
This is the script for the AnimationPlayerController
.
class_name AnimationPlayerController extends AnimationPlayer
## A node for controlling the AnimatedSpriteController easily. Can smoothly play base animations and sudden overlay animations.
# region private variables
var _base_animation: String
var _current_overlay_animation_priority: int = 0
var _is_playing_overlay_animation: bool = false
var _overlay_animation_queue: Array[OverlayAnimation]
# endregion
# region built-in virtual _ready method
func _ready():
animation_finished.connect(_on_animation_finished)
# endregion
# region remaining built-in virtual methods
func _process(_add_constant_forcedelta):
if not is_playing() and _base_animation != "":
play(_base_animation)
# endregion
# region public methods
## Change the base animation to be playing.
func play_base_animation(base_animation_name: String):
self._base_animation = base_animation_name
if not _is_playing_overlay_animation:
play(_base_animation)
## Play an overlay animation and return to the base animation when finish. Alternatively add the animation to queue. The queue will play
## in the order of priority until empty, then it will return tp the base animation.
func play_overlay_animation(overlay_animation: String, priority: int, join_queue: bool = false):
if join_queue:
if _overlay_animation_queue.is_empty() and not _is_playing_overlay_animation:
play(overlay_animation)
_is_playing_overlay_animation = true
else:
_overlay_animation_queue.append(OverlayAnimation.new(overlay_animation, priority))
_overlay_animation_queue.sort_custom(_sort_animation_priority)
else:
if priority > _current_overlay_animation_priority:
play(overlay_animation)
_is_playing_overlay_animation = true
_current_overlay_animation_priority = priority
# endregion
# region private methods
func _on_animation_finished(_param):
if not _overlay_animation_queue.is_empty():
var next_animation = _overlay_animation_queue.pop_front()
_current_overlay_animation_priority = next_animation.priority
play(next_animation)
else:
_is_playing_overlay_animation = false
play(_base_animation)
_current_overlay_animation_priority = 0
func _sort_animation_priority(a: OverlayAnimation, b: OverlayAnimation):
if a.priority < b.priority: return true
return false
# endregion
# region subclasses
class OverlayAnimation:
var name: String
var priority: int
func _init(p_name, p_priority):
self.name = p_name
self.priority = p_priority
# endregion
The orcBase
inherits from enemyBase
, which inherits from creatureBase
which finally inherits from entityBase
. In researching my problem i’ve found examples of people saying inheritance in godot is shabby at best. I’ve tested with clearing the inheritance on the orcBase
but the problem persists. All of the bases are shown below
entityBase
:
creatureBase
:
enemyBase
As shown in the screenshots i’ve already tried making the texture resource local to scene. This did not work.
For anyone interested here is the animationcontroller with one of the animations selected:
and here is the animation library
I’ve also tried to make the library unique. Did not work.
Finally i’ve been trying to access both the animationPlayerController
and Sprite2D
as Unique Name. Did not work either.
I’ve also tried removing the animationPlayerController
all together and just using the animationPlayer
as this:
class_name BasicEnemy extends Node2D
enum Direction {
LEFT,
RIGHT,
}
@export var health_regen_pause_time: float = 10
@onready var top_down_entity_2D: TopDownEntity2D = $TopDownEntity2D
@onready var health: DamageReceiver = $DamageReceiver
@onready var animation_player: AnimationPlayer = $AnimationPlayer
@onready var attack_controller: AttackController = $AttackController
var _last_movement_direction = Direction.LEFT
var _is_playing_charge_anim = false
func _ready():
attack_controller.charge_started.connect(_on_charge_attack_started)
attack_controller.charge_end.connect(_on_charge_attack_end)
attack_controller.attack_started.connect(_on_attack_started)
animation_player.play_base_animation("enemyIdleLeft")
health.damage_received.connect(on_damage_taken)
func on_damage_taken(p_amount, knockback, damage_dealer):
health.pause_growth_for(health_regen_pause_time)
if _last_movement_direction == Direction.RIGHT:
animation_player.play("enemyHurtRight")
else:
animation_player.play("enemyHurtLeft")
func _process(delta):
if top_down_entity_2D.is_moving:
if top_down_entity_2D.direction.x > 0:
_last_movement_direction = Direction.RIGHT
if not _is_playing_charge_anim:
animation_player.play("enemyWalkRight")
else:
_last_movement_direction = Direction.LEFT
if not _is_playing_charge_anim:
animation_player.play("enemyWalkLeft")
elif not _is_playing_charge_anim:
if _last_movement_direction == Direction.RIGHT:
animation_player.play("enemyIdleRight")
else:
animation_player.play("enemyIdleLeft")
func _on_charge_attack_started():
_is_playing_charge_anim = true
if _last_movement_direction == Direction.RIGHT:
animation_player.play("enemyChargeRight")
else:
animation_player.play("enemyChargeLeft")
func _on_charge_attack_end():
_is_playing_charge_anim = false
func _on_attack_started():
if _last_movement_direction == Direction.RIGHT:
animation_player.play("enemyAttackRight")
else:
animation_player.play("enemyAttackLeft")
This did not work either.
The player also inherits from entityBase
and has the same problem when duplicated. Both versions of the player is playing a hurt animation when only one is hit.
I’ve been at this for hours so any help is greatly appreciated <3
.