对象池实操(二)_对一的演示的补充_实现对象的数据重置
来源:互联网 发布:反ps软件叫什么 编辑:程序博客网 时间:2024/06/05 09:50
对象池实操(二)_对一的演示的补充_实现对象的数据重置<15/10/2017>
先看效果,主要是实现了一个重置的过程:
一共四个脚本,一个是池管理PoolManager,一个是测试管理TestManager,一个是池对象PoolObject,一个是测试对象TestObject:
PoolManager脚本:
using System.Collections;using System.Collections.Generic;using UnityEngine;public class PoolManager : MonoBehaviour{ Dictionary<int, Queue<ObjectInstance>> poolDictionary = new Dictionary<int, Queue<ObjectInstance>>();//键名不存在顺序之分 static PoolManager _instance; public static PoolManager instance { get { if (_instance == null) { _instance = FindObjectOfType<PoolManager>();//找到身上挂有PoolManager脚本的物体类型(单例模式) } return _instance; } } public void CreatePool(GameObject prefab, int poolSize) { int poolKey = prefab.GetInstanceID();//***物体的实例id始终保证是独一无二的*** GameObject poolHolder = new GameObject(prefab.name + "pool");//把所有预制体同一进行管理,避免杂乱 poolHolder.transform.parent = transform;//把这个用来分类管理的空父物体的父类都定义为PoolManager,以至于不那么杂乱 if (!poolDictionary.ContainsKey(poolKey))//检查有没有唯一ID,没有就增加 { poolDictionary.Add(poolKey, new Queue<ObjectInstance>()); } for (int i = 0; i < poolSize; i++)//产生对应的对象后,不激活对象,且用队列的形式放到字典Dictionary中 { ObjectInstance newObject = new ObjectInstance(Instantiate(prefab) as GameObject); poolDictionary[poolKey].Enqueue(newObject);//入列存字典Dictionary中 newObject.SetParent(poolHolder.transform); } } public void ReuseObject(GameObject prefab, Vector3 position, Quaternion rotation) { int poolKey = prefab.GetInstanceID(); if (poolDictionary.ContainsKey(poolKey))//对象的重用,先找有没有这个对象,找到后出列用新的引用指针调用,然后再入列,很有调用逻辑,每次都是按顺序使用 { ObjectInstance objectToReuse = poolDictionary[poolKey].Dequeue();//创造一个空的对象来引用指向在字典中的它,踢出队列最前排 poolDictionary[poolKey].Enqueue(objectToReuse);//回到队列最后排 objectToReuse.Reuse(position, rotation);//调用类的方法来实现调用的方法 } } public class ObjectInstance//定义一个类来存储对象信息,使得其重置对象的所有数据参数,使得其每次调用都是全新的开始 { GameObject gameObject; Transform transform; bool hasPoolObjectComponent;//判断对象是否拥有PoolObjecet组件(TestObject继承于PoolObject),然后进行判断 PoolObject poolObjectScript; public ObjectInstance(GameObject objectInstance)//构造方法 { gameObject = objectInstance; transform = gameObject.transform; gameObject.SetActive(false);//开始时默认都是不激活的状态 if (gameObject.GetComponent<PoolObject>())//TestObject继承于PoolObject,每个预制体身上都有个TestObject { hasPoolObjectComponent = true; poolObjectScript = gameObject.GetComponent<PoolObject>();//复用重置 } } public void Reuse(Vector3 position, Quaternion rotation) { if (hasPoolObjectComponent)//用于重置对象属性的判断 { poolObjectScript.OnObjectReuse();//TestObject等同于PoolObject } gameObject.SetActive(true); transform.position = position; transform.rotation = rotation; } public void SetParent(Transform parent)//归类管理,避免杂乱 { transform.parent = parent; } }}TestManager脚本:
using System.Collections;using System.Collections.Generic;using UnityEngine;public class TestManager : MonoBehaviour{ public GameObject prefab; void Start() { PoolManager.instance.CreatePool(prefab, 3); } void Update() { if (Input.GetKeyDown(KeyCode.Space)) { PoolManager.instance.ReuseObject(prefab, Vector3.zero, Quaternion.identity); } }}
PoolObject脚本:
using System.Collections;using System.Collections.Generic;using UnityEngine;public class PoolObject : MonoBehaviour{ public virtual void OnObjectReuse() { } protected void OnDestroy() { gameObject.SetActive(false);//用false不激活设置代替该对象被删除 }}TestObject脚本:(继承于PoolObject)
using System.Collections;using System.Collections.Generic;using UnityEngine;public class TestObject : PoolObject{ TrailRenderer trail; float trailTime; private void Awake() { trail = GetComponent<TrailRenderer>();//拿到自身的拖尾组件,好吧这个不重要可以忽略 trailTime = trail.time; } void Update() { transform.localScale += Vector3.one * Time.deltaTime;//预制体体积不断增大 transform.Translate(Vector3.left * Time.deltaTime * 5);//预制体诞生后持续朝一个方向移动 } public override void OnObjectReuse()//每次使用复用对象时,都会重置对象的各类属性值,使得其复用回到初始状态,而不是调用变化后的效果 { trail.time = -1; Invoke("ResetTrail", .1f);//0.1秒后激活拖尾效果 transform.localScale = Vector3.one;//重置对象的体积 } void ResetTrail() { trail.time = trailTime; }}
运行前和运行时的层级视图:
运行前运行时
最终效果(主要是重置):
阅读全文
1 0
- 对象池实操(二)_对一的演示的补充_实现对象的数据重置
- 面向对象_一、二、三个对象的内存图
- 黑马程序员_关于对象的知识点补充
- 对象~时间篇_日历的实现
- 对象池实操(一)_发射子弹简单演示
- 对《原子对象模式》一文的补充
- C++笔记_类和对象_类的定义_数据成员与成员函数
- 0012_对象的多态性
- PHP面向对象_对象的遍历
- 04_HttpServletResponse_响应对象的产生_响应数据
- Python学习_面向对象(OOP)一:类的实现机制
- C++笔记_类和对象_类的定义_类和对象
- 黑马程序员_对象的简单分析_对象与函数参数_常见错误
- [ATL/WTL]_[初级]_[常用的界面对象操作]
- C++_类_对象的生存周期
- 面向对象_静态的应用_工具类
- 39_面向对象_12_继承_方法的重写
- [并发并行]_[初级]_[C++实现sychronized方式的对象锁]
- TEZ 0.8.5与Hadoop2.7.3的guava兼容性问题
- [BZOJ2186][SDOI2008]沙拉公主的困惑(数论)
- git命令使用
- CentOS升级Python2.6到Python2.7并安装pip
- 树形结构的查找(平衡二叉树--插入时调整)
- 对象池实操(二)_对一的演示的补充_实现对象的数据重置
- 关于struts三种action后台接收参数的方法
- http状态码详解
- POJ 1363 (栈的)
- SpringMVC源码剖析(一)- 从抽象和接口说起
- php-redis扩展
- 基于Dragonboard 410c的总线控制之SPI(二)
- ProjectForge研究第一天
- poj 1861 Network(并查集)