If I have an instance of a class B
which is defined locally, is there any way to access B (as a variable) using that instance?
class B extends A:
pass
# example
func is_subclass(sub: A, sup: A) -> bool:
return is_instance_of(sub, sup.get_class_local())
var a := A.new()
var b := B.new()
is_subclass(b, a) # true
is_subclass(a, b) # false
I want to be able to do things like call Object.new()
and use is_instance_of()
, which I can't do without accessing B
. Using get_class()
doesn't work, and neither does using get_script()
in this case. Is there really no way around this? :(
[I]s there any way to access
B
(as a variable), using that instance?
Generally speaking, you can use Object.get_script()
to access a class stored as a resource, and use Script functions to probe its properties, functions, and even query its human-readable global name (when registered to ClassDB using class_name
).
Script.get_global_name()
is different from Object.get_class()
: the latter returns the built-in class name, as opposed to the registered one, as a string. (Why? See here and here.) You can circumvent this behaviour by overriding the get_class()
and is_class()
functions, as suggested in the PRs above and other places online, or even deploying your own implementation for class instancing at runtime.
However, since you
...want to [...] call
Object.new()
and useis_instance_of()
...
on object instances directly, we can reformulate the problem differently. If a subclass B
is a class that extends a superclass A
, then B
is of (sub)type A
without being strictly A
(thus, one of its subtypes). In GDScript:
func is_subclass(sub, sup) -> bool:
return (
is_instance_of(sub, sup.get_script())
and not sub.get_script() == sup.get_script()
)
The function above yields the following results:
class_name A extends Node
class B extends A:
pass
func _ready() -> void:
var a := A.new()
var b := B.new()
print( is_subclass(b, a) ) # Prints "true"
print( is_subclass(a, b) ) # Prints "false"
print( is_subclass(a, a) ) # Prints "false"
print( is_subclass(b, b) ) # Prints "false"