Quick answer: Declare with instance uniform vec3 color; in the shader. Set via node.set_instance_shader_parameter("color", value). Each MeshInstance3D gets its own value while sharing the material.

You set a uniform per enemy. All enemies turn the same color. Plain uniform is shared via Material; instance uniform is per-node.

The Symptom

Per-instance uniform changes affect every node sharing the material. Want unique values per instance.

The Fix

shader_type spatial;

instance uniform vec3 enemy_color : source_color = vec3(1, 1, 1);

void fragment() {
    ALBEDO = enemy_color;
}

From script:

$Enemy1.set_instance_shader_parameter("enemy_color", Color.RED)
$Enemy2.set_instance_shader_parameter("enemy_color", Color.GREEN)

Each instance now renders with its own color while sharing the material asset.

Verifying

Spawn N instances with different parameter values. Each renders with its unique color. With plain uniform: all change to the last set.

“instance uniform. set_instance_shader_parameter. Per-node values.”

Related Issues

For shader uniform runtime, see runtime uniform. For MultiMesh instance color, see MultiMesh color.

Instance keyword. Per-node uniform.