animation annpassen

This commit is contained in:
Andre 2026-03-15 23:23:49 +01:00
parent 3bdd0780c5
commit 08a5de8ee8
2 changed files with 86 additions and 53 deletions

View file

@ -52,7 +52,9 @@ const ANIMATION_FILES = {
"walk": "res://assets/animations/Walking.fbx", "walk": "res://assets/animations/Walking.fbx",
"autoattack": "res://assets/animations/Autoattack.fbx", "autoattack": "res://assets/animations/Autoattack.fbx",
"die": "res://assets/animations/Dying Backwards.fbx", "die": "res://assets/animations/Dying Backwards.fbx",
"idle": "res://assets/animations/Idle.fbx",
} }
const LOOP_ANIMATIONS = ["walk", "idle"]
var anim_player: AnimationPlayer = null var anim_player: AnimationPlayer = null
var current_anim: String = "" var current_anim: String = ""
@ -69,13 +71,8 @@ func _ready():
# Animationen laden # Animationen laden
func _setup_animations(): func _setup_animations():
# Debug: Alle Kinder ausgeben um den Modell-Node zu finden
print("Enemy Kinder: ")
for child in get_children():
print(" - ", child.name, " (", child.get_class(), ")")
var model = get_node_or_null("EnemyModel") var model = get_node_or_null("EnemyModel")
if model == null: if model == null:
print("Enemy: EnemyModel nicht gefunden!")
return return
anim_player = _find_node_by_class(model, "AnimationPlayer") anim_player = _find_node_by_class(model, "AnimationPlayer")
if anim_player == null: if anim_player == null:
@ -91,7 +88,6 @@ func _setup_animations():
for anim_id in ANIMATION_FILES: for anim_id in ANIMATION_FILES:
var scene = load(ANIMATION_FILES[anim_id]) as PackedScene var scene = load(ANIMATION_FILES[anim_id]) as PackedScene
if scene == null: if scene == null:
print("Enemy: Animation nicht gefunden: ", ANIMATION_FILES[anim_id])
continue continue
var instance = scene.instantiate() var instance = scene.instantiate()
var source_ap = _find_node_by_class(instance, "AnimationPlayer") var source_ap = _find_node_by_class(instance, "AnimationPlayer")
@ -99,21 +95,12 @@ func _setup_animations():
var names = source_ap.get_animation_list() var names = source_ap.get_animation_list()
if names.size() > 0: if names.size() > 0:
var anim = source_ap.get_animation(names[0]) var anim = source_ap.get_animation(names[0])
if anim_id in ["walk", "idle"]:
anim.loop_mode = Animation.LOOP_LINEAR
if lib.has_animation(anim_id): if lib.has_animation(anim_id):
lib.remove_animation(anim_id) lib.remove_animation(anim_id)
lib.add_animation(anim_id, anim) lib.add_animation(anim_id, anim)
print("Enemy: Animation geladen: ", anim_id)
else:
print("Enemy: Kein AnimationPlayer in ", ANIMATION_FILES[anim_id])
instance.queue_free() instance.queue_free()
print("Enemy: Verfügbare Animationen: ", anim_player.get_animation_list())
# Debug: Modell-Hierarchie ausgeben
_print_tree(model, 0)
func _print_tree(node: Node, depth: int):
print(" ".repeat(depth), node.name, " (", node.get_class(), ")")
for child in node.get_children():
_print_tree(child, depth + 1)
func _find_node_by_class(node: Node, class_name_str: String) -> Node: func _find_node_by_class(node: Node, class_name_str: String) -> Node:
for child in node.get_children(): for child in node.get_children():
@ -126,21 +113,14 @@ func _find_node_by_class(node: Node, class_name_str: String) -> Node:
func _play_anim(anim_name: String): func _play_anim(anim_name: String):
if anim_player == null: if anim_player == null:
print("Enemy: anim_player ist null!")
return return
# Wenn Animation ausgelaufen ist, zurücksetzen
if not anim_player.is_playing():
current_anim = ""
if anim_name != current_anim: if anim_name != current_anim:
current_anim = anim_name current_anim = anim_name
if anim_name != "" and anim_player.has_animation(anim_name): if anim_player.has_animation(anim_name):
anim_player.play(anim_name) anim_player.play(anim_name)
print("Enemy: Spiele Animation: ", anim_name)
# Debug: Track-Pfade und root_node ausgeben
var anim = anim_player.get_animation(anim_name)
print(" AnimPlayer root_node: ", anim_player.root_node)
print(" AnimPlayer absoluter Pfad: ", anim_player.get_path())
for t in range(mini(3, anim.get_track_count())):
print(" Track ", t, ": ", anim.track_get_path(t))
elif anim_name != "":
print("Enemy: Animation nicht gefunden: ", anim_name, " | Verfügbar: ", anim_player.get_animation_list())
else: else:
anim_player.stop() anim_player.stop()
@ -273,7 +253,7 @@ func _physics_process(delta):
else: else:
velocity.x = 0 velocity.x = 0
velocity.z = 0 velocity.z = 0
_play_anim("") # Idle beim Angriff _play_anim("idle") # Idle beim Angriff
if can_attack: if can_attack:
_attack() _attack()
@ -296,7 +276,7 @@ func _do_patrol():
# Am Ziel angekommen, warten und neues Ziel wählen # Am Ziel angekommen, warten und neues Ziel wählen
velocity.x = 0 velocity.x = 0
velocity.z = 0 velocity.z = 0
_play_anim("") _play_anim("idle")
_wait_at_patrol_point() _wait_at_patrol_point()
else: else:
# Zum Patrol-Ziel laufen # Zum Patrol-Ziel laufen

