Condividi tramite


Panoramica dell'istanza del materiale - MRTK3

Il MaterialInstance comportamento si attiva nel rilevamento della durata del materiale dell'istanza e elimina automaticamente i materiali istanzati per l'utente. Questo componente di utilità può essere usato come sostituzione di Renderer.material o Renderer.materials.

Nota

I materialPropertyBlock sono preferiti rispetto alla creazione di istanze di materiale, ma non sono sempre disponibili in tutti gli scenari.

Perché l'uso di Renderer.material può essere un problema? Se si aggiunge il codice seguente a una scena di Unity e si preme l'utilizzo della memoria di riproduzione, l'aumento e l'aumento continueranno:

public class Leak : MonoBehaviour
{
    private void Update()
    {
        var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        // Memory leak, the material allocated is not tracked & destroyed.
        cube.GetComponent<Renderer>().material.color = Color.red;
        ...
        Destroy(cube);
    }
}

Nota

Il comportamento di perdita precedente causa l'arresto anomalo di Unity se è stato eseguito per troppo tempo.

In alternativa, provare a usare il MaterialInstance comportamento:

public class NoLeak : MonoBehaviour
{
    private void Update()
    {
        var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        // No memory leak, the material allocated is tracked & destroyed by MaterialInstance.
        cube.EnsureComponent<MaterialInstance>().Material.color = Color.red;
        ...
        Destroy(cube);
    }
}

Utilizzo

Quando si richiama renderer.material/i di Unity, Unity crea automaticamente un'istanza dei nuovi materiali. È responsabilità del chiamante distruggere i materiali quando un materiale non è più necessario o l'oggetto del gioco viene distrutto. Il MaterialInstance comportamento consente di evitare perdite di materiale e mantiene coerenti i percorsi di allocazione dei materiali durante la modifica e la fase di esecuzione.

Quando un MaterialPropertyBlock non può essere usato e un materiale deve essere istanzato, MaterialInstance può essere usato come segue:

public class MyBehaviour : MonoBehaviour
{
    // Assigned via the inspector.
    public Renderer targetRenderer;

    private void OnEnable()
    {
        Material material = targetRenderer.EnsureComponent<MaterialInstance>().Material;
        material.color = Color.red;
        ...
    }
}

Se più oggetti richiedono la proprietà dell'istanza del materiale, è consigliabile acquisire la proprietà esplicita per il rilevamento dei riferimenti. Esiste un'interfaccia facoltativa denominata IMaterialInstanceOwner per facilitare la proprietà. Di seguito è riportato un esempio di utilizzo:

public class MyBehaviour : MonoBehaviour,  IMaterialInstanceOwner
{
    // Assigned via the inspector.
    public Renderer targetRenderer;

    private void OnEnable()
    {
        Material material = targetRenderer.EnsureComponent<MaterialInstance>().AcquireMaterial(this);
        material.color = Color.red;
        ...
    }

    private void OnDisable()
    {
        targetRenderer.GetComponent<MaterialInstance>()?.ReleaseMaterial(this)
    }

    public void OnMaterialChanged(MaterialInstance materialInstance)
    {
        // Optional method for when materials change outside of the MaterialInstance.
        ...
    }
}

Per altre informazioni, vedere l'esempio di utilizzo illustrato all'interno del ClippingPrimitive comportamento.

Vedere anche