找回密码
 立即注册
查看: 7049|回复: 95

[常见问题] unity对象池(优化)

[复制链接]
发表于 2015-1-21 18:06 | 显示全部楼层 |阅读模式
我们在做项目的时候,如果同一个物体要用到好多次,我们就不要再用实例化了,因为每次创建一个新物体是很消耗资源的,引用对象池技术,顾名思义,把所有要用到的对象在初始化的时候都扔到这个池子里,想用的时候拿出来用,不想用的时候放回去,这样会大大节省资源,我在蛮牛上看到一个写对象池不错的code,拿来分享一下。  这个脚本非常简单,但它可以通过大量减少实例化所带来的开销使我的iOS游戏得到很大的性能提升。
  
  • 把脚本ObjectPool.cs链接到一个GameObject上。
  • 在物体预设数组中设置你想要放到池中并重复利用的预设物体。
  • 在缓冲数组中,指定你希望每个物体在游戏开始时被实例化的数量,这样在开始的时候你就有了池对象。
  • 在你的游戏中调用ObjectPool.instance.GetObjectForType(objectType,onlyPooled)来使用它。objectType写你想生成的预设的名字、并为onlyPooled指定布尔值,如果返回真,它将返回你已经放到池中的对象;如果返回假,它将实例化一个全新的对象。(如果你想限制被池对象的数量,那么设定为真,这样做非常有用,尤其是在需要限制同时播放特效的数量的时候)。
  • 确保你从池中调用的对象知道当它被删除时需要返回到池中。
    1.    

    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;

    5. public class ObjectPool : MonoBehaviour
    6. {

    7.     public static ObjectPool instance;

    8.     /// <summary>
    9.     /// The object prefabs which the pool can handle.
    10.     /// </summary>
    11.     public GameObject[] objectPrefabs;

    12.     /// <summary>
    13.     /// The pooled objects currently available.
    14.     /// </summary>
    15.     public List<GameObject>[] pooledObjects;

    16.     /// <summary>
    17.     /// The amount of objects of each type to buffer.
    18.     /// </summary>
    19.     public int[] amountToBuffer;

    20.     public int defaultBufferAmount = 3;

    21.     /// <summary>
    22.     /// The container object that we will keep unused pooled objects so we dont clog up the editor with objects.
    23.     /// </summary>
    24.     protected GameObject containerObject;

    25.     void Awake ()
    26.     {
    27.         instance = this;
    28.     }

    29.     // Use this for initialization
    30.     void Start ()
    31.     {
    32.         containerObject = new GameObject("ObjectPool");

    33.         //Loop through the object prefabs and make a new list for each one.
    34.         //We do this because the pool can only support prefabs set to it in the editor,
    35.         //so we can assume the lists of pooled objects are in the same order as object prefabs in the array
    36.         pooledObjects = new List<GameObject>[objectPrefabs.Length];

    37.         int i = 0;
    38.         foreach ( GameObject objectPrefab in objectPrefabs )
    39.         {
    40.             pooledObjects[i] = new List<GameObject>();

    41.             int bufferAmount;

    42.             if(i < amountToBuffer.Length) bufferAmount = amountToBuffer[i];
    43.             else
    44.                 bufferAmount = defaultBufferAmount;

    45.             for ( int n=0; n<bufferAmount; n++)
    46.             {
    47.                 GameObject newObj = Instantiate(objectPrefab) as GameObject;
    48.                 newObj.name = objectPrefab.name;
    49.                 PoolObject(newObj);
    50.             }

    51.             i++;
    52.         }
    53.     }

    54.     /// <summary>
    55.     /// Gets a new object for the name type provided.  If no object type exists or if onlypooled is true and there is no objects of that type in the pool
    56.     /// then null will be returned.
    57.     /// </summary>
    58.     /// <returns>
    59.     /// The object for type.
    60.     /// </returns>
    61.     /// <param name='objectType'>
    62.     /// Object type.
    63.     /// </param>
    64.     /// <param name='onlyPooled'>
    65.     /// If true, it will only return an object if there is one currently pooled.
    66.     /// </param>
    67.     public GameObject GetObjectForType ( string objectType , bool onlyPooled )
    68.     {
    69.         for(int i=0; i<objectPrefabs.Length; i++)
    70.         {
    71.             GameObject prefab = objectPrefabs[i];
    72.             if(prefab.name == objectType)
    73.             {

    74.                 if(pooledObjects[i].Count > 0)
    75.                 {
    76.                     GameObject pooledObject = pooledObjects[i][0];
    77.                     pooledObjects[i].RemoveAt(0);
    78.                     pooledObject.transform.parent = null;
    79.                     pooledObject.SetActiveRecursively(true);

    80.                     return pooledObject;

    81.                 } else if(!onlyPooled) {
    82.                     return Instantiate(objectPrefabs[i]) as GameObject;
    83.                 }

    84.                 break;

    85.             }
    86.         }

    87.         //If we have gotten here either there was no object of the specified type or non were left in the pool with onlyPooled set to true
    88.         return null;
    89.     }

    90.     /// <summary>
    91.     /// Pools the object specified.  Will not be pooled if there is no prefab of that type.
    92.     /// </summary>
    93.     /// <param name='obj'>
    94.     /// Object to be pooled.
    95.     /// </param>
    96.     public void PoolObject ( GameObject obj )
    97.     {
    98.         for ( int i=0; i<objectPrefabs.Length; i++)
    99.         {
    100.             if(objectPrefabs[i].name == obj.name)
    101.             {
    102.                 obj.SetActiveRecursively(false);
    103.                 obj.transform.parent = containerObject.transform;
    104.                 pooledObjects[i].Add(obj);
    105.                 return;
    106.             }
    107.         }
    108.     }

    109. }
    复制代码

发表于 2017-2-27 15:02 | 显示全部楼层
很不错
发表于 2017-2-27 15:38 | 显示全部楼层
楼主是超人
发表于 2017-2-27 15:09 | 显示全部楼层
好帖就是要顶
发表于 2017-2-27 14:49 | 显示全部楼层
真心顶
发表于 2017-2-27 14:48 | 显示全部楼层
LZ真是人才
发表于 2017-3-10 16:29 | 显示全部楼层
很不错
发表于 2017-3-10 16:43 | 显示全部楼层
好帖就是要顶
发表于 2017-3-10 16:32 | 显示全部楼层
真心顶
发表于 2017-3-10 16:22 | 显示全部楼层
说的非常好
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-4 02:02 , Processed in 0.427505 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表