Material 和 ShareMaterial 区别

官方定义:

material:

Returns the first instantiated Material assigned to the renderer.

Modifying material will change the material for this object only.

If the material is used by any other renderers, this will clone the shared material and start using it from now on.


sharedMaterial:

The shared material of this object.

Modifying sharedMaterial will change the appearance of all objects using this material, and change material settings that are stored in the project too.

It is not recommended to modify materials returned by sharedMaterial. If you want to modify the material of a renderer use material instead.


初始状态:



测试一:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestMaterial : MonoBehaviour {

    public GameObject cube;

	// Use this for initialization
	void Start () {
        Renderer cubeRenderer = cube.GetComponent<Renderer>();

        GameObject cube1 = Instantiate(cube);
        cube1.transform.position = new Vector3(2.0f, 0.0f, 0.0f);
        Renderer cube1Renderer = cube1.GetComponent<Renderer>();

        if (cubeRenderer.sharedMaterial == cube1Renderer.sharedMaterial)
        {
            Debug.Log("cube1 sharedMaterial == cube sharedMaterial");
        }
        else
        {
            Debug.Log("cube1 sharedMaterial != cube sharedMaterial");
        }

        //这句调用后,产生变化
        cube1Renderer.material.color = Color.blue;

        if (cubeRenderer.sharedMaterial == cube1Renderer.sharedMaterial)
        {
            Debug.Log("cube1 sharedMaterial == cube sharedMaterial");
        }
        else
        {
            Debug.Log("cube1 sharedMaterial != cube sharedMaterial");
        }

        if (cube1Renderer.material == cube1Renderer.sharedMaterial)
        {
            Debug.Log("cube1 material == cube1 sharedMaterial");
        }
        else
        {
            Debug.Log("cube1 material != cube1 sharedMaterial");
        }

    }
}

结果分析:

    Instantiate对象后,cube和cube1的shareMaterial都是一样的,引用的材质都是本地M0。 当调用cube1Renderer.material后,cube和cube1的shareMaterial就不一样了,但是cube1的material和shareMaterial却一样了。根据官方的解释,当调用cube1Renderer.material 后,会根据第一个赋值给renderer的材质实例化一份新的材质出来,这里第一个赋值的材质是M0,所以实例化出来的对象是M0(Instance), 并且此时cube1的material和shareMaterial的值都是M0(Instance).


测试2


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestMaterial : MonoBehaviour {

    public GameObject cube;

	// Use this for initialization
	void Start () {
        Renderer cubeRenderer = cube.GetComponent<Renderer>();
        Material M0 = cubeRenderer.sharedMaterial;
        Material M1 = new Material(Shader.Find("Unlit/Color"));
        //使用这句的结果和cubeRenderer.sharedMaterial是一样的
        //cubeRenderer.material = M1;
        cubeRenderer.sharedMaterial = M1;
        Material M2 = cubeRenderer.material;
        Material M3 = cubeRenderer.sharedMaterial;

        if(M1 == M2)
        {
            Debug.Log("M1 == M2");
        }
        else
        {
            Debug.Log("M1 != M2");
        }

        if (M1 == M3)
        {
            Debug.Log("M1 == M3");
        }
        else
        {
            Debug.Log("M1 != M3");
        }

        if (M2 == M3)
        {
            Debug.Log("M2 == M3");
        }
        else
        {
            Debug.Log("M2 != M3");
        }
    }
}

结果分析:

  不论使用cubeRenderer.material = M1 还是 cubeRenderer.sharedMaterial = M1; 结果是一样的。 M1都是作为第一个赋值给Renderer的材质,所以调用cubeRenderer.material后,都将生成一个M1的实例出来。


推测出实现方式:

        private bool mMaterialChange = true;
    //初始材质
    private Material mMaterial = new Material(Shader.Find("Default-Material"));

    public Material material
    {
        set
        {
            mMaterialChange = true;
            mMaterial = value;
        }

        get
        {
            if(mMaterialChange)
            {
                mMaterialChange = false;
                mMaterial = new Material(mMaterial);
            }
            return mMaterial;
        }
    }


    public Material sharedMaterial
    {
        set
        {
            mMaterialChange = true;
            mMaterial = value;
        }

        get
        {
            return mMaterial;
        }
    }
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值