Istanza materiale - MRTK2
L'aide MaterialInstance
di comportamento nella durata del materiale dell'istanza di rilevamento e distrugge automaticamente i materiali di istanza per l'utente. Questo componente di utilità può essere usato come sostituzione di Renderer.material o Renderer.material.
Nota
MaterialPropertyBlocks è preferibile rispetto al materiale instancing, ma non sempre disponibile in tutti gli scenari.
Perché usare Renderer.material è un problema? Se si aggiunge il codice seguente a una scena unity e l'utilizzo della memoria di hit play continuerà a salire e salire:
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 della perdita precedente si arresterà in modo anomalo su Unity se è stato eseguito troppo a lungo!
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 di Unity, Unity crea automaticamente un'istanza di 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 mantenere coerenti i percorsi di allocazione materiale durante la modifica e l'esecuzione.
Quando non è possibile usare materialPropertyBlock e un materiale deve essere usato, MaterialInstance
può essere usato come indicato di seguito:
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 accettare la proprietà esplicita per il rilevamento dei riferimenti. Un'interfaccia facoltativa denominata IMaterialInstanceOwner
esiste per aiutare con 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'utilizzo dell'esempio illustrato all'interno del ClippingPrimitive
comportamento.