Anyagpéldány – MRTK2
A MaterialInstance
viselkedés segít nyomon követni a példányok anyagélettartamát, és automatikusan megsemmisíti a felhasználó példányos anyagait. Ez a segédprogram-összetevő használható a Renderer.material vagy a Renderer.materials helyettesítésére.
Megjegyzés
A MaterialPropertyBlocks használata előnyben részesíthető az anyagbetanítással szemben, de nem mindig érhető el minden esetben.
Miért lehet probléma a Renderer.material használata? Ha hozzáadja az alábbi kódot egy Unity-jelenethez, és eléri a lejátszási memóriahasználatot, az továbbra is mászni és mászni fog:
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 fut!
Alternatív megoldásként próbálja meg használni a viselkedést MaterialInstance
:
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(ok) meghívásakor a Unity automatikusan új anyagokat példányosít. A hívó felelőssége, hogy megsemmisítse az anyagokat, amikor már nincs szükség egy anyagra, vagy a játékobjektum megsemmisül. A MaterialInstance
viselkedés segít elkerülni az anyagszivárgást, és konzisztensen tartja az anyagfoglalási útvonalakat a szerkesztés és a futtatás során.
Ha a MaterialPropertyBlock nem használható, és egy anyagot kell példányosíteni, MaterialInstance
az alábbiak szerint 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 szüksége van az anyagpéldány tulajdonjogára, a legjobb, ha explicit tulajdonjogot vesz igénybe a referenciakövetéshez. (Egy nem kötelezően hívható IMaterialInstanceOwner
felület létezik a tulajdonosi jogú aide számára.) Az alábbi példahasználat:
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ésen belül bemutatott példahasználatot ClippingPrimitive
.