Closed maxime4000 closed 2 weeks ago
I'm pretty sure this is intended behavior, and inevitable, if your WeaponNode
isn't a tool script.
Non-tool scripts don't get attached to nodes and resources during editor-time. They only get created during runtime.
Addons have access to all the project files and classes, so I don't see why the typing should be wrong in that case. This information can be found by reading the Scene file, so I don't see why this is an issues. Here some question I'm curious to know for this issues:
Do you think I Should insert a special command that I can trigger in my Game to execute a script that generate code that will be used by the game? I've learn that this should be living outside of the game's code, right? I mean, I could do this, but this is not right? Right?
(Though, it would fix my debugging issues at the same time π€π )
Tools should has the same knowledge that they would have at runtime? If I can do better stuff when running the game than when running a Script, this encourage bad design choice? I'm pretty sure that there are reasons to have it done this way, but I also think this is inconsistency in how limited Tools script could be.
What I didn't tried, is to do the same code but with GDScript. Would it be Node3D or WeaponNode ?
To reiterate: Godot does not, and should not, instantiate your custom classes, when creating nodes and resources, as long as those custom classes aren't marked at tools (using the "Tool" attribute). You may still be able to access these classes, but the generated nodes will only include anything that is permittet to be instantiated by the editor.
The information about what script is attached to a node/resource can be easily found using the "script" property. If you want your custom nodes to be accessible during editor time, simply annotate them all using the Tool attribute; that's the intended behavior.
The "test" you're proposing will also result in a Node3D in GDScript, unless the "@tool
" annotation is used by that custom node.
If you want to limit the scope of what classes are available to tool scripts, that would be an entirely different issue than what you originally proposed... Your original issue seems to only rely on a missunderstanding of how godot is meant to work, rather than a bug.
Maybe? I mean, I'm searching ways to read scenes somewhere and generate some content somewhere else with it. This script is a run once in awhile. But the output I'm looking to generate is: Functional C# code. I need the proper type of the PackedScene dynamically read through folder navigation so I can type my C# code output accurately. If I can't get this information, I need to manually change the types of Node3D to WeaponNode or any other custom class and that's a no-go!
EditorPlugin seems the right place to execute those kinda task. I just think that the GetType().Name should be the proper type of the packedscene loaded from any context. Tools or Runtime!
The documentation around EditorPlugin could be more explained. I feel that this part of the documentation could be improved greatly. There is no example that tries to solve a complex issues just for demonstration sake. The C# documentation is not fully on par with GDScript. And if those restrictions that you mentioned are by design, why this information is not available easily?
But really, how would you build meta programming features for your project in my case? How would you do it? Where would you do it? Help me understand what I don't know that if I knew, it would help me achieve my goals easier?
Here is a example of the line I'm looking to generate: (consider preloading assets the next steps after)
public static WeaponNode PistolA => GD.Load<PackedScene>("res://scenes/weapons/PistolA tscn").Instantiate<WeaponNode>();
But in the Tools scope, I get this output:
public static Node3D PistolA => GD.Load<PackedScene>("res://scenes/weapons/PistolA tscn").Instantiate<Node3D>();
But really, how would you build meta programming features for your project in my case? How would you do it? Where would you do it? Help me understand what I don't know that if I knew, it would help me achieve my goals easier?
This isn't really the place to ask support questions, please ask in the other community channels instead and lets focus on actual bugs here, does it work correctly when using [Tool]
? If so then this can be closed, otherwise we need to pin down what else might be wrong, but let's stay on topic
If so then this can be closed, otherwise we need to pin down what else might be wrong, but let's stay on topic
Why can't it GetType() correctly here when the same code elsewhere can do it right? It's inconsistant and that's not explained...
Maybe in the Engine Code it can be explained, but as a Developer and User of the Engine, my worries are about building my game, not about limitation of the Tool.
All I'm looking for is a solution that I can have the same code work exactly the same in the game or as a Script. If behavior is different between those environment, where can I run a Script that will use the right type? If RunTime is better, why can't I have a Plugin that use the Runtime environment and features?
How can we solve that? How can I solve an issue that :
If you can't respond with a proper solution to thoses questions am asking, I think you are not the right person to debate about the irrelevance of my issue.
I'm looking for a proper fix for this inconsistency or a proper solution to do the same without the issues I'm facing. Then this issues can be close.
What limitation are you talking about? That you need [Tool]
to run code in the editor? That's well documented
That GetType().Name don't return the same string value in one of the 2 environment! I'm reading the same file, running the same code, but the result differ and I don't think it should differ.
I want to use the Godot SDK as a way to generate code, batch transform GDScene or GDResource file to something else. That's a the purpose of a generator or a Script! And EditorPlugin seem the correct way to do those things? But! I can't because the environment is inferior to the Runtime environment for an unknown reason that I think this limitation should not exist or a Proper workaround should exist!
AddToolMenuItem("Script", Callable.From(GeneratorScript.Run));
outside of a [Tools] ?I'm trying to build something similar to Generator with Prisma, but instead of analysing a DMMF.Model, I'm analysing a GDScene. Isn't EditorPlugin the proper way to build Generator script?
For reference here is 2 repo that do Meta programming in a way that I would like to replicate with PackedScene and GetType().Name :
How wrong I'm building my script? Because to my understanding, I'm using the right tools for the job and I get a worst experience for using the right tools... So what I am doing wrong and how I should be doing it instead, if it's "by design"? What is the "by design" way to do solve what I'm experiencing?
Scripts (both C# and GDScript) are only instantiated and executed at runtime by default, unless they are marked as tool scripts (with the [Tool]
attribute in C# and the @tool
annotation in GDScript). I think this is already well documented. See the Running code in the editor documentation page.
As a consequence of this, nodes and resources retrieved in a plugin that is running in the editor, will not have instantiated its script unless it's marked as tool.
Let's say you have a script MyNode
like this one:
public partial class MyNode : Node2D
{
[Export] public int MyNumber { get; set; }
}
Since the script is not marked as tool, when running in the editor we can't create an instance of MyNode
, because of the rules just explained above. Instead, we use the base built-in type to create it (Node2D
).
So when you retrieve a node with the MyNode
script attached, you'll get a Node2D
instance. The System.Object.GetType
API will give you a System.Type
instance that corresponds to the real type of the instance, which is Node2D
(a MyNode
instance was never created).
This is by design, because we don't want to execute a non-tool script in the editor. Even calling the constructor can have side-effects.
But this is just a consequence of the rule that non-tool scripts are not executed in the editor, if they are not executed in the editor they can't be instantiated and therefore an instance of MyType
can't exist. I feel like this rule is well documented, but if you think it's not clear enough we can always improve the documentation.
Regarding your specific use-case, @Maximilian-Seitz already told you how to access the script information but you might have missed it. You can retrieve the script instance, for example:
var nodeScript = node.GetScript().As<Script?>();
if (nodeScript is not null && nodeScript.ResourcePath == "res://MyNode.cs")
{
// The node has the 'MyNode' script attached.
// Let's set the 'MyNumber' property.
node.Set("MyNumber", 42);
}
Or you can also mark MyNode
as a tool-script with [Tool]
. That way, the script will be instantiated when running in the editor, and then you can use it as you normally would.
@raulsntos Thanks for the details explanation. Thanks for the Demo about GetScript().As<Script?>();
That was the alternative I was looking for! I got the value I was looking for. I haven't yet test it out on a diverse set of scenes yet to see if it's a reliable alternative, but that seem to get the information I was looking for. Thanks!
Sorry @Maximilian-Seitz I was confuse about the meaning of the script part. Example of code would have make it clearer to me.
Or you can also mark MyNode as a tool-script with [Tool]. That way, the script will be instantiated when running in the editor, and then you can use it as you normally would.
Maybe I'm not understanding it right, but should the Tool Attribute only being set when used for visually updating things through the editor? I mean, it feel like you should not use Tool unless you really need it, but maybe I did not understand that I should use it more often? So does it make sense to have many of your GlobalClass also being Tool ?
Maybe I'm not understanding it right, but should the Tool Attribute only being set when used for visually updating things through the editor?
It's simply for running any code in the editor, check the link above for more details
The documentation you're looking for can be found in the documentation page linked by @raulsntos. Specifically these subsections:
Code from other nodes doesn't run in the editor.
This includes the method GetType
, among others. It could be more explicit, but this kind of behavior, and warnings about the fragility of tool
scripts, is reiterated throughout this page, and the page is apparently already long enough for people to not read it, so I doubt being more explicit would help.(These are just two mentions of these kinds of warnings I've found at a quick glance)
I understand what you mean and to be completely honest, I'm writting mostly code and barely touch any Visual feature of the Editor for the past months of my Godot Journey.
I'm building an Action 3D Game with no knowledge of 3D. As I'm learning 3D slowly, I'm writing most of my game through code. My intents are that I'm building a "Framework" of the game I want to build, then when the main Gameplay loop will be fully functionnal, I will start working around the 3D features, which would implied a deep dive in this Tools side of the Engine at this point.
Because writing scripting is more code than any visual thing and because I have copied a other plugins C# code to understand how to make my own plugin, I have not read much on the Tools documentation and I did not consider that I would encounter one of the quirks of Tools and I'm sorry for not understanding that within the first response.
There are many issues that I have met with Godot and C# which aren't always obvious to solve. Some I encounter early on like:
partial RefCounted classes
over C# "normal" classes
and some that are still an issue like: If you search for GetType or GetScript, you won't find much in the documentation and if you haven't read the full documentation, you won't know that it's known and "by design" of a feature that you barely knew about, just that it allowed you to execute some script in the IDE.
I will be closing this issue. Thanks for your time and your help.
Tested versions
4.3-Stable
System information
Window 10 - 4.3-Stable
Issue description
I'm doing some Meta programming and I'm doing it using EditorPlugin because it's seem the right way to do it. Now
GetType().Name
won't return the right thing in addons...Unrelated question:
How do you debug EditorPlugin in C# with VSCode? I can't get the editor to be able to debug addons. Printing code is not fun! π
Steps to reproduce
Minimal reproduction project (MRP)
mrp-addons-type.zip