一、前言
我们在Unity中对材质进行操作时,会经常用到material和sharedMaterial这两个变量,那么他们到底有什么不同呢,本文对这两个变量进行了简单的分析总结。
二、Unity文档说明
在Unity文档中是这样介绍这两个变量的
从官方文档中我们可以非常清楚的了解到,material是创建了一个新的材质的实例并且赋给这个对象,因此此时修改材质的一些属性并不会影响到源材质,也就不会影响到其他使用同种材质的对象,因为修改的是新的实例;
而sharedMaterial获取到的是源材质,如果修改属性会对所有引用这个材质的对象都进行修改。
三、实验
接下来我们将对两个使用同种材质的对象进行一些操作。
现在场景中存在两个使用相同材质的立方体,左侧为A,右侧为B。
1.修改A的material
现在给A添加脚本
运行后的结果
我们可以看到A的颜色发生了改变而B没有改变,并且A中的Render中的Materials可以很清楚的看到材质多了一个Instance,说明修改的是新的材质的实例,不会对源材质进行修改,B的颜色也就不会改变。
2.修改A的sharedMaterial
我们将代码改为
运行后的结果
很清楚的看到A和B的颜色都发生改变,说明sharedMaterial修改的是源材质的属性,所有引用该材质的对象都会发生变化;并且他还会修改本地文件Project内该材质的属性。
可以看到这个材质的颜色已经被修改了。
3.先修改A的sharedMaterial,再修改A的material
此时这个材质的默认颜色为蓝色。
我们将代码修改为
依据之前的两次实验,我们这次猜测,A的颜色会是黄色,B的颜色会是黑色。
实验结果如下
我们的猜测正确,因为首先将源材质修改为黑色,A和B都使用了这个材质,所有就都会变成黑色,此时再对A的material修改,相对于创建了一个新的实例,可以看到A的Render中Materials右侧多了Instance,说明是新的实例,这个新的材质实例的颜色为黄色,修改它不会影响到B。
4.先修改A的material,再修改A的sharedMaterial
此时源材质的颜色为黑色。
将代码修改为
实验结果
我们发现B并没有变成绿色,这是什么原因?
因为我们首先修改的A的material,相对于创建了一个新的材质实例,并将它改为红色,再对A的sharedMaterial进行修改,因为A的material已经被替换为了新的实例,因此他的sharedMaterial就是之前创建的新的实例,和B中使用的材质已经不是同一个了,所以将它的sharedMaterial改为绿色只会影响到A,而B不会受到影响。
此时本地文件Project内的材质颜色仍为黑色,也证明了它没有被修改。
四、注意事项
我们可以看到在Renderer.material的官方文档中有这么一句话:
注意:\ 该函数自动实例化材质并使其对该渲染器唯一。 当销毁游戏对象时,您负责销毁该材质。Resources.UnloadUnusedAssets 也会销毁材质,但是通常仅当加载新关卡时调用。
这一点尤其重要,因为如果你在运行时频繁访问material属性来改变对象的材质属性,可能会无意中创建很多不必要的材质副本,这可能会导致内存占用过高和垃圾回收问题。这种情况下,优化的做法是提前创建所需的材质副本,并在需要时将它们分配给对象,而不是反复访问material属性。