재질 인스턴스 개요 — MRTK3
MaterialInstance
동작은 인스턴스 재질 수명 추적을 보조하고 사용자의 인스턴스 재질을 자동으로 삭제합니다. 이 유틸리티 구성 요소는 Renderer.material 또는 Renderer.materials를 대체하는 용도로 사용할 수 있습니다.
참고
MaterialPropertyBlock은 재질 인스턴스화보다 선호되지만 모든 시나리오에서 항상 사용할 수 있는 것은 아닙니다.
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
라는 선택적 인터페이스가 있습니다.) 다음은 사용 예제입니다.
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
동작 내에 설명된 사용 예제를 참조하세요.