Is the script really duplicating the mesh, and not for example a meshinstance? If you have multiple meshinstances drawing the same mesh, it is still just one mesh unless you explicitly dupllicate the resource. However, most of the time you don't want to do that, since it uses unnecessary resources. If you want your meshinstances to have different materials, then one solution could be to set the material on the instance instead of directly on the mesh. Just make sure you actually duplicate the material, so you're not assigning the same material resource to all the instances. If you're working with custom shaders, then I think you can use per instance parameters to for example make them have different colours.
#change should be only for 1 mesh, not for all !
1 messages · Page 1 of 1 (latest)
Try duplicate material not mesh: material = material.duplicate()
try local to scene then:
I think you've got variable typing syntax wrong btw. You declare variables like this:
var mesh: Mesh
var mesh: Mesh = get_mesh()
var mesh := get_mesh() # if get_mesh has Mesh return type
var mesh := get_mesh() as Mesh # if you need to cast the returned value
You're only creating a local material variable in that function, you need to assign it to the node for it to have any effect on the scene. But I think you should only duplicate the original material once. e.g.
extends MeshInstance3D
func _ready():
material_override = material_override.duplicate()
func change_color():
material_override.albedo = Color.RED
Yes, the typing thing wasn't meant to solve your problem, just a side-note 🙂
This still sets the colour for all of your scene instances, right? Or did I misunderstand your current problem?
Ok. Anyhow, the basic idea is to get a reference to the "original" material, duplicate it, and then assign it as override material for the mesh instance.
in ready:
mesh_instance.mesh = mesh_instance.mesh.duplicate()
mesh_instance.mesh.surface_set_material(0, Material.new())
and when run game:
To update material not set new one you need to duplicate also material:
mesh_instance.mesh = mesh_instance.mesh.duplicate()
var mat = mesh_instance.mesh.surface_get_material(0)
mesh_instance.mesh.surface_set_material(0, mat.duplicate())
mat = mesh_instance.mesh.surface_get_material(0)
mat.set_shader_parameter("cell_color", Vector4(1,1,1,1))
duplicate() has some flags you can change, but i am not sure if they will prevent this. Lemme check the git issue, seems to be closed as a false alarm or working as intended.
Welp, that was a duplicate, the original issue is still open, but someone provided a workaround in the comments.
https://github.com/godotengine/godot/issues/45350
The other solution is to manually duplicate the material on the new node.
For me "local to scene" option don't work even when set for mesh and material
can you post script for object you try to create, and change color?
Change var material = Material to var material = Material.new()
don't use absolute patch in editor use copy path you will get "res://Map/Materials/red_alpha_material.tres"
for formating code use ` three times
In _ready for meshinstance3d try to add:
self.mesh = self.mesh.duplicate()
var mat = self.mesh.surface_get_material(0)
self.mesh.surface_set_material(0, mat.duplicate())```
Don't know if I am 100% correct but when you run instantiate(), this not create new mesh and material for performance purpose. So when you change material you change it in all added object. Because mesh is linked with material you must cuplicate mesh and material to be able to change them in on instance of object
But you add the same material if it is already loaded why added it second time? Don't need as for performance is better to use existend one.
Godot don't know that you want to test and for this you have duplicate or local_to_scene that don't work in this scenerio
if new instance is MeshInstance3D why get_node? Don't know how override_material works
add this one line to MeshInstance3D _ready: self.mesh = self.mesh.duplicate()
and test change material with var mat = Material.new()
or when you create instance do: instance.mesh = instance.mesh.duplicate()
extends MeshInstance3D
#Called when the node enters the scene tree for the first time.
func _ready() -> void:
self.mesh = self.mesh.duplicate()
#Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass
func _on_area_3_dparticule_area_entered(area: Area3D) -> void:
var material = Material.new()
material.set_albedo(Color(0,1,1))
mesh.surface_set_material(0, material)
btw to format code
```swift
<code/>
```
remove this line and check with default new material
The first line var material = Material.new() is redundant as you instantly replace the new material with an existing one.
What i DO recommend is creating a duplicate like this:
material = material.duplicate(true)
This would replace the material it has with an indentical one. So it is no longer being shared with the other node.
Then I don't know, what you try to achieve.