开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

首页   >   博客   >   a5302770826

游戏CPU节省--------------------对象池

个人分类: CPU节省 | 2018-3-22 15:23
游戏制作引擎:unity
       编程语言:c# 
       在第一次制作游戏场景中的玩家消灭敌人的时候,我使用的是最为直观的Destory来进行销毁。直到

学了更多的东西才了解到一些游戏运行时节省Cpu的方法,Destory在这里相比对象池更消耗CPU。所以,对

象池的使用可以让游戏运行起来更流畅,速度更快,可能一个场景节省0.1s,100个场景就能节省10s

,那么这个游戏也就更有可玩性了。
       因为对象池整个游戏中只需要一个,所以将他设置成静态的。对象池中的游戏对象可以用

List或是Dictionay来存,这样当我们需要的时候,可以通过键来找当前的游戏对象,在下面就先说一下

List在对象池的运用。
       首先举一个例子:坦克大战1990。这个游戏是小时候的回忆,所以应该很多人都玩过,在这个游戏

里,敌人坦克是在几个固定的生成点生成的,同时,玩家和敌人坦克都会发射子弹,那么子弹也需要生成,

也就是说,在这个游戏的对象池里,需要用3个List来存。那么这个对象池中应该实例化3个静态公有的

List:
       public static List<GameObject> BulletPool = new List<GameObject>();// 敌人子弹集合
       public static List<GameObject> EnemyPool = new List<GameObject>();        // 敌人集合
       public static List<GameObject> PlayerBulletPool = new List<GameObject>(); // 玩家子弹集

       定义一个用来生成游戏对象的函数
       static object obj = new object();//定义一个静态obj,用来锁定进程防止同时生成或销毁游戏

物体时报错
       public static GameObject Instance(GameObject _gameObject, Vector3 vector, ObjPool pool) 

// 参数为要生成的游戏对象,生成的位置,枚举要生成的类型
    {
        List<GameObject> list;
         lock(obj)      //用互斥锁来锁定当前进程,在进程结束时将其释放
          {
            if (pool == ObjPool.enemy)//通过枚举类型判断要用哪个List装对象
            {
                list = EnemyPool;
            }
            else if (pool == ObjPool.enemybullet)
            {
                list = BulletPool;
            }
            else
            {
                list = PlayerBulletPool;
            }
            for (int i = 0; i < list.Count; i++)
            {
                if (!list[i].activeSelf)
                {  
                    list[i].SetActive(true);
                    list[i].transform.position = vector;
                    return list[i];                                          //如果GameObject

的activeSelf为false,就把list里的第i项拿出来用,设置其坐标
                }
            }
            GameObject instance = GameObject.Instantiate(_gameObject, vector, 

Quaternion.identity);
            list.Add(instance);                                         //如果要生成的

GameObject不在List中,就生成一个,然后添加进List中
            return instance;
        } 
    }
        上面的函数实现了用gameobject的activeSelf属性来生成对象,那么因为对象池是静态的,且存的

对象是引用类型,在游戏重新开始时需要将其清空,否则会报异常。
         public static void ClearPool()
    {
        BulletPool.Clear();
        EnemyPool.Clear();
        PlayerBulletPool.Clear();
    }
       以上的脚本做的对象池已经可以使用了,那么在需要游戏对象销毁时只需要将对象的active设

置为false就可以了,因为对象生出出来的时候已经在对应的List里了。
       例:
       gameobject.SetActive(false);
0 0

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册帐号
返回顶部