材料實例概觀 - MRTK3
此 MaterialInstance
行為有助於追蹤實例材質存留期,並自動終結使用者的實例資料。 此公用程式元件可用來取代 Renderer.material 或 Renderer.material。
注意
MaterialPropertyBlocks 優先于材料實例,但並非所有案例都可使用。
為何使用 Renderer.material 是問題? 如果您將下列程式碼新增至 Unity 場景,並叫用播放記憶體使用量將會繼續提升並提升:
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);
}
}
注意
如果執行的時間太長,上述流失行為 將會損毀 Unity !
或者,請嘗試使用 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);
}
}
使用方式
叫用 Unity 的 Renderer.material () 時,Unity 會自動具現化新的材質。 當不再需要材質或終結遊戲物件時,呼叫者必須負責終結材質。 此 MaterialInstance
行為有助於避免材料外泄,並讓材料配置路徑在編輯和執行時間保持一致。
當 無法使用 MaterialPropertyBlock 且必須具現化材質時, MaterialInstance
可以使用如下:
public class MyBehaviour : MonoBehaviour
{
// Assigned via the inspector.
public Renderer targetRenderer;
private void OnEnable()
{
Material material = targetRenderer.EnsureComponent<MaterialInstance>().Material;
material.color = Color.red;
...
}
}
如果多個物件需要材料實例的擁有權,最好取得明確的參考追蹤擁有權。 (名為 的選擇性介面 IMaterialInstanceOwner
存在,具有 ownership.) 以下是範例用法:
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.
...
}
}
如需詳細資訊,請參閱行為內示範的 ClippingPrimitive
範例使用方式。