70 lines
2.4 KiB
GDScript
70 lines
2.4 KiB
GDScript
extends Node3D
|
|
|
|
## Merges every animation in the AnimationPlayer into a single looping clip and
|
|
## plays it, so meshes driven by different animations (e.g. ted_bones and
|
|
## fishing_acc) all animate simultaneously instead of overwriting each other.
|
|
## Attach to any node that has an AnimationPlayer child.
|
|
|
|
@onready var anim_player: AnimationPlayer = $AnimationPlayer
|
|
|
|
const MERGED_LIB := "merged"
|
|
const MERGED_NAME := "merged/all"
|
|
|
|
func _ready() -> void:
|
|
if not anim_player:
|
|
push_warning("tekton_fishing_autoplay: No AnimationPlayer found")
|
|
return
|
|
|
|
# Wait one frame for the scene tree to settle
|
|
await get_tree().process_frame
|
|
|
|
var source_names := anim_player.get_animation_list()
|
|
if source_names.is_empty():
|
|
return
|
|
|
|
var merged := _build_merged_animation(source_names)
|
|
if not merged:
|
|
return
|
|
|
|
var lib := AnimationLibrary.new()
|
|
lib.add_animation("all", merged)
|
|
if anim_player.has_animation_library(MERGED_LIB):
|
|
anim_player.remove_animation_library(MERGED_LIB)
|
|
anim_player.add_animation_library(MERGED_LIB, lib)
|
|
|
|
anim_player.play(MERGED_NAME)
|
|
|
|
|
|
## Combines the tracks of every source animation into one Animation. The source
|
|
## animations target disjoint node sets, so simply concatenating their tracks
|
|
## drives all meshes at once.
|
|
func _build_merged_animation(source_names: Array) -> Animation:
|
|
var merged := Animation.new()
|
|
merged.loop_mode = Animation.LOOP_LINEAR
|
|
|
|
var max_length := 0.0
|
|
for anim_name in source_names:
|
|
var src: Animation = anim_player.get_animation(anim_name)
|
|
if not src:
|
|
continue
|
|
max_length = max(max_length, src.length)
|
|
for t in src.get_track_count():
|
|
_copy_track(src, t, merged)
|
|
|
|
merged.length = max_length
|
|
return merged
|
|
|
|
|
|
func _copy_track(src: Animation, src_track: int, dst: Animation) -> void:
|
|
var new_track := dst.add_track(src.track_get_type(src_track))
|
|
dst.track_set_path(new_track, src.track_get_path(src_track))
|
|
dst.track_set_interpolation_type(new_track, src.track_get_interpolation_type(src_track))
|
|
dst.track_set_interpolation_loop_wrap(new_track, src.track_get_interpolation_loop_wrap(src_track))
|
|
dst.track_set_enabled(new_track, src.track_is_enabled(src_track))
|
|
|
|
for k in src.track_get_key_count(src_track):
|
|
var time := src.track_get_key_time(src_track, k)
|
|
var value = src.track_get_key_value(src_track, k)
|
|
var transition := src.track_get_key_transition(src_track, k)
|
|
dst.track_insert_key(new_track, time, value, transition)
|