Quick answer: Use MaterialPropertyBlock for per-instance shader properties. Avoids the shared-material trap.

Color tinted per enemy in scene. Designer applies the prefab. All tints revert.

The Fix

public class EnemyTint : MonoBehaviour {
    static readonly int ColorID = Shader.PropertyToID("_BaseColor");
    MaterialPropertyBlock _mpb;
    Renderer _r;

    void Start() {
        _r = GetComponent<Renderer>();
        _mpb = new MaterialPropertyBlock();
    }

    public void SetTint(Color c) {
        _r.GetPropertyBlock(_mpb);
        _mpb.SetColor(ColorID, c);
        _r.SetPropertyBlock(_mpb);
    }
}

MPB lives on the renderer instance. No shared material modification, no prefab desync.

Verifying

Set tint per enemy. Apply prefab: tints persist (they're on the renderer, not the material). Restart play: SetTint reapplies on Start.

“MPB per renderer. Prefab safe.”

Related Issues

For Shader Graph SubGraph, see SubGraph property. For keyword toggle, see keyword toggle.

MPB. Per instance. Safe.