godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91k stars 21.17k forks source link

[Godot4.1.dev4 mono] An error occurs when assigning a value to the [export] script node in the [tool] class #77892

Open xlljc opened 1 year ago

xlljc commented 1 year ago

Godot version

4.1.dev4 mono

System information

windows10

Issue description

[Export] an attribute of type script in the class marked [Tool]. Attempting an assignment in the editor results in an error

modules/mono/glue/runtime_interop.cpp:1325 - System.InvalidCastException: Unable to cast object of type 'Godot.Sprite2D' to type 'Icon'. at Main.SetGodotClassPropertyValue(godot_string_name& name, godot_variant& value) in D:\GameProject\Godot4.1.dev4_bug\Godot.SourceGenerators\Godot.SourceGenerators.ScriptPropertiesGenerator\Main_ScriptProperties.generated.cs:line 13 at Godot.Bridge.CSharpInstanceBridge.Set(IntPtr godotObjectGCHandle, godot_string_name name, godot_variant value) in /root/godot/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/CSharpInstanceBridge.cs:line 57

This bug only exists in mono_4.1.dev4, not in 4.1.dev3 and 4.0.stable

Steps to reproduce

  1. Create scripts Main.cs and Icon.cs, and add [Tool] and [Export] icon to Main.cs.
    
    using Godot;
    using System;

[Tool] public partial class Main : Node2D { [Export()] public Icon Icon; }

 ```cshap
using Godot;
using System;

public partial class Icon : Sprite2D
{
}
  1. Create a scenario Main.tscn. Mount the Main.cs script on the root node and the Icon.cs script on the child node. image

  2. Compile the project and drop the Icon node into the Icon property exported from the Main node. The editor will report an error bug

Note: Be sure to add [Tool], otherwise it will not be repeated

Minimal reproduction project

Godot4.1.dev4_bug.zip

raulsntos commented 1 year ago

The editor can only instantiate classes that are marked as [Tool]. The Icon class is not a tool script so the editor can't instantiate it. It instantiates a Sprite2D which is the closest thing it can instantiate, but this throws an InvalidCastException because a Sprite2D can't be converted to Icon.

In short, every class that you use inside a class marked as [Tool] must also be marked as [Tool].

xlljc commented 1 year ago

编辑器只能实例化标记为 .该类不是工具脚本,因此编辑器无法实例化它。它实例化 a 这是它可以实例化的最接近的东西,但这会抛出一个,因为 a 无法转换为 .[Tool]``Icon``Sprite2D``InvalidCastException``Sprite2D``Icon

简而言之,在标记为的类中使用的每个类也必须标记为 。[Tool]``[Tool]

But it works in 4.1.dev3

raulsntos commented 1 year ago

Before 4.1.dev4 the property wasn't being set, instead it was only setting metadata/_editor_prop_ptr_Icon (this is the backing field that stores the NodePath to the node). You'll notice that the property Icon remains null even after setting it.

It seems this was changed in PR https://github.com/godotengine/godot/pull/76389, now it actually sets the real property as well. This is what users would normally expect so I think this is correct, but it also means that now trying to assign an invalid value will result in the error that you are seeing.