问题描述:
今天实现的一个功能是在敌人实例化之前,先让出生点的地砖闪烁一秒,再生成敌人。使用协程实现。先获取目标地砖的材质属性,确定初始色和高亮色,然后使用Mathf.PingPong()产生振荡效果,进行初始色到高亮色的插值变化。结果发现所有的地砖同时闪烁。
解决:
经过调试发现确实获取到了出生点处的地砖及其材质,但是获取材质的方法用的是GetComponent<Renderer>().sharedMaterial,应该是GetComponent<Renderer>().material。之前在渲染障碍物颜色时使用过这个sharedMaterial,当时在网上查了一下两者的区别:
- sharedMaterial 是共用的 Material,称为共享材质。修改共享材质会改变所用使用该材质的物体,并且编辑器中的材质设置也会改变。
- material 是独立的 Material,返回分配给渲染器的第一个材质。修改材质仅会改变该物体的材质。如果该材质被其他的渲染器使用,将克隆该材质并用于当前的渲染器。
所以当我改变sharedMaterial的颜色时,所有地砖都使用的改材质,所以全部都会变色。那么问题又来了,之前生成的那么多障碍物使用的就是sharedMaterial,为什么还能显示那么多种颜色呢?以下是源码:
// 渲染障碍物颜色
Renderer obstacleRenderer = newObstacle.GetComponent<Renderer>();
Material obstacleMaterial = new Material(obstacleRenderer.sharedMaterial); // 使用material属性可能会造成内存泄漏
float colourPercent = randomCoord.y / (float)currentMap.mapSize.y; // 提前转化为float防止int整除
obstacleMaterial.color = Color.Lerp(currentMap.foregroundColour, currentMap.backgroundColour, colourPercent);
obstacleRenderer.sharedMaterial = obstacleMaterial;
虽然中间new了新的材质,但是最后也是直接将sharedMaterial换成新的obstacleMaterial,按道理来说所有的障碍物也应该会变成同一种颜色?尝试将代码改成如下,发现所有障碍物都变成同一种颜色了。
Renderer obstacleRenderer = newObstacle.GetComponent<Renderer>();
Material obstacleMaterial = new Material(obstacleRenderer.sharedMaterial); // 使用material属性可能会造成内存泄漏
float colourPercent = randomCoord.y / (float)currentMap.mapSize.y; // 提前转化为float防止int整除
Color color = Color.Lerp(currentMap.foregroundColour, currentMap.backgroundColour, colourPercent);
obstacleRenderer.sharedMaterial.color = color;
两者区别在于,第一种直接将物体的sharedMaterial换成才new出来的新的Matrial,而第二种是将sharedMaterial的color属性换成新的Color。目前合理的解释就是第一种直接放弃了对原Material的指引,指向了新的Material了,即Material和Color都被改变;第二种仍然指向原来的Material,只有其Color属性被改变。但是尝试了一下打印这个sharedMaterial的地址发现第二种改变前后也是不一样的,如果上面的解释是正确的话地址应该不变才对……
(未解决)明天写个test测试一下直接改变sharedMaterial而不是sharedMaterial.Color会不会影响别的使用了改材质的物体。
原创文章,作者:wdmbts,如若转载,请注明出处:https://blog.ytso.com/277456.html