#change should be only for 1 mesh, not for all !

1 messages · Page 1 of 1 (latest)

lilac oyster
#

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.

lapis lagoon
#

Try duplicate material not mesh: material = material.duplicate()

lapis lagoon
#

try local to scene then:

lilac oyster
#

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?

lapis lagoon
#

Made some test and make it work. In scene I have to meshinstance3d.

lilac oyster
#

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.

lapis lagoon
#

in ready:

mesh_instance.mesh = mesh_instance.mesh.duplicate()
mesh_instance.mesh.surface_set_material(0, Material.new())
#

and when run game:

hot idol
#

Set the mesh local_to_scene = true

#

As well as the material

lapis lagoon
#

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))
hot idol
#

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.

#

The other solution is to manually duplicate the material on the new node.

lapis lagoon
#

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?

lapis lagoon
#

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/>
```

lapis lagoon
#

remove this line and check with default new material

hot idol
#

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.

lapis lagoon
#

Then I don't know, what you try to achieve.