Unity程序优化之对象池

  对于做程序的朋友来说优化是一个避免不了的话题,对于程序的优化可以从两个方面来入手,一个是CPU方面的优化,一个是GPU的优化。对于CPU与GPU的作用简单理解的话你可以暂时当做CUP是处理计算的、GPU是处理渲染的,例如程序中的一些计算啊逻辑处理啊都是有CPU来处理的,,我们程序的显示啊,特效等一切看到的东西都是GPU来处理的。当然他们的关系不单单如此,扯远了哈,我们这篇博客主要讲CPU优化方面的对象池技术。对象池大家应该都听说过,它主要应用于处理需要大量重复利用的资源的,因为如果有很多资源如果我们需要重复利用的话,如果我们每次都是创建销毁创建销毁,是很耗计算机性能的,我们完全可以把不用的资源暂时禁用掉SetActive(false)而不是销毁,当我们需要再次使用时就把它激活重复利用。

  对象池的原理很简单,就是首先我们要创建一个池子,可以用字典也可以用栈,取决于你自己数据结构学的怎么样了,你觉得怎么高效怎么来,然后需要一个从池子里取东西的方法和一个回收东西到池子的方法,我们暂时不用的资源就可以通过回收的方法将其放到池子里暂时禁用,当我们再次需要利用时就将其从池子里取出来,重新激活使用就行了,一个简单的对象池脚本如下,这是一个单例脚本,我池子用的是字典结构,通过物品的名字来索引资源,使用时直接调用取资源的方法GetGameFromPool()和回收资源的方法RecycleToPool(GameObject gam)就好。

