Skip to content
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

[C#] Scripts that export a 'resource' type in a property cannot be assigned without an InvalidCastException #83980

Closed
Panthr75 opened this issue Oct 26, 2023 · 2 comments

Comments

@Panthr75
Copy link

Panthr75 commented Oct 26, 2023

Godot version

v4.1.2.stable.mono.official [399c9dc]

System information

Windows 10

Issue description

For C# Scripts that have a custom property list where one of the properties's hint is HintType.ResourceType and the hint string is the name of the script, attempting to assign it throws an InvalidCastException:

modules/mono/glue/runtime_interop.cpp:1324 - System.InvalidCastException: Unable to cast object of type 'Godot.Resource' to type 'Y'.
  at X._Set(StringName property, Variant value)
  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 67

Steps to reproduce

Generic Overview

  1. Create a script named Foo.cs
  2. Create a script named Bar.cs
  3. Open the Bar.cs script. Make the base class Resource
  4. Mark Bar as a GlobalClass
  5. Open Foo.cs
  6. Mark Foo as a Tool, and GlobalClass.
  7. Paste the following code inside the class body of Foo:
private Bar barRef;

public override Variant _Get(StringName property)
{
  if (property == "bar_ref")
  {
    return this.barRef;
  }
  return default;
}

public override bool _Set(StringName property, Variant value)
{
  if (property == "bar_ref")
  {
    this.barRef = value.As<Bar>();
  }
  return true;
}

public override Array<Dictionary> _GetPropertyList()
{
  return new Array<Dictionary>()
  {
    new Dictionary()
    {
      ["name"] = "bar_ref",
      ["hint"] = (int)PropertyHint.ResourceType,
      ["type"] = (int)Variant.Type.Object,
      ["usage"] = (long)PropertyUsageFlags.Default,
      ["hint_string"] = nameof(Bar)
    }
  };
}
  1. Import missing references like Godot.Collections
  2. Save both scripts and recompile them
  3. Create a new Bar resource in the FileSystem
  4. Create a new Foo object in a scene.
  5. Attempt to assign Bar to bar_ref property in Foo
  6. InvalidCastException

Minimal Reproduction Project

  1. Open up the project
  2. Make sure to compile the scripts
  3. Open root scene if not already open.
  4. On the root node, there should be a script named Foo. If not, add it.
  5. Click on the Bar Ref property and assign it to bar in the FileSystem
  6. InvalidCastException

Minimal reproduction project

project.zip

@raulsntos
Copy link
Member

Tool scripts are instantiated and executed in the editor, but non-Tool scripts are not. Your Bar type is not marked with the [Tool] attribute so the editor can't instantiate it when you assign it to a property of the Tool script Foo.

Add the [Tool] attribute to the Bar type or use a less specific type for the Foo.barRef field (e.g.: Resource).

@raulsntos raulsntos closed this as not planned Won't fix, can't repro, duplicate, stale Oct 26, 2023
@raulsntos raulsntos added archived and removed bug labels Oct 26, 2023
@Panthr75
Copy link
Author

Is it possible that there make a specific error for this in the editor instead of throwing an Invalid Cast Exception?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants