Unity对象池的创建与使用


本文提供全流程,中文翻译。

Chinar 坚持将简单的生活方式,带给世人!

(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例)


Chinar —— 心分享、心创新!

助力快速完成 Unity 对象池的创建与使用

为新手节省宝贵的时间,避免采坑!

Chinar 教程效果:



全文高清图片,点击即可放大观看 (很多人竟然不知道)


1

MonoSingleton —— 单例基类

任何继承自 MonoSingleton 泛型基类的脚本/类 都是单例类

using UnityEngine;

/// <summary>
/// 泛型单例基类 —— 任何继承自该类的类,都是单例类
/// </summary>
/// <typeparam name="T">泛型</typeparam>
public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
private static T instance;
public static T Instance
{
get
{
if (instance == null)
{
instance = FindObjectOfType(typeof(T)) as T;
if (instance == null) instance = new GameObject("Chinar Single of " + typeof(T).ToString(), typeof(T)).GetComponent<T>();
} return instance;
}
} private void Awake()
{
if (instance == null) instance = this as T;
} private void OnApplicationQuit()
{
instance = null;
}
}

2

ObjectPool —— 对象池

新建一个脚本 ObjectPool 继承自泛型基类 MonoSingleton《ObjectPool》

是以 ObjectPool 就会是一个单例类

using System.Collections;
using System.Collections.Generic;
using UnityEngine; /// <summary>
/// 对象池(重复调用/使用的游戏物体) 子弹,技能,导弹,敌人
/// </summary>
public class ObjectPool : MonoSingleton<ObjectPool>
{
//字段 池 技能预设物(因为一个技能可能有多个预制件) 技能的复用性
private Dictionary<string, List<GameObject>> cache = new Dictionary<string, List<GameObject>>();
int i = 0; //标记 0 /// <summary>
/// 创建显示对象
/// </summary>
/// <returns>The object.</returns>
/// <param name="key">对象名称</param>
/// <param name="go">对象的预制件</param>
/// <param name="position">对象的新位置</param>
/// <param name="quaternion">对象的角度</param>
public GameObject CreateObject(string key, GameObject go, Vector3 position, Quaternion quaternion)
{
GameObject tempgo = cache.ContainsKey(key) ? cache[key].Find(p => !p.activeSelf) : null; //返回池中未激活的对象,所有都被激活就返回空,赋值给临时对象
if (tempgo != null) //如果临时对象不为空
{
tempgo.transform.position = position; //设置位置
tempgo.transform.rotation = quaternion; //旋转信息
}
else //否则,就是空了。(也就是没能从池子里取出对象)
{
tempgo = Instantiate(go, position, quaternion); //那就根据传入的预设物,生成一个新物体
print("实例化物体数量:" + i++);
if (!cache.ContainsKey(key)) //池中没有键
{
cache.Add(key, new List<GameObject>()); //新建一个 列表
} cache[key].Add(tempgo); //给字典中的列表加入/add 临时物体,如果有键就直接添加了
} tempgo.SetActive(true); //并启用临时物体
return tempgo; //返回
} /// <summary>
/// 直接回收
/// </summary>
/// <param name="go">Go.</param>
public void CollectObject(GameObject go)
{
go.SetActive(false);
} /// <summary>
/// 延迟回收
/// </summary>
/// <param name="go">Go.</param>
/// <param name="delay">Delay.</param>
public void CollectObject(GameObject go, float delay)
{
StartCoroutine(Collect(go, delay));
} private IEnumerator Collect(GameObject go, float delay)
{
yield return new WaitForSeconds(delay);
CollectObject(go);
} /// <summary>
/// 释放资源
/// </summary>
/// <returns>The clear.</returns>
/// <param name="key">Key.</param>
public void Clear(string key)
{
if (cache.ContainsKey(key))
{
//Destroy当中所有的对象
for (int i = 0; i < cache[key].Count; i++)
{
Destroy(cache[key][i]);
} //清除键当中的所有值
//cache[key].Clear();
//清除这个键(键值一起清除)
cache.Remove(key);
}
} /// <summary>
/// 释放所有对象池
/// </summary>
public void ClearAll()
{
var list = new List<string>(cache.Keys);
for (int i = 0; i < list.Count; i++)
{
Clear(list[i]);
}
}
}

3

PoolTest —— 测试对象池的使用

新建一个脚本 PoolTest 用来测试对象池的使用

using UnityEngine;

/// <summary>
/// 测试对象池的调用
/// </summary>
public class PoolTest : MonoBehaviour
{
GameObject go; //临时对象
GameObject item; //临时对象池对象 void Start()
{
go = Resources.Load<GameObject>("Cube"); //在Resources文件目录下做一个Cube预设物
} void Update()
{
if (Input.GetKey(KeyCode.Space)) //按下空格创建一个Cube
{
item = ObjectPool.Instance.CreateObject("Object1", go, Vector3.zero, new Quaternion(0, 0, 0, 0));
item.transform.position += new Vector3(0, 0, 1);
} if (Input.GetMouseButtonDown(0)) //按下左键执行回收对象
{
if (item != null)
{
ObjectPool.Instance.CollectObject(item, 0.2f);
}
} if (Input.GetMouseButtonDown(1)) //按下右键执行清除已经生成的对象
{
ObjectPool.Instance.Clear("Object1");
}
}
}

支持

May Be —— 搞开发,总有一天要做的事!

