animation annpassen
This commit is contained in:
parent
3bdd0780c5
commit
08a5de8ee8
2 changed files with 86 additions and 53 deletions
40
enemy.gd
40
enemy.gd
|
|
@ -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
|
||||||
|
|
|
||||||
99
player.gd
99
player.gd
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue