游戏中经常需要用到大量只是参数(比如坐标,旋转角,尺寸,颜色等)有些不同的重复物体,如植物,子弹,粒子等。如果数量非常多,在一个场景中逐一绘制这些对象将会消耗大量的性能。在学习OpenGL的时候我们知道有个实例化的方式,可以在一瞬间绘制数十万个仅仅位置不同的同一个对象而且并不会对GPU造成很高的负担,在实际开发中怎么使用这个方法来提升性能呢?享元模式可以做到这一点。
享元模式的基本思路尽量少向GPU发送数据的数量,从而提升性能。为了做到这一点,我们需要将共享数据(如网格,纹理)单独发送到GPU,然后再将所有对象独有的属性(位置,颜色等)发送的GPU。
由于这个模式相对简单,所以先直接上代码:
using UnityEngine;
using System.Collections;
using System;
public class flyweightTerrain : MonoBehaviour {
public Material redMat;
public Material greenMat;
flyweightTile redTile;
flyweightTile greenTile;
flyweightTile[,] tiles;
int width = 5;
int height = 5;
int[,] terrain = {
{ 0,1,0,0,0},
{ 0,0,0,1,0},
{ 1,0,0,1,0},
{ 1,0,0,0,0},
{ 0,0,1,0,0}
};
void Start () {
redTile = new flyweightTile(redMat, true);
greenTile = new flyweightTile(greenMat, false);
drawTerrain();
}
void drawTerrain() {
tiles = new flyweightTile[width, height];
for (int i = 0; i < width; i++)
for (int j = 0; j < height; j++)
{
if (terrain[i, j] == 0)
tiles[i, j] = greenTile;
else
tiles[i, j] = redTile;
}
for (int i = 0; i < width; i++)
for (int j = 0; j < height; j++)
{
GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
obj.transform.position = new Vector3(i - 2, 0, j);
obj.GetComponent<MeshRenderer>().material = tiles[i, j].mat;
}
}
}
class flyweightTile {
public flyweightTile(Material mat, bool isHard=false){
this.mat = mat;
_ishard = ishard;
}
public Material mat;
bool _ishard = false;
public bool ishard {
get { return _ishard; }
}
}
上例中,flyweightTile是用来存储对象差异属性的类,在这里仅仅需要材质和一个表示是否坚硬的布尔值。通常为了我们需要将每个物体的属性单独存储一份,但是这里使用了享元模式,我们仅仅创建两个flyweightTile对象redTile和greenTile作为元对象,其他所有对象通过引用元对象来实现共享数据。虽然这里我们的元对象仅仅共享了材质数据,但是在实际操作中,材质可能会非常消耗性能,因为有可能会有很多贴图和很复杂的特效在这个材质中,通过共享材质,我们就共享了这份性能消耗。
上述代码实际运行效果:
可以看到,我们仅仅用两个材质就绘制出了整个地面。
转载请注明出处:http://blog.csdn.net/ylbs110/article/details/53862269