mrtk_developmentreleases/2.0.0releases/2.1.0releases/2.2.0
  • 指南
  • API 文档
  • 指南

    Show / Hide Table of Contents

    材质实例 Material instance

    MaterialInstance behavior有助于跟踪材质实例的生命周期,并自动销毁用户的材质实例。这个实用组件可以用来替代Renderer.material 或 Renderer.materials.

    Note

    MaterialPropertyBlocks 比材质实例更受欢迎,但并非在所有场景中都可用。

    为什么使用 Renderer.material 会成为一个问题?如果你把下面的代码添加到一个Unity场景,并点击播放内存使用将继续攀升和攀升:

    public class Leak : MonoBehaviour
    {
        private void Update()
        {
            var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
            // 内存泄漏,分配的材质没有被跟踪和销毁。
            cube.GetComponent<Renderer>().material.color = Color.red;
            ...
            Destroy(cube);
        }
    }
    
    Note

    上述泄漏行为将崩溃Unity如果运行太久!

    另一种方法是尝试使用MaterialInstance behavior:

    public class NoLeak : MonoBehaviour
    {
        private void Update()
        {
            var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
            // 没有内存泄漏,所分配的材质由MaterialInstance进行跟踪和销毁。
            cube.EnsureComponent<MaterialInstance>().Material.color = Color.red;
            ...
            Destroy(cube);
        }
    }
    

    使用

    当调用Unity的Renderer.material(s), Unity y会自动实例化新材质。当不再需要材质或游戏对象被销毁时,调用方有责任销毁材质。 MaterialInstance 有助于避免材质泄漏,并在编辑和运行时保持材质分配路径一致。

    当一个 MaterialPropertyBlock 不能被使用,并且一个材质必须被实例化,MaterialInstance 可以被使用如下:

    public class MyBehaviour : MonoBehaviour
    {
        // 在inspector上指派
        public Renderer targetRenderer;
    
        private void OnEnable()
        {
            Material material = targetRenderer.EnsureComponent<MaterialInstance>().Material;
            material.color = Color.red;
            ...
        }
    }
    

    如果多个对象需要材质实例的所有权,最好采用显式的所有权进行引用跟踪。(一个可选的接口叫做 IMaterialInstanceOwner 来辅助所有权。.) 下面是示例用法:

    public class MyBehaviour : MonoBehaviour,  IMaterialInstanceOwner
    {
        // 在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)
        {
            // 可选方法,当材质在 MaterialInstance外部发生变化时使用。
            ...
        }
    }
    

    有关更多信息,请参见ClippingPrimitive behavior中演示的示例用法.

    建议浏览

    • MRTK 标准着色器
    • Improve this Doc
    In This Article
    • 使用
    • 建议浏览
    Back to top Generated by DocFX