Resources are shared between Scene instances even when "local to scene" is checked

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Matthew Goulart

I have the following setup:

    |-MeshInstance3D (both mesh and material come from rock.res)
            |- CollisionShape3D

My levels consist of different blocks (no not minecraft) and the levels are generated in code. I instantiate and place each block like this:

var block = blockList[blockId].Instantiate<MeshInstance3D>();
block.Position = new Vector3(j, 0, i);

So at this point, I know that if I have say 10 of the same block, they all share the same Material. I realize it’s probably not a good idea to have separate materials for each block, but for testing purposes I’d like to do it anyways. So I open res://Blocks/Rock.tscn, navigate to the MeshInstance3D -> Surface 0 -> Material and tick off Local to scene. I then save the scene file and rerun.

I’m expecting each block’s material to behave independently. When I try to set Mesh.GetSurfaceMaterial(0).EmissionEnabled to true, all the blocks become emissive.

I also tried setting all the resources in Rock.tscn to Local to scene and no dice.

I even tried doing:

var mat = (StandardMaterial3D)Mesh.SurfaceGetMaterial(0);
mat = (StandardMaterial3D)mat.Duplicate();
mat.EmissionEnabled = true;
Mesh.SurfaceSetMaterial(0, mat);

And it still affects every instance of the scene!!

What am I doing wrong here?

:bust_in_silhouette: Reply From: Inces

Local to the scene only works for scenes set up in editor. When doing it in code, YOu have to use duplicate()
However, You have to notice, that there are 3 material slots in MeshInstance !. If you kept materials in the mesh property, You will have to make mesh unique/ duplicate as well!
Finally, remember that shader file, whoch is part of shader material, is also a resource. So if visual difference depends on shader code, not just shader_params - You have to make this one unique too.