Anyagpéldány

A példányok anyagának élettartamának nyomon követésében ható viselkedést, és automatikusan megsemmisíti a példányban MaterialInstance használt anyagokat a felhasználó számára. Ez a segédprogram-összetevő helyettesítheti a Renderer.material vagy a Renderer.materials összetevőt.

Megjegyzés

A MaterialPropertyBlocks az előnyben részesített, mint az anyagstabilitálás, de nem mindig érhetők el minden forgatókönyvben.

Miért lehet probléma a Renderer.material használatával? Ha hozzáadja az alábbi kódot egy Unity-jelenethez, és a Play memóriahasználatot nyomja le, az továbbra is el fog omozni:

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

Megjegyzés

A fenti szivárgási viselkedés összeomlik a Unityben, ha túl sokáig futott!

Alternatív megoldásként próbálja meg a következő viselkedést MaterialInstance használni:

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

Használat

A Unity Renderer.material(anyag)hoz létre, amikor a Unity automatikusan példányosul új anyagokat. A hívó felelőssége, hogy megsemmisítse az anyagokat, amikor egy anyagra már nincs szükség, vagy a játékobjektumot megsemmisítik. A viselkedés segít elkerülni az anyagszivárgást, és konzisztensen tartja az anyagkiosztási MaterialInstance útvonalakat a szerkesztés és a futtatás során.

Ha a MaterialPropertyBlock nem használható, és egy anyagot kell példányosítanunk, a következőképpen használható:

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

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

Ha több objektumnak is tulajdonosi jogokat kell tulajdonba vennie az anyagpéldányban, akkor a legjobb, ha a referenciakövetést explicit tulajdonba veszi. (Létezik egy nevű választható IMaterialInstanceOwner felület, amely tulajdonjoggal rendelkezik.) Az alábbiakban egy használati példát mutatunk be:

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

További információért tekintse meg a viselkedésben szemléltetett használati ClippingPrimitive példát.

Lásd még