Open GNSS-Stylist opened 1 year ago
This is the intended behavior so as not to break the editor. However, it has been pointed out previously that this is an inconvenient limitation for functions like Particle that are previewed by a function. See also https://github.com/godotengine/godot/issues/73043.
It would be very convenient to preview work in the editor. Couldn't we make it call the methods only when the script is in tool mode? Additionally, a tool mode
could be added to the track itself but I don't think it's really needed.
i found a solid work around. i gave the animation_started
signal idea a try. i'm using godot 3.5
give the AnimationPlayer this script and it should be able to call any function you put on its method track.
extends AnimationPlayer
tool
func _ready():
connect("animation_started", self, "animation_started_func")
const EDITOR_PATH = "/root/EditorNode/@@596/@@597/@@605/@@607/@@611/@@615/@@616/@@617/@@633/@@634/@@643/@@644/@@6618/@@6450/@@6451/@@6452/@@6453/@@6454/@@6455/ViewportContainer/"
var function_calls = []
func animation_started_func(dismiss):
# print("animation_started_func(dismiss: %s)" % dismiss)
var song_animation = get_animation("song")
# print(" %s" % song_animation)
for track_index in song_animation.get_track_count():
if song_animation.track_get_type(track_index) == Animation.TYPE_METHOD:
var path = EDITOR_PATH + song_animation.track_get_path(track_index)
# print(" track_index: %s" % track_index)
# print(" path: %s" % path)
var track_key_count = song_animation.track_get_key_count(track_index)
for key_index in track_key_count:
var time = song_animation.track_get_key_time(track_index, key_index)
if time >= current_animation_position:
# print(" key_index: %s" % key_index)
var _name = song_animation.method_track_get_name(track_index, key_index)
var params = song_animation.method_track_get_name(track_index, key_index)
# print(" name: %s" % _name)
# print(" time: %s" % time)
function_calls.append({
"path": path,
"name": _name,
"time": time
})
else:
# print(' ...')
else:
# print(" ...")
func _process(delta):
if is_playing():
var remove_these_function_calls = []
for i in function_calls.size():
var function_call = function_calls[i]
if function_call.time <= current_animation_position:
# print("AnimationPlayer is calling the function of another node.")
# print(" path: %s" % function_call.path)
# print(" name: %s" % function_call.name)
var node = get_node(function_call.path)
node.call(function_call.name)
remove_these_function_calls.append(i)
for index in remove_these_function_calls:
# print("AnimationPlayer is removing function call from its queue.")
function_calls.remove(index)
NOTE: your EDITOR_PATH
will probably need to be different than mine. i set mine from reading the error codes and finding what the AnimationPlayer's path was.
Godot version
v4.1.dev.custom_build [c29866dbc], also 4.0.1 stable
System information
Windows 10
Issue description
Functions in AnimationPlayer's Method Call Tracks seem to never be called when using the editor. Video:
https://user-images.githubusercontent.com/50438441/228674782-27a6a2fa-4fd1-46bb-b57d-7fd6b59f8a26.mp4
I first stumbled upon this when trying to add a function to RESET-animation to get rid of some resources generated using tool-scripts unnecessarily bloating the tscn-file. First I wasn't sure if the Method Call Tracks are even supposed to work on tool-scripts, but for example according to the original RESET-track proposal (https://github.com/godotengine/godot-proposals/issues/1597) they apparently are supposed to work.
I tried to fix this myself, and got it working somewhat by removing Engine::get_singleton()->is_editor_hint()-check from void AnimationPlayer::_animation_process_animation-function, case Animation::TYPE_METHOD (file scene/animation/animation_player.cpp). Although the functions were called after the change when running the animations, I didn't manage to get them to run (called from RESET-track) before saving the scene. Changing the method call mode to immediate didn't fix the problem.
A bit hacky way to work around this is to use a setter (also shown in the video). Setter is also called before saving when called from a RESET-track.
There is another problem with setters not able to set sub-node's properties (in this case $Label_Setter.text) when loading the scene (probably related to creation order of nodes?). Is this a feature rather than a bug? This is also added as a comment in the MRP's code (and seen in the video). If this is a bug I can create an issue about it (or if anyone wants to create it, feel free to do so). If the null-check is removed this error is shown: _Node not found: "LabelSetter" (relative to "Node2D"). res://Main.gd:15 - Invalid set index 'text' (on base: 'null instance') with value of type 'String'.
Steps to reproduce
Add a Method Call Track to an animation, functions to it and play it in the editor. Functions will not be called.
Minimal reproduction project
AnimationPlayerToolFunctionBug.zip