Materiaalexemplaren — MRTK2

Het MaterialInstance gedrag is een assistent bij het bijhouden van de levensduur van exemplaarmateriaal en vernietigt automatisch exemplaarmateriaal voor de gebruiker. Dit hulpprogrammaonderdeel kan worden gebruikt als vervanging voor Renderer.material of Renderer.materials.

Notitie

MaterialPropertyBlocks hebben de voorkeur boven materiaal instancing, maar zijn niet altijd beschikbaar in alle scenario's.

Waarom kan het gebruik van Renderer.material een probleem zijn? Als u de onderstaande code toevoegt aan een Unity-scène en op Afspelen klikt, blijft het geheugengebruik stijgen en stijgen:

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);
    }
}

Notitie

Het bovenstaande lekgedrag crasht Unity als het te lang wordt uitgevoerd.

Als alternatief kunt u het MaterialInstance volgende proberen:

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);
    }
}

Gebruik

Wanneer u Renderer.material(s) van Unity aanroept, maakt Unity automatisch een instantie van nieuwe materialen. Het is de verantwoordelijkheid van de beller om de materialen te vernietigen wanneer een materiaal niet meer nodig is of het spelobject wordt vernietigd. Het MaterialInstance gedrag helpt materiaallekken te voorkomen en houdt materiaaltoewijzingspaden consistent tijdens bewerkings- en uitvoeringstijd.

Wanneer een MaterialPropertyBlock niet kan worden gebruikt en een materiaal moet worden uitgevoerd, MaterialInstance kan als volgt worden gebruikt:

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

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

Als meerdere objecten eigendom van het materiaalexemplaren nodig hebben, kunt u het beste expliciet eigendom nemen voor het bijhouden van verwijzingen. (Er bestaat een optionele interface met de naam IMaterialInstanceOwner om te helpen met eigendom.) Hieronder ziet u een voorbeeld van gebruik:

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.
        ...
    }
}

Zie voor meer informatie het voorbeeldgebruik dat in het ClippingPrimitive gedrag wordt gedemonstreerd.

Zie ook