项目中,DC太多,小小一个手游达到了几千DC。发现是Renderer的材质没有弄成共享材质导致的(材质共享,可以开启自动合并mesh,极大减少DC)。因此探究了一下这两个属性。
新建工程,随便建了一个cube,在resource里新建一个材质,在代码里价值赋值,得到了这个结果:
然后两次运行分别执行了这两行代码:
Material sharedMaterial = meshRenderer.sharedMaterial;
没有变化。
Material material = meshRenderer.material;
变化如图:
可以得到结论sharedMaterial属性:直接获取renderer的材质。material属性:会用原材质new一个材质赋值给自己然后传出。
之后在运行多次调用material的代码以后发现,只要调用过一次,并不会重复的从原材料新建材质。会一直使用第一次调用时new出来的材质。
尝试改变sharedMaterial的颜色,发现项目里的材质也被改变。不过只要renderer里的材质不是直接从项目里load出来,而是新建出来的材质,那么改变sharedMaterial并不会改变项目里的材质。
现在继续探究,我分别执行了以下代码,debug结果附在的注释里:
meshRenderer = cube.GetComponent<MeshRenderer>();
meshRenderer.material = Resources.Load<Material>("New Material");
newCube = Instantiate(cube);
MeshRenderer newMeshRenderer = newCube.GetComponent<MeshRenderer>();
Material material = meshRenderer.material;
newMeshRenderer.material=meshRenderer.sharedMaterial;
Debug.Log(newMeshRenderer.sharedMaterial == meshRenderer.sharedMaterial);
//true newCube下的material名字:New Material(Instance)Cube下的material名字:New Material(Instance)
meshRenderer = cube.GetComponent<MeshRenderer>();
meshRenderer.material = Resources.Load<Material>("New Material");
newCube = Instantiate(cube);
MeshRenderer newMeshRenderer = newCube.GetComponent<MeshRenderer>();
Material material = meshRenderer.material;
material = newMeshRenderer.material;
Debug.Log(newMeshRenderer.sharedMaterial==meshRenderer.sharedMaterial);
//false newCube下的material名字:New Material(Instance)Cube下的material名字:New Material(Instance)
meshRenderer = cube.GetComponent<MeshRenderer>();
meshRenderer.material = Resources.Load<Material>("New Material");
newCube = Instantiate(cube);
MeshRenderer newMeshRenderer = newCube.GetComponent<MeshRenderer>();
Material material = meshRenderer.material;
newMeshRenderer.material = meshRenderer.sharedMaterial;
Debug.Log(newMeshRenderer.material == meshRenderer.sharedMaterial);
//false newCube下的material名字:New Material(Instance)(Instance)Cube下的material名字:New Material(Instance)
meshRenderer = cube.GetComponent<MeshRenderer>();
meshRenderer.material = Resources.Load<Material>("New Material");
newCube = Instantiate(cube);
MeshRenderer newMeshRenderer = newCube.GetComponent<MeshRenderer>();
Material material = meshRenderer.material;
newMeshRenderer.sharedMaterial = meshRenderer.sharedMaterial;
Debug.Log(newMeshRenderer.sharedMaterial == meshRenderer.sharedMaterial);
//true newCube下的material名字:New Material(Instance)Cube下的material名字:New Material(Instance)
具体逻辑分析就不赘述了,可以总结如下:
material属性的get:第一次调用会改变renderer里的材质,然后取值。这里第一次的定义是,实际意义上的第一次,以及每次调用过material或sharedMaterial的Set属性以后的第一次。
material属性的set:单纯的给renderer里的材质赋值。
sharedMaterial属性的get:单纯的取值
sharedMaterial属性的set:单纯的赋值
也可以用这样的代码来解释:
public class Renderer {
Material realMaterial;
bool firstGet=true;
Material material
{
get
{
if(firstGet)
{
realMaterial = Object.Instantiate(realMaterial);
firstGet = false;
}
return realMaterial;
}
set
{
firstGet = true;
realMaterial = value;
}
}
Material sharedMaterial
{
get
{
return realMaterial;
}
set
{
firstGet = true;
realMaterial = value;
}
}
}
好了,探究结束,时间仓促,如有谬误欢迎指出。楼主也是边解决问题边撸的博文,感觉不自己记录一点东西,每次遇到类似问题,尽管之前解决过,也需要重新爬贴。所以用自己能理解的描述方式,在博客做记录便于查看确实是好习惯。