this post was submitted on 22 Apr 2025
8 points (100.0% liked)

Godot

6570 readers
29 users here now

Welcome to the programming.dev Godot community!

This is a place where you can discuss about anything relating to the Godot game engine. Feel free to ask questions, post tutorials, show off your godot game, etc.

Make sure to follow the Godot CoC while chatting

We have a matrix room that can be used for chatting with other members of the community here

Links

Other Communities

Rules

We have a four strike system in this community where you get warned the first time you break a rule, then given a week ban, then given a year ban, then a permanent ban. Certain actions may bypass this and go straight to permanent ban if severe enough and done with malicious intent

Wormhole

!roguelikedev@programming.dev

Credits

founded 2 years ago
MODERATORS
 

Hi, folks! So, I have the problem with making materials as unique.

Image

I need effects, such as painting of ships in red color, will applies only where particles will spawns. But... As you can see those effects can applies also into other ships.

I've already set these materials as "Local to Scene" into inspector tab.

And have create script for making those materials as unique:

func _make_ship_materials_unique() -> void:
	for i in ship.get_children():
		if i is MeshInstance3D:
			for n in range(i.get_surface_override_material_count()):
				i.mesh.surface_set_material(n, i.mesh.surface_get_material(n).duplicate(true))

But it given me few results ๐Ÿ˜•

If it can help, here's the script of applying of ships painting:

func damaged_spec_effect() -> void:
	for i in ship.get_children():
		if i is MeshInstance3D:
			for n in range(i.get_surface_override_material_count()):
				_create_fade_in_then_out_effect(i.mesh.surface_get_material(n), Color.RED)
func _create_fade_in_then_out_effect(material: Material, final_color: Color) -> void:
	if material is StandardMaterial3D:
		material.albedo_color = Color.WHITE
		var tween = get_tree().create_tween()
		tween.tween_property(material, "albedo_color", final_color, EFFECTS_DURATION / 2)
		tween.tween_property(material, "albedo_color", Color.WHITE, EFFECTS_DURATION / 2)

So, what do I need to do for solving my problem? ๐Ÿค”

you are viewing a single comment's thread
view the rest of the comments
[โ€“] unexposedhazard@discuss.tchncs.de 2 points 2 days ago* (last edited 2 days ago) (6 children)

I have never played much with 3D or materials, but from testing around in the Editor, it seems that both the mesh AND the material need to be unique.

If you have the same mesh attached to multiple MeshInstance3D, then modifying the material of that mesh on any of them will still apply the changes to all MeshInstance3D that use that mesh. All you are doing at that point is giving the same mesh new unique materials over and over.

So i would try duplicating the mesh and then its materials.

As i said, im really not an expert on this, so maybe im completely off the mark here...

[โ€“] aqua_cat@pawb.social 1 points 2 days ago* (last edited 2 days ago) (1 children)

this, also the code is just $[the node with mesh].mesh.duplicate() and the same thing for the material. put it at a func start() and you're set.

[โ€“] unexposedhazard@discuss.tchncs.de 2 points 2 days ago (1 children)

Actually i think you can do it even simpler. Just use i.set_surface_override_material instead of i.mesh.surface_set_material

[โ€“] xolatgames@programming.dev 2 points 2 days ago (1 children)

Thanks a lot to everyone! I'll try it ๐Ÿ˜„

[โ€“] unexposedhazard@discuss.tchncs.de 1 points 2 days ago (1 children)

Let us know if it worked out :)

[โ€“] xolatgames@programming.dev 1 points 2 days ago (1 children)

Thanks a lots, folks! ๐Ÿ˜„ Everything works fine now ๐Ÿ‘๐Ÿผ

Image

What I have to do:

  1. Made don't only materials, but also meshes as unique:
var new_model = model.front.duplicate(true)
var new_ship: Node3D = new_model.instantiate()
new_ship.position = front_model_pos
_model_parent.add_child(new_ship)
_make_ship_materials_unique(new_ship)
  1. Change mesh.surface_set_material to mesh.set_surface_override_material:
func _make_ship_materials_unique(new_ship: Node3D) -> void:
	for i in new_ship.get_children(true):
		if i is MeshInstance3D:
			for n in range(i.get_surface_override_material_count()):
				i.set_surface_override_material(n, i.mesh.surface_get_material(n).duplicate(true))
func damaged_spec_effect() -> void:
	for i in ship.get_children(true):
		if i is MeshInstance3D:
			for n in range(i.get_surface_override_material_count()):
				_create_fade_in_then_out_effect(i.get_surface_override_material(n), Color.RED)

And everything started works as well. Thanks again ๐Ÿค๐Ÿผ

Just out of curiosity is 1. really necessary? What happens if you only do 2. ?

load more comments (4 replies)