How to check type of a custom Class?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Guilherme Furst

Given when you make custom object class (plainly a script), how can you check with gdscript for its type?
Presumably you would use Object.is_type for the checks, but they never worked for me:

if myobject.is_type("myclass.gd"):

I’ve tried different combinations but without success. Also note that they changed the method in Godot3 to is_class().
Another way to check could be:

if myobject is mycalss:

But that one also doesn’t to work quite as well.

Not perfect at all, but you could use get_script() and regex, requiring the script name to be equal to the type name:

# obviously the pattern is not right for the script name, it's just two seperated examples
# you'll have to come up with a expression, that works
extends Node2D

func _ready():
    var script_path= get_script().resource_path
    var regex = RegEx.new()
    regex.compile("something")
    var string = "something1"
    var substring = regex.sub(string, "1")
    print(substring)

Footurist | 2018-02-28 01:59

:bust_in_silhouette: Reply From: Footurist

Not perfect at all, but you could use get_script() and regex, requiring the script name to be equal to the type name (Object.resource_name returns nothing for some reason):

# obviously the pattern is not right for the script name, it's just two seperated examples
# you'll have to come up with a expression, that works
extends Node2D

func _ready():
    var script_path= get_script().resource_path
    var regex = RegEx.new()
    regex.compile("something")
    var string = "something1"
    var substring = regex.sub(string, "1")
    print(substring)
:bust_in_silhouette: Reply From: Zylann

GDScript resources behave like classes, so you can do it like this:

if my_object is preload("custom_class.gd"):

Or like this:

const CustomClass = preload("custom_class.gd")

and then:

if my_object is CustomClass:

Zylann, do you happen to know why print(get_script().resource_name) prints nothing?

Footurist | 2018-02-28 02:27

Clean solution, but that requires the class to be loaded already on the script.

@Zylann, I think probably because resourcename and resourcepath are different things, while most resources should have a path, they’re aren’t all named.

Guilherme Furst | 2018-02-28 12:16

It requires to load the script indeed, but it’s the closest to an OOP solution and it will have zero cost most of the time, unless you preload scenes or assets into that script (which isn’t a good idea imo, load would be preferred)

Zylann | 2018-02-28 19:42

Looks like in 3.3.2 I can just do

if my_object is class_name

Without needing to import the gd file. Neat.

dabe | 2021-07-05 17:09

:bust_in_silhouette: Reply From: avencherus

I used to use meta data, or special flags, but lately I’ve been using another idea that I am favoring since it is more in line with Godot’s internals.

I override the get_type() and is_type(type) methods in my classes.

It might look like this: (Though I generally use constants.)

func is_type(type): return type == "MyObject" or .is_type(type)
func    get_type(): return "MyObject"

In the is_type(type) it will also fall back to an inherited type. If your object extends a KinematicBody2D, you could still check for that with is_type("KinematicBody2D"). The first condition == "MyObject" would be false, then it would pass the parameter back to the original method for comparison, and if it matches will return true.

I like this, good idea.

What I don’t get is, what does get_type returns for custom classes? have you experimented there?

Guilherme Furst | 2018-02-28 12:13

Okay, so just to be clear, I did some testing, and it seem get_type() really just returns the base class of what the object would be (the c++ class).

So doing a replacement function works pretty well.

Guilherme Furst | 2018-03-01 14:31

It seems like get_type and is_type are get_class and is_class in 3.1 now. Other than that, yeah, this works finely~!

Alfonso | 2019-03-03 07:39

Updated syntax for Godot 4:

func is_class(type: String) -> bool:
    return type == "MyClass" || super.is_class(type)
    
func get_class() -> String:
    return "MyClass"

HOWEVER, DO NOT DO THIS.
Overriding get_class is not suported and will not produce the expected result in some situations.
See : Inconsistent behaviour of overridden Node methods · Issue #92394 · godotengine/godot · GitHub

I ended up giving up on all those fancy solutions, and instead I implement my very own method : get_class_name

========

See also : get_class() and is_class() not returning class_name · Issue #21789 · godotengine/godot · GitHub
See also : Add `GDScriptType` wrapper instead of `GDScriptNativeClass` · godotengine/godot-proposals · Discussion #6502 · GitHub