How to detect when a Material resource changes?

Godot Version

4.7

Question

I’m writing a plugin for the editor that works as a material previewer for the entire project. I have it generating thumbnails of all the resources in my project. I’m doing this by rendering a thumbnail image of a mesh using the material to an offscreen buffer. (Since there are a large number of materials, I need to take snapshots since creating a separate offscreen buffer for each materail will quickly consume all the available slots for offscreen buffers).

Anyhow, if the user updates the material, I need to update the snapshot. How would I do this? I thought that if I loaded the resource and monitored it’s changed signal that would work, but it’s not being called (for StandardMaterial3D at least). I’m also listening for EditorFileSystem.resources_reimported, but it’s not being called either. How can I detect if the user has made a change to a material resource?

This is a stab but may help.

In Godot, notifications are integer constants sent by the engine to objects and nodes via the virtual _notification(what: int)

What you could do is setup a test to see if a notification is sent to the virtual function when a change is made. Printout the what integer

As a warning you will get many notifications but narrow it down. Here is a partial list.

https://share.google/aimode/nSREEuNWdJsuil4Yz

I don’t think this will help. To override _notification() I’d have to be writing my own class that extends Material. What I’m trying to do is determine when an existing ShaderMaterial3D has changed.

You could connect to the EditorInspector.property_edited signal instead:

@tool
extends EditorPlugin


func _enter_tree() -> void:
	var inspector = EditorInterface.get_inspector()
	inspector.property_edited.connect(_on_property_edited)


func _exit_tree() -> void:
	var inspector = EditorInterface.get_inspector()
	if inspector.property_edited.is_connected(_on_property_edited):
		inspector.property_edited.disconnect(_on_property_edited)
		

func _on_property_edited(property: String) -> void:
	var inspector = EditorInterface.get_inspector()
	var object = inspector.get_edited_object()
	if object is Material:
		printt("Object changed", object.resource_name, property)