[Unity] Renderer的materials与share
1、默认情况下(无修改),同一个模型的多个实例,共享一份sharedMaterials
,改变某个材质的属性,会影响到这个模型的所有实例。
2、同一个Renderer对象,它的materials与sharedMaterials始终是一样的,无论用什么方式修改它们。(修改其中一个,另一个会一起改变)
3、从Renderer.sharedMaterials
、Renderer.materials
中取值(get),每次调用每次都会返回新的Array对象。
Note that like all arrays returned by Unity, this returns a copy of materials array. If you want to change some materials in it, get the value, change an entry and set materials back.
4、通过Renderer.materials
获取(get)过材质列表后,该Renderer使用的全部材质都会实例化一份【Material变为Material(Instance)】。这以后,该实例的材质列表与其他实例的不再共享。
5、Renderer内部实例化过的材质,不会重复实例化。
1)多次执行Renderer.materials
取值,每个材质最多只会实例化一份
2)给Renderer.materials
或Renderer.sharedMaterials
赋值(set)后,再通过Renderer.materials
取值(get),之前已经在材质列表中实例化过的材质不会变,只有新增材质的会创建一个Instance副本
// 假设
renderer.sharedMaterials = new Material[] { Mat[id=0], Mat[id=1] }
// 第一次取material
var mats = renderer.materials; // 结果变为{ Mat(Instance)[id=2], Mat(Instance)[id=3] }
// 重新赋值
renderer.sharedMaterials = new Material[] { mats[0], new Material()[id=4] }
// 再次取material,注意:这里只有 [id=4] 变为了 [id=5]
mats = renderer.materials; // 结果变为{ Mat(Instance)[id=2], Mat(Instance)[id=5] }
6、在Renderer外修改材质数组,不会影响Renderer中的内容。
// 赋值后修改
Material[] myMats = new Material[] { ... };
Renderer.materials = myMats;
myMats[0] = null; // 对Renderer无影响
// 取值后修改
Material[] getMats = Renderer.materials;
getMats[0] = null; // 对Renderer无影响
附:
1)for遍历的时候,每次都会执行结束条件的判断
// 这里会创建sharedMaterials的(Length+1)个副本,堆内存很浪费
for(int i=0; i<renderer.sharedMaterials.Length; ++i)
2)foreach遍历只会取值一次
// 这里只会创建sharedMaterials的1个副本
foreach (Material m in renderer.sharedMaterials)