拥有自己的服务器,无需再找攻略!

Chinar 提供一站式教程,闭眼式创建!

为新手节省宝贵时间,避免采坑!

先点击领取 —— 阿里全产品优惠券 (享受最低优惠)



1 —— 云服务器超全购买流程 (新手必备!)



2 —— 阿里ECS云服务器自定义配置 - 购买教程(新手必备!)



3—— Windows 服务器配置、运行、建站一条龙 !



4 —— Linux 服务器配置、运行、建站一条龙 !




" role="presentation">

Chinar


END

本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究


对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com


对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址

unity中实现简单对象池,附教程原理的更多相关文章

  1. Unity编程标准导引-3.4 Unity中的对象池

    本文为博主原创文章,欢迎转载.请保留博主链接http://blog.csdn.net/andrewfan Unity编程标准导引-3.4 Unity中的对象池 本节通过一个简单的射击子弹的示例来介绍T ...

  2. Unity中的 原生插件/平台交互 原理

    http://blog.csdn.net/u010019717/article/details/78451660 声明:  内容摘录自:  http://gad.qq.com/article/deta ...

  3. GameObjectPool——Unity中的对象池

    这里介绍一种对象池的写法.它的优点在于无论取出还是插入游戏物体都是常数量时间. using UnityEngine; using System.Collections; using System.Co ...

  4. Unity中的万能对象池

    本文为博主原创文章,欢迎转载.请保留博主链接http://blog.csdn.net/andrewfan Unity编程标准导引-3.4 Unity中的万能对象池 本节通过一个简单的射击子弹的示例来介 ...

  5. 对象池----unity中应用

    对象池应用在unity中能减少资源消耗,节省内存空间具体原理不再赘述. 以下是他的操作步骤:(注意:对象池中应用到了栈或对队列!) 1).先建立一个(怪物)物体   mMonster; 2).再建立一 ...

  6. Java并发编程(您不知道的线程池操作), 最受欢迎的 8 位 Java 大师,Java并发包中的同步队列SynchronousQueue实现原理

    Java_并发编程培训 java并发程序设计教程 JUC Exchanger 一.概述 Exchanger 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchan ...

  7. Unity教程之再谈Unity中的优化技术

    这是从 Unity教程之再谈Unity中的优化技术 这篇文章里提取出来的一部分,这篇文章让我学到了挺多可能我应该知道却还没知道的知识,写的挺好的 优化几何体   这一步主要是为了针对性能瓶颈中的”顶点 ...

  8. 骨骼动画的原理及在Unity中的使用

    制作骨骼动画 我们看看这几步操作后,我们得到了那些数据: 1.每个皮肤顶点的初始世界坐标. 2.每个骨骼关节顶点的初始世界坐标. 3.每个顶点被骨骼顶点的影响信息. 4.骨骼如何移动. 骨骼动画原理 ...

  9. 【Unity3D基础教程】给初学者看的Unity教程(七):在Unity中构建健壮的单例模式(Singleton)

    作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点推荐.谢谢! 该博客中的代码均出自我的开源项目 : 迷你微信 ...

随机推荐

  1. 把旧系统迁移到.Net Core 2.0 日记(1) - Startup.cs 解析

    因为自己到开发电脑转到Mac Air,之前的Webform/MVC应用在Mac 跑不起来,而且.Net Core 2.0 已经比较稳定了. 1. 为什么会有跨平台的.Net Core  近年来,我们已 ...

  2. C#调用接口返回json数据中含有双引号 或其他非法字符的解决办法

    这几天,调用别人接口返回json数据含有特殊符号(双引号),当转换成json对象总是报错, json字符格式如下 { "BOXINFO":[ { ", "ITE ...

  3. map的key 为指针

    STL中map的key能否用char *呢?当然可以! 在程序中需要用到一个map,本来是这样写的,map<string, int> mapStr; 为了追求效率,把string改成了ch ...

  4. angular 路由项目例子

    angular 路由是我在工作中体验非常便捷的一点, 这是详细的API ,查看API 可以了解很多东西, https://github.com/angular-ui/ui-router/wiki/Qu ...

  5. 一个非常适合IT团队的在线API文档、技术文档工具 (ShowDoc)

    在逸橙呆了不到两年,开发时后端都有开发接口API,来到数库,好多后端开发和前端沟通是还是发doc文档,很不方便,我向cto反应,自己找到这个,老乡田雷(php,隔壁村的)也用过,可能某些原因选择其他的 ...

  6. MySQL 占用cpu 100%

    目前的线上数据库,分为主从两个库,从库用来做比较耗时的数据统计分析. 今天top了一下从库服务器,发现mysqld 在很长一段时间都占用105% cpu,一开始以为是从库在处理主库的binlog. 两 ...

  7. 图的邻接矩阵存储实现,C++描述

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  8. 数据库编程测试机试 QQ

    创建QQ数据库 #创建数据库 CREATE DATABASE QQ #创建表名 并且添加列 DROP TABLE IF EXISTS `dbo.BaseInfo`; CREATE TABLE `stu ...

  9. json解析写入mysql

    import json,requests,pymysql from pprint import pprint from datetime import datetime dt=datetime.now ...

  10. MicroOrm.Dapper.Repositories 的使用

    https://github.com/geffzhang/MicroOrm.Dapper.Repositories 1.特性标记都是要引用: System.ComponentModel.DataAnn ...