View file

@ -96,7 +96,9 @@ var cast_spell_id = "" # Welcher Zauber gecastet wird
# Animation System # Animation System
const ANIMATION_FILES = { const ANIMATION_FILES = {
"start_walk": "res://assets/animations/Start Walking.fbx",
"walk": "res://assets/animations/Walking.fbx", "walk": "res://assets/animations/Walking.fbx",
"stop_walk": "res://assets/animations/Stop Walking.fbx",
"walk_back": "res://assets/animations/Walking Backwards.fbx", "walk_back": "res://assets/animations/Walking Backwards.fbx",
"strafe_left": "res://assets/animations/Left Strafe Walking.fbx", "strafe_left": "res://assets/animations/Left Strafe Walking.fbx",
"strafe_right": "res://assets/animations/Right Strafe Walking.fbx", "strafe_right": "res://assets/animations/Right Strafe Walking.fbx",
@ -104,7 +106,10 @@ const ANIMATION_FILES = {
"autoattack": "res://assets/animations/Autoattack.fbx", "autoattack": "res://assets/animations/Autoattack.fbx",
"heavy_strike": "res://assets/animations/Heavy Strike.fbx", "heavy_strike": "res://assets/animations/Heavy Strike.fbx",
"die": "res://assets/animations/Dying Backwards.fbx", "die": "res://assets/animations/Dying Backwards.fbx",
"idle": "res://assets/animations/Idle.fbx",
} }
# Animations-State für Walk-Kette
var walk_state: String = "" # "", "start", "walking", "stop"
var anim_player: AnimationPlayer = null var anim_player: AnimationPlayer = null
var current_anim: String = "" var current_anim: String = ""
@ -154,22 +159,16 @@ func _ready():
# Animationen aus FBX-Dateien laden und in AnimationPlayer einbinden # Animationen aus FBX-Dateien laden und in AnimationPlayer einbinden
func _setup_animations(): func _setup_animations():
print("Player Kinder: ")
for child in get_children():
print(" - ", child.name, " (", child.get_class(), ")")
var model = get_node_or_null("PlayerModel") var model = get_node_or_null("PlayerModel")
if model == null: if model == null:
print("PlayerModel nicht gefunden!")
return return
# AnimationPlayer im Modell finden # AnimationPlayer im Modell finden
anim_player = _find_node_by_class(model, "AnimationPlayer") anim_player = _find_node_by_class(model, "AnimationPlayer")
if anim_player == null: if anim_player == null:
# Neuen AnimationPlayer erstellen und ans Modell hängen
anim_player = AnimationPlayer.new() anim_player = AnimationPlayer.new()
anim_player.name = "AnimationPlayer" anim_player.name = "AnimationPlayer"
model.add_child(anim_player) model.add_child(anim_player)
print("Neuer AnimationPlayer erstellt")
# AnimationLibrary holen oder erstellen # AnimationLibrary holen oder erstellen
var lib: AnimationLibrary var lib: AnimationLibrary
@ -183,24 +182,36 @@ func _setup_animations():
for anim_id in ANIMATION_FILES: for anim_id in ANIMATION_FILES:
var scene = load(ANIMATION_FILES[anim_id]) as PackedScene var scene = load(ANIMATION_FILES[anim_id]) as PackedScene
if scene == null: if scene == null:
print("Animation nicht gefunden: ", ANIMATION_FILES[anim_id])
continue continue
var instance = scene.instantiate() var instance = scene.instantiate()
var source_ap = _find_node_by_class(instance, "AnimationPlayer") var source_ap = _find_node_by_class(instance, "AnimationPlayer")
if source_ap: if source_ap:
var names = source_ap.get_animation_list() var names = source_ap.get_animation_list()
if names.size() > 0: if names.size() > 0:
var anim = source_ap.get_animation(names[0]) var anim = source_ap.get_animation(names[0])
# Endlos-Animationen loopen
if anim_id in ["walk", "walk_back", "strafe_left", "strafe_right", "idle"]:
anim.loop_mode = Animation.LOOP_LINEAR
if lib.has_animation(anim_id): if lib.has_animation(anim_id):
lib.remove_animation(anim_id) lib.remove_animation(anim_id)
lib.add_animation(anim_id, anim) lib.add_animation(anim_id, anim)
print("Animation geladen: ", anim_id)
instance.queue_free() instance.queue_free()
print("Verfügbare Animationen: ", anim_player.get_animation_list()) # Signal für Walk-Kette: Start Walking → Walking
anim_player.animation_finished.connect(_on_animation_finished)
# Callback wenn eine Animation fertig ist
func _on_animation_finished(anim_name: StringName):
if anim_name == "start_walk" and walk_state == "start":
# Start Walking fertig → Walking (loop) starten
walk_state = "walking"
current_anim = "walk"
anim_player.play("walk")
elif anim_name == "stop_walk" and walk_state == "stop":
# Stop Walking fertig → Idle
walk_state = ""
current_anim = "idle"
anim_player.play("idle")
# Rekursiv nach einem Node einer bestimmten Klasse suchen # Rekursiv nach einem Node einer bestimmten Klasse suchen
func _find_node_by_class(node: Node, class_name_str: String) -> Node: func _find_node_by_class(node: Node, class_name_str: String) -> Node:
@ -217,15 +228,56 @@ func _update_animation(input_dir: Vector2):
if anim_player == null: if anim_player == null:
return return
var new_anim = "" # Angriffs-/Death-Animation nicht unterbrechen
if anim_player.is_playing() and current_anim in ["autoattack", "heavy_strike", "die"]:
return
var is_walking_forward = input_dir.y < -0.1 or (input_dir.length() > 0 and abs(input_dir.y) <= 0.1 and abs(input_dir.x) <= 0.1)
var is_moving = input_dir.length() > 0
# Vorwärts-Laufen: Start Walking → Walking → Stop Walking
if is_walking_forward:
if walk_state == "":
# Loslaufen: Start Walking abspielen
walk_state = "start"
current_anim = "start_walk"
anim_player.play("start_walk")
elif walk_state == "start" and not anim_player.is_playing():
# Start Walking fertig → Walking (loop)
walk_state = "walking"
current_anim = "walk"
anim_player.play("walk")
elif walk_state == "stop":
# War gerade am Anhalten, wieder loslaufen
walk_state = "start"
current_anim = "start_walk"
anim_player.play("start_walk")
# walking state: walk loopt automatisch
return
# Nicht mehr vorwärts → Stop Walking wenn nötig
if walk_state == "start" or walk_state == "walking":
if not is_moving:
walk_state = "stop"
current_anim = "stop_walk"
anim_player.play("stop_walk")
return
else:
# Wechsel zu anderer Bewegung (rückwärts, strafe)
walk_state = ""
# Stop Walking läuft noch
if walk_state == "stop":
if anim_player.is_playing():
return # Warten bis Stop Walking fertig
walk_state = ""
# Andere Animationen
var new_anim = ""
if not is_on_floor(): if not is_on_floor():
new_anim = "jump" new_anim = "jump"
elif input_dir.length() > 0: elif is_moving:
# Vorwärts/Rückwärts hat Priorität if input_dir.y > 0.1:
if input_dir.y < -0.1:
new_anim = "walk"
elif input_dir.y > 0.1:
new_anim = "walk_back" new_anim = "walk_back"
elif input_dir.x < -0.1: elif input_dir.x < -0.1:
new_anim = "strafe_left" new_anim = "strafe_left"
@ -234,15 +286,15 @@ func _update_animation(input_dir: Vector2):
else: else:
new_anim = "walk" new_anim = "walk"
else: else:
new_anim = "" # Idle — keine Animation (oder Idle wenn vorhanden) new_anim = "idle"
# Angriffs-/Death-Animation nicht unterbrechen # Wenn Animation ausgelaufen ist, zurücksetzen
if anim_player.is_playing() and current_anim in ["autoattack", "heavy_strike", "die"]: if not anim_player.is_playing():
return current_anim = ""
if new_anim != current_anim: if new_anim != current_anim:
current_anim = new_anim current_anim = new_anim
if new_anim != "" and anim_player.has_animation(new_anim): if anim_player.has_animation(new_anim):
anim_player.play(new_anim) anim_player.play(new_anim)
else: else:
anim_player.stop() anim_player.stop()
@ -253,6 +305,7 @@ func _play_attack_anim(anim_name: String):
return return
if anim_player.has_animation(anim_name): if anim_player.has_animation(anim_name):
current_anim = anim_name current_anim = anim_name
walk_state = "" # Walk-Kette unterbrechen
anim_player.stop() anim_player.stop()
anim_player.play(anim_name) anim_player.play(anim_name)