Unity3D通过对象池模式 管理场景中的元素
来源:互联网 发布:python实现支付宝登录 编辑:程序博客网 时间:2024/04/28 15:01
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class ObjPoolMgr : MonoBehaviour
{
#region 公共属性
/// <summary>
/// 池中所使用的元素Prefab
/// </summary>
public GameObject ObjPrefab;
/// <summary>
/// 初始容量
/// </summary>
public int InitialCapacity;
#endregion
#region 私有属性
/// <summary>
/// 初始下标
/// </summary>
private int _startCapacityIndex;
/// <summary>
/// 可用下标
/// </summary>
private List<int> _avaliableIndex;
/// <summary>
/// 池中全部元素
/// </summary>
private Dictionary<int, GameObject> _totalObjList;
#endregion
#region 事件/重写方法
void Start()
{
_avaliableIndex = new List<int>(InitialCapacity);
_totalObjList = new Dictionary<int, GameObject>(InitialCapacity);
ExpandPool();
}
#endregion
#region 公共方法
/// <summary>
/// 取得一个物体,返回值 1,obj代表,ID是1的物体被取到,ID可以用来归还物体的时候用到
/// </summary>
/// <returns></returns>
public KeyValuePair<int, GameObject> PickObj()
{
if (_avaliableIndex.Count == 0)
ExpandPool();
int id = _avaliableIndex[0];
_avaliableIndex.Remove(id);
_totalObjList[id].SetActive(true);
return new KeyValuePair<int, GameObject>(id, _totalObjList[id]);
}
/// <summary>
/// 回收一个物体
/// </summary>
/// <param name="id"></param>
public void RecyleObj(int id)
{
_totalObjList[id].SetActive(false);
_totalObjList[id].transform.parent = transform;
_avaliableIndex.Add(id);
}
#endregion
//放回池中的时候,我们把元素的父节点也设置为池元素,这样做是避免当元素挂载的对象在内存中被删除的时候,元素也被删除的问题。
#region 私有方法
/// <summary>
/// 扩展池
/// </summary>
private void ExpandPool()
{
int start = _startCapacityIndex;
int end = _startCapacityIndex + InitialCapacity;
for (int i = start; i < end; i++)
{
//加入验证判断,避免在极端情况下
//(1:两次申请同时发起 2:第二次申请的时候,第一次还没有扩展任何元素)时
//,往字典添加相同的主键,导致游戏报错闪退的问题
if (_totalObjList.ContainsKey(i))
continue;
GameObject newObj = Instantiate(ObjPrefab) as GameObject;
newObj.SetActive(false);
_avaliableIndex.Add(i);
_totalObjList.Add(i, newObj);
}
_startCapacityIndex = end;
}
#endregion
}
//在游戏场景中,我们有时候会需要复用一些游戏物体,比如常见的子弹、子弹碰撞类,某些情况下,怪物也可以使用池管理,UI部分比如:血条、文字等等
//这些元素共同的特性是:存在固定生命周期,使用比较频繁,场景中大量使用。
//所以,我们就通过池管理思路,在游戏初始化的时候,生成一个初始的池,存放我们要复用的元素,
//当要用到时,从池中取出;生命周期结束,放回到池中。
//代码
//这个池的参数有两个:1池中存放的元素 2 池的初始容量(如果池不够了,则会按照这个容量进行扩展)
//声明方式:
//ObjectPoolManager _bulletPool = GameObject.Find("你挂载的物体名称").GetComponent<ObjectPoolManager>();
//取出元素:
//KeyValuePair<int, GameObject> bulletKV = _bulletPool.PickObj();
//放回:
//_bulletPool.RecyleObj(bulletID);
//适用
//子弹 子弹碰撞特效 攻击特效 被攻击特效 怪物血条(基于NGUI制作) 场景部分文字(施法时、怪物被攻击时,基于NGUI制作) 等等
using System.Collections;
using System.Collections.Generic;
public class ObjPoolMgr : MonoBehaviour
{
#region 公共属性
/// <summary>
/// 池中所使用的元素Prefab
/// </summary>
public GameObject ObjPrefab;
/// <summary>
/// 初始容量
/// </summary>
public int InitialCapacity;
#endregion
#region 私有属性
/// <summary>
/// 初始下标
/// </summary>
private int _startCapacityIndex;
/// <summary>
/// 可用下标
/// </summary>
private List<int> _avaliableIndex;
/// <summary>
/// 池中全部元素
/// </summary>
private Dictionary<int, GameObject> _totalObjList;
#endregion
#region 事件/重写方法
void Start()
{
_avaliableIndex = new List<int>(InitialCapacity);
_totalObjList = new Dictionary<int, GameObject>(InitialCapacity);
ExpandPool();
}
#endregion
#region 公共方法
/// <summary>
/// 取得一个物体,返回值 1,obj代表,ID是1的物体被取到,ID可以用来归还物体的时候用到
/// </summary>
/// <returns></returns>
public KeyValuePair<int, GameObject> PickObj()
{
if (_avaliableIndex.Count == 0)
ExpandPool();
int id = _avaliableIndex[0];
_avaliableIndex.Remove(id);
_totalObjList[id].SetActive(true);
return new KeyValuePair<int, GameObject>(id, _totalObjList[id]);
}
/// <summary>
/// 回收一个物体
/// </summary>
/// <param name="id"></param>
public void RecyleObj(int id)
{
_totalObjList[id].SetActive(false);
_totalObjList[id].transform.parent = transform;
_avaliableIndex.Add(id);
}
#endregion
//放回池中的时候,我们把元素的父节点也设置为池元素,这样做是避免当元素挂载的对象在内存中被删除的时候,元素也被删除的问题。
#region 私有方法
/// <summary>
/// 扩展池
/// </summary>
private void ExpandPool()
{
int start = _startCapacityIndex;
int end = _startCapacityIndex + InitialCapacity;
for (int i = start; i < end; i++)
{
//加入验证判断,避免在极端情况下
//(1:两次申请同时发起 2:第二次申请的时候,第一次还没有扩展任何元素)时
//,往字典添加相同的主键,导致游戏报错闪退的问题
if (_totalObjList.ContainsKey(i))
continue;
GameObject newObj = Instantiate(ObjPrefab) as GameObject;
newObj.SetActive(false);
_avaliableIndex.Add(i);
_totalObjList.Add(i, newObj);
}
_startCapacityIndex = end;
}
#endregion
}
//在游戏场景中,我们有时候会需要复用一些游戏物体,比如常见的子弹、子弹碰撞类,某些情况下,怪物也可以使用池管理,UI部分比如:血条、文字等等
//这些元素共同的特性是:存在固定生命周期,使用比较频繁,场景中大量使用。
//所以,我们就通过池管理思路,在游戏初始化的时候,生成一个初始的池,存放我们要复用的元素,
//当要用到时,从池中取出;生命周期结束,放回到池中。
//代码
//这个池的参数有两个:1池中存放的元素 2 池的初始容量(如果池不够了,则会按照这个容量进行扩展)
//声明方式:
//ObjectPoolManager _bulletPool = GameObject.Find("你挂载的物体名称").GetComponent<ObjectPoolManager>();
//取出元素:
//KeyValuePair<int, GameObject> bulletKV = _bulletPool.PickObj();
//放回:
//_bulletPool.RecyleObj(bulletID);
//适用
//子弹 子弹碰撞特效 攻击特效 被攻击特效 怪物血条(基于NGUI制作) 场景部分文字(施法时、怪物被攻击时,基于NGUI制作) 等等
0 0
- 《Unity3D》通过对象池模式,管理场景中的元素
- Unity3D通过对象池模式 管理场景中的元素
- unity3d 切换场景不销毁对象池中的物体方案
- Unity3D 场景管理单例模式
- Unity3D 删除场景中的实例对象
- [Unity3d]场景管理插件-SceneManager
- Unity3D 中的地形元素
- Unity3D内存管理——对象池
- Unity3D——对象管理缓冲池
- unityios开发----触屏选中Unity3D场景中的GameObject对象代码
- Unity3D场景管理插件Scene Manager
- Unity3D 11-SceneManager场景管理用法总结
- unity3d 异步加载场景和游戏对象
- Maya中的场景与Unity3D中的场景匹配
- 元素对象管理
- 在Unity内通过对象池管理游戏物体与单例模式
- 遍历聚合对象中的元素——迭代器模式
- 遍历聚合对象中的元素——迭代器模式
- Java基础——集合Collection
- POJ 2752 Seek the Name, Seek the Fame(KMP)
- eclipse导入java和android sdk源码,帮助文档
- uboot移植之配置分析
- COM--类厂
- Unity3D通过对象池模式 管理场景中的元素
- Swift(十二、方法&下标脚本)
- 【分享】魔王的地下要塞1+2(デモニオン)【日文硬盘版】(带全CG存档+打开存档+1.03升级+SSG补丁)
- 快速开发平台为树型部件添加图标
- GFS、HDFS等分布式文件系统对比介绍
- Android Studio插件-Android Butterknife Zelezny
- Mapreduce不设置reduce,只执行map的输出结果
- 文件下载 Servlet实现
- makefile老是报“recipe for target xxx”错误,不妨先看看编码是否正确