/***********************************
*    Description:对象池
*    Mountpoint:这是一个单例类,无需挂载
*    Date:2019.05.25
*    Version:版本
*    Author:LJF
***********************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace LJF
{
    //规范命名、合理封装、限制访问修饰符
    public class ObjectPool
    {
        //构造函数
        private ObjectPool()
        {
            pool = new Dictionary<string, List<GameObject>>();
            prefabs = new Dictionary<string, GameObject>();
        }
        //单例
        private static ObjectPool instance;
        //获取单例
        public static ObjectPool Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ObjectPool();
                }
                return instance;
            }
        }
        //对象池
        private Dictionary<string, List<GameObject>> pool;

        //预设体
        private Dictionary<string, GameObject> prefabs;

        /// <summary>
        /// 从池子中获取GameObject
        /// </summary>
        /// <param name="objectname">物体的路径(名字)</param>
        /// <returns></returns>
        public GameObject GetGameFromPool(string objectname)
        {
            GameObject g = null;
            if (pool.ContainsKey(objectname))
            {
                if (pool[objectname].Count > 0)
                {
                    g = pool[objectname][0];
                    g.SetActive(true);
                    pool[objectname].Remove(g);
                    return g;
                }
            }
            GameObject t = null;
            if (prefabs.ContainsKey(objectname))
            {
                t = prefabs[objectname];
            }
            else
            {
                //1,从Resources读取
                t = Resources.Load<GameObject>("Prefabs/" + objectname);
                //2,从AssetBundle读取
                //AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/AssetBundle/all.ab");//有文件生成资源包
                //t = ab.LoadAsset<GameObject>(objectname);
                prefabs.Add(objectname, t);
            }
            t = UnityEngine.Object.Instantiate(t);
            t.SetActive(true);
            t.name = objectname;
            return t;

        }
        /// <summary>
        /// 回收物体到池子中
        /// </summary>
        /// <param name="gam"></param>
        public void RecycleToPool(GameObject gam)
        {
            gam.SetActive(false);
            if (pool.ContainsKey(gam.name))
            {
                pool[gam.name].Add(gam);
            }
            else
            {
                pool.Add(gam.name, new List<GameObject>() { gam });
            }
        }
    }
}

原文地址:https://www.cnblogs.com/linkshow/p/12101162.html

时间: 2024-11-09 00:52:50

Unity程序优化之对象池的相关文章

Unity内存管理之对象池(Object Pool)

第一篇博客,打算和大家分享一下关于Unity开发当中用到的对象池,那么何为对象池呢? [对象池]:对象池是一种经常用到的内存管理服务,它的作用在于可以减少从头创建每个对象的系统开销. 众所周知,在Unity游戏开发的过程中经常会创建一些新的对象,如果数量较少还可以接受,如果创建的新对象数量庞大,那么对内存而言是一个极大的隐患.例如射击游戏当中,每发射一颗子弹,都要创建一个新的子弹对象,那么子弹是数量庞大,可想而知一场游戏当中会创建多少这样的新对象,那么如果这些子弹创建之后都对游戏起着关键且持续性

as3 性能之对象池技术

优化 Adobe® Flash® Platform 的性能:http://help.adobe.com/zh_CN/as3/mobile/index.html 为什么使用对象池? 因为FLASH是托管的GC清理资源,具体什么时候清理只有GC知道,那么我们的游戏的性能就......... 例如:游戏里点击按钮会加载一张图片,再次点击图片,会销毁图片. 那么如果用户不停的点击,会执行不断的加载 显示 销毁.内存就会很难控制. 摘自Adobe的一段 http://help.adobe.com/zh_C

Go36-33-临时对象池(sync.Pool)

临时对象池(sync.Pool) sync.Pool是Go语言标准库中的一个同步工具. 介绍 sync.Pool类型可以被称为临时对象池,它的值可以被用来存储临时的对象.它属于结构体类型,在它的值被真正使用之后,就应该再被复制了. 临时对象,就是不需要持久使用的某一类值.这类值对于程序来说可有可无,但如果有的话明显更好.它们的创建和销毁可以在任何时候发生,并且完全不会影响到程序功能.同时,它们也应该是无需被区分的,其中的任何一个值都可以代替另一个.如果某类值完全符合上述条件,就可以把它们存储到临

Unity 对象池的使用

在游戏开发过程中,我们经常会遇到游戏发布后,测试时玩着玩着明显的感觉到有卡顿现象.出现这种现象的有两个原因:一是游戏优化的不够好或者游戏逻辑本身设计的就有问题,二是手机硬件不行.好吧,对于作为程序员的我们只能从第一个原因着手了,那就开始对着Profiler看性能开销,接下来就开始做各种内存,特效,代码上的优化了.对于这种问题,有经验的开发者在一开始就会做一个规范的设计,就我们的项目而言,设计时包含了角色池,怪物池,特效池,经验池,伤害池......所谓的对象池就是尽可能的复用内存中已经驻留的资源

Unity中对象池的使用

unity中用到大量重复的物体,例如发射的子弹,可以引入对象池来管理,优化内存. 对象池使用的基本思路是: 将用过的对象保存起来,等下一次需要这种对象的时候,再拿出来重复使用.恰当地使用对象池,可以在一定程度上减少频繁创建对象所造成的开销. 并非所有对象都适合拿来池化――因为维护对象池也要造成一定开销.对生成时开销不大的对象进行池化,反而可能会出现“维护对象池的开销”大于“生成新对象的开销”,从而使性能降低的情况. GameObjectPool.cs如下 using UnityEngine; u

Unity ----- 对象池GameObjectPool

孙广东 2014.6.28 很早之前看到的外国文章,觉得不错,分享一下, 对象池在AssetStore中也是有很多插件的,但是有些重了,自己写一个轻量的岂不是很好. 当你需要创建大量某种类型对象时,它可以方便地重新使用单个对象,而不是不断地 创建/销毁(操作会导致大量的垃圾回收).此ObjectPool脚本,生成和回收您的游戏对象的对象池.代码:https://github.com/UnityPatterns/ObjectPoolhttp://unitypatterns.com/resource

GameObjectPool——Unity中的对象池

这里介绍一种对象池的写法.它的优点在于无论取出还是插入游戏物体都是常数量时间. using UnityEngine; using System.Collections; using System.Collections.Generic; //对象池 public class GameObjectPool : MonoSingleton<GameObjectPool> { /// <summary>可能存放多个种类的对象,每个种类有多个对象 </summary> priv

Unity对象池试水

其实接触对象池这个概念已经很久了,网上也有很多现成的插件,比较有名的是PoolManager,功能听说很完善,我并没有细看.现在我想根据网上的一些案例和教程写一个应用于现在这个项目的小ObjectPool,这里有一篇文章对ObjectPool有一定的解释,有兴趣的可以看看.我项目里面有几十个反复要使用的模型,就在这一块下手吧,主要来实现存取两块代码,为了便于检索采用List<T>来实现存取. using UnityEngine; using System.Collections; using

Unity内存优化

对项目优化有很多,如:mesh合并,减少DrawCall和模型骨骼以及物理计算,合并材质球,优化代码等等. 优化: 1. 更新不透明贴图的压缩格式为ETC 4bit,因为android市场的手机中的GPU有多种,每家的GPU支持不同的压缩格式,但他们都兼容ETC格式. 2.对于透明贴图,我们只能选择RGBA 16bit 或者RGBA 32bit. 3.减少FPS 在ProjectSetting-> Quality中的VSync Count 参数会影响你的FPS,EveryVBlank相当于FPS