Is it possible to get which node/object has invoked the setter function?
why am I asking this?
atm I have custom animation player:
tool
extends Animation
func track_insert_key(track_idx : int, time : float, key, transition : float = 1) -> void:
var track_path=track_get_path(track_idx)
var key_node=<some_function>.get_node(track_path)
if(key_node.get_class()=="some_node"):
# do something before setting keyframe
.track_insert_key(track_idx, time, key, transition)
but I can eliminate the need of a custom animation player if I could intercept who called the getter function, maybe something like this:
tool
extends Node2D
var custom_variable=0 setget ,get_custom_variable
func get_custom_variable(by):
print("called by=",by)
if(by.get_class()=="Animation"):
# do something before setting keyframe
so is anything like this possible? or some similar approach which eliminates the need of a custom AnimationPlayer
?
THIS ANSWER DOES NOT WORK ON TOOL SCRIPTS RUNNING ON THE EDITOR
We cannot exactly get the calling Node
, but we can have an idea of the caller.
We can get an iterate over the stack trace like this:
var stack := get_stack()
for item in stack:
prints(item)
The get_strack
function returns an Array
that contains a Dictionary
per entry of the call stack, with these keys:
"function"
: The name of the calling method."line"
: The line number of the call."source"
: The path of the calling script.So, no, we are not getting the instance that is calling.
By the way, the first entry (index 0
) returned by get_stack
corresponds to the call to get_stack
. So you want the second entry (index 1
). Furthermore, the result will only have one entry if your script is not being called from a script (e.g. the engine is calling a method such as _ready
or _process
, or it is resuming from yield
):
var stack := get_stack()
var path_of_the_script := ""
if stack.size() == 1:
prints("called from external code")
else:
path_of_the_script = stack[1].source
Beyond that, we could look into ProjectSettings.get_setting("_global_script_classes")
to find out the name of the class (if it is an script with class_name
):
var stack := get_stack()
var path_of_the_script := ""
if stack.size() == 1:
prints("called from external code")
else:
path_of_the_script = stack[1].source
var class_id := path_of_the_script
if ProjectSettings.has_setting("_global_script_classes"):
for x in ProjectSettings.get_setting("_global_script_classes"):
if x.path == path_of_the_script:
class_id = x.class
prints("called from:", class_id)
And that would be the name of the script class that is calling your method, if it has one. Hopefully that is useful enough.