Caso material

Os MaterialInstance assessores de comportamento no rastreio do tempo de vida do material de exemplo e destrói automaticamente materiais de instância para o utilizador. Este componente de utilidade pode ser utilizado como substituto de Renderer.material ou renderer.materials.

Nota

Os Blocos de Materiais são preferidos em relação à instalação de materiais, mas nem sempre estão disponíveis em todos os cenários.

Por que usar renderer.material pode ser um problema? Se adicionar o código abaixo a uma cena de Unidade e atingir o uso da memória de reprodução continuará a subir e a subir:

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

O comportamento acima do Leak irá colidir com a Unidade se formos corridos durante demasiado tempo!

Como alternativa, tente usar o 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);
    }
}

Utilização

Ao invocar o renderer.material(s) da Unidade, a Unidade instantaneamente novos materiais. É da responsabilidade do chamador destruir os materiais quando um material já não é necessário ou o objeto do jogo é destruído. O MaterialInstance comportamento ajuda a evitar fugas de material e mantém os caminhos de alocação de material consistentes durante a edição e o tempo de execução.

Quando um MaterialPropertyBlock não pode ser utilizado e um material deve ser incluído, pode ser usado da seguinte forma:

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 vários objetos precisam de propriedade do material, é melhor tomar a propriedade explícita para rastreamento de referência. (Existe uma interface opcional chamada IMaterialInstanceOwner para auxiliar com a propriedade.) Abaixo está a utilização por exemplo:

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

Para mais informações consulte o uso do exemplo demonstrado dentro do ClippingPrimitive comportamento.

Ver também