-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
get_class() and is_class() not returning class_name #21789
Comments
This is expected, those methods get the name of the native class. It never worked with inner classes, which also have names. Also, it's not clear what would this return if the script class don't have a name. |
I imagined that the
Good point. First time looking at those in 3.1, it seems at least Since it would be enhancement request, and this makes sense to do, maybe inner classes would override in the same way with their given names. The usefulness for having
In the meanwhile I'm doing an override in every custom class to enable that behavior:
|
BTW, I'm not really against it, but technically it breaks compatibility. |
In my opinion it seems really odd to me that it doesn't return the custom types. It should definitely be documented though either way. |
@vnen I'm glad you're weighing in on it for that reason. These are just the "would be nice" thoughts of an end-user. X) I am curious though the nature of breakage. I'm not sure if you mean for users going from 3.0 to 3.1, or something more on the internals side of things. |
I would maybe go with get_class() -> returns base class name, and get_class_name() -> returns class_name? |
@PLyczkowski At least one way to determine an extended class currently is to do |
@avencherus This thread is about this new functionality: https://godot.readthedocs.io/en/latest/getting_started/step_by_step/scripting_continued.html#register-scripts-as-classes So for example this would work like this:
|
I have also just encountered it and would like if there was at least another method to get the actual class name but that really makes the API dirty. BC break for get_class() would be the cleaner solution. |
I think it would make more sense to make the get_class return the class_name... get_type() -> Type: then you could have: type.class -> return the class_name |
Is there any plans for this? This would help tremendously, especially in debugging scenarii. And I guess it's probably not a huge thing to implement. |
Here's a clumsy but actually easy/working solution for people using tools capable of mass replacing text across a whole folder/subfolders using regexes, such as IntelliJ Idea. Replace:
with:
Do test it on one file though in case your IDE/tool uses different regex syntax (you don't want to fail a mass replace, especially when some editors don't allow that to be undone). You can run this easily as many times as you want and it'll just add the missing ones. |
I have an object that, when it enters the scene, it needs to connect relevant signals. I'd like to use class names in this process. To accomplish this I've overloaded
This feels extremely clumsy. This functionality could be all contained with the |
A very useful use case for this would be in cross-scripting scenarios. Currently, when accessing GDScript scipts from C# code, as far as I can tell, there is no way to check the class name of a node. The workarounds mentioned here do not work, as you cannot overload C#'s IsClass/GetClass from GDScript code. |
I was about to open a new issued but stumbled upon this one instead. |
You can override the method inside the class:
you need to do this manually though! :( |
Sure, but this is rather a workaround than a solution :) |
Since Godot 4.0 is supposed to have a number of BC breaks anyway, making this behave as expected instead of the way it does now would be ideal. |
Yeah, with 4.0 breaking compatibility, it's a good opportunity to make this much cleaner:
This provides you with full access to everything you need. Just need to have the Of course, to make this work well, we also need to have script class support for all programming languages. I've got a branch with VisualScript support, but my C# one has been broken for a long time cause I haven't been able to get the ScriptClass class attribute I made actually detected by the mono runtime. |
@willnationsdev Perfect |
How is |
@mechPenSketch internal engine methods never call script methods (except for virtual methods which are intended to be overridden). So the script |
Actually, the error can be turned into a warning or even muted in the project settings. |
Would it be possible to create a method called |
Someone mentioned in #62273 that |
This is a great time to change behavior, the more versions change, the heavier the compatibility baggage will be, and I hope this issue will be resolved soon! |
I don't think changing I have a
|
Get resource_id() from class_name, on all RuleBasedResources Godot doesn't have an easy way to get a custom class name, because get_class() only gets base classes and apperently there is no better way [1], so the solution was to get the source code for the class and find a "class_name" definition [1]: godotengine/godot#21789 Signed-off-by: Rodrigo Volpe Battistin <[email protected]>
On my opinion, first, I agree with the suggestions here and second I want to add my experience: I had the get_class() function shadowed, on Godot 3.x. Now, trying to go to Godot 4 I decided to de-shadow all. And for my surprise, all things broke because I depend too much on get_class() on my code just to determine what kind of Item is it. And everything returns "Node2D"!! LoL. And the player character too returns "KinematicBody2D", so my player is of class "KinematicBody2D". xD I don't know from what realm is that character but I think he is from the town of the computer science xD Well, now I have to use something like "item is Weapon". Leaving me sometimes lead to recursive references that ends in an error on the Godot Editor. So that is not always possible. I wanted to share my experience to make it more important to take in account. Because I really depends on knowing the class_name. And as I read above I am not the only one. Now for my characters I decided to create a redundant function just to define the same as class_name but returning a String. And for items I need to save that to a file so I really don't know how I will do for now. Because I need to save the class_name to a file so I can load the same item class. LoL, that really broke my game! |
Would be great for tools too, it's not just the get_class function but also to have it in class_name field of the get_property_list(). Would be so much convenient to define it and make some UI by types. |
According to my understanding, the demand for this feature often stems from "type recognition." We need some built-in and convenient way to distinguish different types and then... call their functions. I suddenly realized that this is actually an "interface" issue. GDScript does not have true interfaces, and it is foreseeable that it will not introduce interfaces like C++ or C#. However, I think there is a design that can be borrowed, which is the interface of the GO language. Some people may not be familiar with GO, so I can briefly introduce it: Simply put, if you want to implement an interface, you don't need to inherit it in any way, but simply implement the methods it requires:
MagicDuck does not need to inherit any interface. It implements all the required methods of Duck, so some_duck: Duck = MagicDuck() is valid, that is the logic of go. Perhaps GDScript can draw inspiration from this method to solve the interface problem. |
@Smalldy You don't need to make func (d MagicDuck) fly { ... } ? But yeah make me think there is a has_method() on the Object that allow basic checks, there is even meta_data system but I think it's kind of redundant and not straightforward when defining a class_name. |
|
If you're ever wondering why almost all Godot tools and plugins written in GDScript, no matter how awesome and complex, stay exactly only one level of abstraction above the Editor's native features (i.e. they remain desperately self-contained, without ever being built on top of other plugins, or without ever being designed as base under other plugins), this is it. Look no further. By "it", I mean the constant headaches when trying to know exactly where you stand (what classes exist, what are their names, in what class am I currently, etc.). This thread is a case of "it is comically hard to know the type of a given object, because the method for it doesn't exist, while there does exist a misleading method that actually does something else". Meanwhile, the C# code base becomes more robust every day, creating an ever-growing drift between "serious" Godot (C#) and "small teams/small projects" Godot (GDScript). |
Can anyone explain why we can't just make a new method that returns the custom class_name of an object? |
The global name is exposed in #80487 since 4.3.beta. |
That seems to work, but not when using inner classes 🤔 |
I was trying to find a way to to use A workaround I found was to use var names and the
We could potentially add one parameter to |
EDIT: Scratch what I said below, I was mixing variables around. It actually works. Thank you! Hi @kleonc , thanks, I've not seen that before. However, this doesn't seem to work in my implementation quite in the same way. To recap: my aim is to use a static function to determine if a given object is derived from a particular class. When I pass a I've rewritten my func to use static func get_parent_of_class_type(object: Node, class_type):
""" Get first parent with attached script. Will keep on iterating up the hierarchy until it one. First one that matches is returned. If not, then returns null """
var parent = object.get_parent()
while parent != null:
print("object: ", str(object))
print("class_type: ", str(class_type))
print("is_instance_of(object, class_type): ", str(is_instance_of(object, class_type)))
if is_instance_of(object, class_type):
return parent
# if parent == class_id:
# return parent
parent = parent.get_parent()
if parent == null:
return In the output I see something like:
My call is like this: var __character
var character:
get:
if __character == null:
# __character = Statics.get_parent_of_class(self, "Character")
__character = Statics.get_parent_of_class_type(self, Character)
return __character
set(value): pass I.e. __character = Statics.get_parent_of_class_type(self, Character) .. where Am I supposed to transform the class type |
v3.1.alpha.custom_build.5307043
The new
class_name
keyword doesn't affect the results of the methods forget_class()
andis_class()
.I noticed this earlier when encountering #21461, and it feels like maybe it might have been overlooked. Not sure if it falls under bug or a feature request, or if maybe its even intentional and required.
It would be very useful to have these methods return the custom class types in certain situations.
The text was updated successfully, but these errors were encountered: