Udostępnij za pośrednictwem


Wystąpienie materiału — MRTK2

Pomocnicy MaterialInstance zachowania w śledzeniu okresu istnienia materiału wystąpienia i automatycznie niszczy wystąpienia materiałów dla użytkownika. Ten składnik narzędziowy może być używany jako zamiennik elementu Renderer.material lub Renderer.materials.

Uwaga

MaterialPropertyBlocks są preferowane w przypadku blokowania materiału, ale nie zawsze są dostępne we wszystkich scenariuszach.

Dlaczego korzystanie z pliku Renderer.material może być problemem? Jeśli dodasz poniższy kod do sceny aparatu Unity i trafisz na użycie pamięci odtwarzania, będzie nadal wspinać się i wspinać:

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

Uwaga

Powyższe zachowanie przecieku spowoduje awarię aparatu Unity , jeśli zostanie uruchomiona zbyt długo!

Alternatywnie spróbuj użyć MaterialInstance zachowania:

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

Użycie

Podczas wywoływania plików Renderer.material(s) aparatu Unity aparat Unity automatycznie tworzy wystąpienie nowych materiałów. Jest to odpowiedzialność wywołującego za zniszczenie materiałów, gdy materiał nie jest już potrzebny lub obiekt gry zostanie zniszczony. Zachowanie MaterialInstance pomaga uniknąć wycieków materiałów i utrzymuje ścieżki alokacji materiału spójne podczas edycji i czasu wykonywania.

Gdy nie można użyć obiektu MaterialPropertyBlock , a materiał musi być wystąpiony, MaterialInstance można go użyć w następujący sposób:

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

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

Jeśli wiele obiektów wymaga własności wystąpienia materiału, najlepiej podjąć jawną własność do śledzenia odwołań. (Opcjonalny interfejs o nazwie IMaterialInstanceOwner istnieje, aby ułatwić własność). Poniżej przedstawiono przykładowe użycie:

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

Aby uzyskać więcej informacji, zobacz przykładowe użycie pokazane w ramach ClippingPrimitive zachowania.

Zobacz też