I'm finding I'm running into a lot of strange errors when using custom resources in C#. Using GDScript, I can: define a custom resource (let's call it ItemResource) and have it export a property of type Texture called 'icon' create a scene (let's call it ItemButton and have it extend TextureButton) with a script marked as 'tool' which also exports a property of type 'resource' override the _process() method of ItemButton to update the image based on the 'icon' field in the resource data create a second scene (let's call it MainMenu) that has an instance of ItemButton in it * set the resource field of my button and see it update in the editor viewport

When I try to do the same thing in C#, it fails. First of all, the resource fields initially return null even if they have been set (I'm guessing some internal process has not finished setting up the resource yet). If you try to get the value of a field of type Texture before your resource has finished setting up, Godot will crash (as a work around, I have to check if one of the string fields on my resource is null before trying to get the Texture value). Trying to do any of this in a script marked [Tool] seems right out. Any tool script that attempts to access the resource in the _Process() method prints an unending stream of error messages to the console:

Unhandled Exception:
System.InvalidCastException: Specified cast is not valid.
  at ItemButton._Process (System.Single delta) [0x00001] in <fee57e23638e4718980313c16c4a0742>:0
ERROR: System.InvalidCastException: Specified cast is not valid.
   at: debug_send_unhandled_exception_error (modules/mono/mono_gd/gd_mono_utils.cpp:369)

I would prefer to use C# because I find it to be a language that is easier to use for larger projects, but this incompability with custom resources is a problem. Is there a way around this?

  • So it turns out you need to add the [Tool] tag to the resource source file too for the editor to be able to use them. Once I did that, everything worked.

Hmm, strange. Can you access _notification in C# without it printing the error messages to the console? If so, you could use NOTIFICATION_PROCESS and run any of your _process code in there, though it wouldn't be as streamlined as it is in GDScript.

I think it would be something like this, but I'm writing it off memory so it may need adjustments

void _Notification(int what)
{
	// Might be Node::NOTIFICATION_PROCESS ... not sure
	if (what == NOTIFICATION_PROCESS)
	{
		process_function(get_process_delta_time())
	}
}

void process_function(float delta)
{
	// _process code here!
}

I think you will need to call SetProcess(True) as well in _Ready in order to get the NOTIFICATION_PROCESS signal, but I'm not 100% sure.

The notification method only defines 'what' methods for PostInitialize and PreDelete. I don't think I can catch the _Process update event there.

I'm attaching some projects that illustrate the problem. The GDScript one works and demonstrates what I'd like the C# one to do.

8 days later

So it turns out you need to add the [Tool] tag to the resource source file too for the editor to be able to use them. Once I did that, everything worked.

    a year later
    3 months later

    kitfox Thank you! I was having the same issue and if it wasn't for your comment, I would probably try something way less practical.