feat: update vfx
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
extends Node3D
|
||||
|
||||
## Autoplays all animations in the AnimationPlayer simultaneously and loops them.
|
||||
## Attach to any node that has an AnimationPlayer child (e.g. tekton_fishing_animation instances).
|
||||
## 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")
|
||||
@@ -13,13 +18,52 @@ func _ready() -> void:
|
||||
# Wait one frame for the scene tree to settle
|
||||
await get_tree().process_frame
|
||||
|
||||
# Play every animation simultaneously, all looping
|
||||
for anim_name in anim_player.get_animation_list():
|
||||
anim_player.play(anim_name)
|
||||
anim_player.advance(0.0) # ensure it starts
|
||||
var source_names := anim_player.get_animation_list()
|
||||
if source_names.is_empty():
|
||||
return
|
||||
|
||||
# Set all to loop
|
||||
for anim_name in anim_player.get_animation_list():
|
||||
var anim: Animation = anim_player.get_animation(anim_name)
|
||||
if anim:
|
||||
anim.loop_mode = Animation.LOOP_LINEAR
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user