Reputation: 1938
I'm trying to override my animation player functions like this:
tool
extends AnimationPlayer
func seek (seconds:float,update:bool=false ) -> void:
print("seek =>",seconds)
.seek(seconds,update)
func advance (delta:float) -> void:
print("advanced=>",delta)
.advance(delta)
func play (name:String="", custom_blend:float=-1, custom_speed:float=1.0,from_end:bool=false) -> void:
print("play")
.play(name,custom_blend,custom_speed,from_end)
but I have no idea why it isn't working, nothing is being printed when I test it
I'm particularly interested in seek()
, when I move the time bar/when the animation is playing, it should be simultaneously print the seconds
of where it is
Basically I'm trying to track the time bar
Upvotes: 0
Views: 721
Reputation: 40170
These methods are not virtual.
Some people "override" non-virtual Godot methods (e.g. add_child
) but the instances where people report that working, it is because of the type information (or lack thereof). And I should emphasize it is not overriding, but hiding the original method from late binding.
If the code that is calling seek
knows it is an AnimationPlayer
, it will call seek
from the AnimationPlayer
class. And since seek
from the AnimationPlayer
class is not virtual, your code does not have a chance to run. If it were doing late binding, then it might, but you should not rely on that working.
The case we are talking about, is the animation panel in the editor. Which is written in C++ and thus would know it is dealing with an AnimationPlayer
.
First of all, make an EditorPlugin
. You can refer to the documentation on Making Plugins. But, to cover the basics:
EditorPlugin
script on the sub folders of the "addons" folder you specified and with the name you specified.You got your EditorPlugin
script? Good.
The first steps are as I described in another answer.
You can get the current AnimationPlayer
like this:
tool
extends EditorPlugin
var edited_animation_player:AnimationPlayer
func handles(object:Object) -> bool:
return object is AnimationPlayer
func edit(object:Object) -> void:
edited_animation_player = object
print(edited_animation_player)
And you can get a reference to the AnimationToolsPanel
like this:
var animation_tools_panel:AnimationToolsPanel
func _enter_tree() -> void:
var control:= Control.new()
var animation_player_editor:Control
add_control_to_bottom_panel(control, "probe")
for sibling in control.get_parent().get_children():
if (sibling as Control).get_class() == "AnimationPlayerEditor":
animation_player_editor = sibling
break
remove_control_from_bottom_panel(control)
if animation_player_editor == null:
push_error("Unable to find animation player editor")
Alright, now that we got that, we can extract some stuff from it. In particular we want:
So, let us have variables for those two:
var animation_name_input:OptionButton
var animation_time_input:SpinBox
Now, the first child of the AnimationToolsPanel
is the top bar. And the top bar contains the controls we want. So we are going to iterate over the children of the top bar to find them:
var found_option_button:OptionButton
var found_spin_box:SpinBox
for child in animation_player_editor.get_child(0).get_children():
if child is OptionButton:
found_option_button = child as OptionButton
elif child is SpinBox:
found_spin_box = child as SpinBox
if (
is_instance_valid(found_option_button)
and is_instance_valid(found_spin_box)
):
break
animation_name_input = found_option_button
animation_time_input = found_spin_box
Finally, in your _process
if the references you got (the animation player, the editor panel, and the controls) are valid, you can get the animation name and time:
var index := animation_name_input.selected
var animation_name = "" if index == -1 else animation_name_input.get_item_text(index)
var animation_time := animation_time_input.value
You want to do that in _process
so it updates in real time when an animation is playing from the animation panel.
Of course, the issue is that you want to subclass AnimationPlayer
. Thus, in your plugin you can check if the current AnimationPlayer
is one of yours, and if it isn't disable this mechanism. But if it is, you can tell your custom AnimationPlayer
what is the current animation and time is according to the panel from the plugin code by calling a custom method that takes those values as parameters, and does whatever you need to do with them.
Upvotes: 1