我们在使用Unity引擎的时候,有时候需要去修改某个物体上的Material,在Unity的Renderer类里,提供了两个方法接口供我们使用。
Renderer.material和Renderer.sharedMaterial
那么这两货有什么区别呢!
Renderer.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.
Unity官方文档的解释是当我们引用修改这个属性的时候,Unity会返回该Render下第一个实例化后的material赋予当前的Rederer组件。
辣么,什么是第一个实例化后的material呢?
Unity中每个MeshRenderer组件里有个Materals属性,这个数组决定了该物体下可以放几个material组件,默认是1。
当同一个物体上有很多个material的时候,我们可以手动更改material组件的上下位置关系。这里的********第一个实例化后的****material****指的就是该物体上从上往下的第一个material组件,而不是Renderer.materials[0]。
cube01.GetComponent<Renderer> ().material.color = Color.black;
上面的代码在执行的时候其实是这样的一个过程:
Material lastMat = cube01.GetComponent<Renderer> ().material;
Material m = Instantiate(lastMat) as Material;
cube01.GetComponent<Renderer> ().material = m;
m.color = Color.black;
也就是说我们每一次引用就会生成一个新的material到内存中。但是在引用后并不会改变我们项目工程中材质球的原始属性设置。
Renderer.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.
当我们改变Renderer.sharedMaterial的时候,所有使用这个材质球物体都会被改变,并且改变后的设置将会被保存在项目工程中。
官方并不推荐使用这个属性去修改material。
什么意思呢?
代码解释:
public GameObject cube01;
public GameObject cube02;
public Material redMat;
假设cube01和cube02共用一个材质redMat,当我们想通过sharedMaterial修改cube01上material的属性的时候,cube02上对应的属性也会被修改。
举个例子:
我们想修改cube01的颜色:
cube01.GetComponent<Renderer> ().sharedMaterial.color = Color.red;
当执行这句代码的时候,cube02也会相应的被修改为红色,而且我们保存在Project中的材质球也会被持久化的改为红色。
总结
当使用Renderer.material的时候,每次调用都会生成一个新的material到内存中去,这在销毁物体的时候需要我们手动去销毁该material,否则会一直存在内存中。
也可以在场景替换的时候使用Resources.UnloadUnusedAssets去统一释放内存。
当使用Renderer.sharedMaterial的时候并不会生成新的material,而是直接在原material上修改,并且修改后的设置就会被保存到项目工程中。一般不推荐使用这个去修改,当某个材质球只被一个gameobject使用的时候可以使用这个去修改,并且最好在修改之前把原属性设置保存,当使用完毕后立即恢复原设置,防止下次加载后的gameobject上还会残留之前的设置信息。
如果是主角这一类gameobject身上需要修改材质的属性或者shader属性比较多的时候,可以第一次使用material,这样可以动态的生成一个material实例,然后再使用sharedmaterial,动态的修改这个新生成的material,而且不会创建新的material。