unity对象池系统

2023-11-12

当游戏场景中出现大量的可重复利用的物体时,通过Destory来销毁再创建会触发不必要的GC回收机制,浪费性能,我们可以利用unity自带的对象池系统,从而节约性能来得到同样的效果。

为了使用这个对象池系统,我写了一个瞬间产生多枚子弹的测试脚本如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UnlimitedSwordSystem : MonoBehaviour
{
     public GameObject projiectilePrefab;

     public Rigidbody2D rigidbody2d;

     private int projectileNum=20;

     private Vector2 CreatPosition;

     GameObject projectile;
   
    private Coroutine launch3times;

    
    public void CreatProjectiles()
    {
        if(transform.GetComponent<SkillTrigger>().available==false)return;
        if(launch3times!=null)
        {
            StopCoroutine(launch3times);
        }
        launch3times=StartCoroutine("CreatProjectile");   
    }

    private IEnumerator CreatProjectile()
    {
        int k=2;
        while(k>=0)
        {
            k--;
            for(int i=0;i<projectileNum;i++)
        {
            CreatPosition=Random.insideUnitCircle*1.5f;

            projectile = Instantiate(projiectilePrefab, 
            CreatPosition+rigidbody2d.position,
            Quaternion.identity);
        
            launch(CreatPosition);
        }     
            yield return new WaitForSeconds(0.3f);
        }
    }

    
    void launch(Vector2 p)
    {
        projectile.GetComponent<Projectile>().Launch(p.normalized,500);
    }
}

这个脚本可以在瞬间分三次产生共60枚子弹,运行游戏,打开Profiler,可以看到GC Allocated In Frame有明显波动

 接下来使用对象池来优化

创建一个脚本pool,使用unity的对象池需引入UnityEngine.Pool;

从对象池中取出和放入对应着Get和Release这两个函数:

 

为了实现对象池,必须修改一下子弹的脚本,让子弹停留2秒后回收入对象池而非摧毁

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Projectile : MonoBehaviour
{
    System.Action<Projectile>dea;
    public void SetDea(System.Action<Projectile> dea)
    {
        this.dea=dea;
    }
    private Rigidbody2D rigidbody2d;
    public int DamageValue=1;

    void Awake()    //在Start之前调用
    {
        rigidbody2d = GetComponent<Rigidbody2D>();
    }

    public void Launch(Vector2 direction,float force)
    {
        rigidbody2d.AddForce(direction*force);
    }


    float lifeTime=2;
    bool IsActive=true;
    private void Update()
    {
        // if (transform.position.magnitude > 250f)
        // {
        //     Destroy(gameObject);
        // }
        if(!IsActive)return;
        
        lifeTime-=Time.deltaTime;
        if(lifeTime<=0)
        {
            lifeTime=2;
            dea.Invoke(this);

        }
    }

创建对象池所需的参数:

 createFunc:

创建一个对象,值得注意的是当Get不能得到一个对像时,会调用这个方法创建对象。

actionOnGet:

调出对象池对象时要执行的功能

actionOnRelease:

回收对象到对象池时要执行的功能

actionOnDestroy:

摧毁对象池中对象要执行的操作

collectionCheck:

是否开启回收检测功能

defaultCapacity:

对象池的默认容量,和链表或队列类似,当容量不足时会自动扩容。

maxSize:

限制对象池的最大容量,防止对象池的无限扩张,如果maxSize已满,当调用Release函数时,这个Release函数将会忽略。

对象池:

public class Pool : MonoBehaviour
{
    [SerializeField] Projectile prefab;
    [SerializeField] int defaultSize=100;
    [SerializeField] int maxSize=500;
    ObjectPool<Projectile>pool;

    [SerializeField] Rigidbody2D rigidbody2d;
    private void Awake() {
        pool=new ObjectPool<Projectile>(OnCreatPoolItem,OnGetPoolItem,OnReleasePoolItem,
        OnDestoryPoolItem,true,defaultSize,maxSize);
    }

    private void Update() {
        var p=pool.Get();
        p.transform.position=rigidbody2d.position+ Random.insideUnitCircle*2.5f;
    }

    private void OnDestoryPoolItem(Projectile projectile)
    {
        Destroy(projectile.gameObject);
    }

    private void OnReleasePoolItem(Projectile projectile)
    {
        projectile.gameObject.SetActive(false);
    }

    private void OnGetPoolItem(Projectile projectile)
    {
        projectile.gameObject.SetActive(true);
    }

    private Projectile OnCreatPoolItem()
    {
        var projectile=Instantiate(prefab,transform);
        projectile.SetDea(delegate{pool.Release(projectile);});

        return projectile;
    }
}

运行游戏可以看到,GC Allocated In Frame在对象池稳定运行后为0

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

unity对象池系统 的相关文章

  • c#获取cpu序列号

  • Unity中级客户端开发工程师的进阶之路

    上期UWA技能成长系统之 Unity高级客户端开发工程师的进阶之路 得到了很多Unity开发者的肯定 通过系统的学习 可以掌握游戏性能瓶颈定位的方法和常见的CPU GPU 内存相关的性能优化方法 UWA技能成长系统是UWA根据学员的职业发展
  • Unity动画控制器animator.CrossFade

    需要特别注意 1 CrossFade虽然可以不用任何逻辑来链接而直接跳转 但是CrossFade只能覆盖其他动画 当当前动画播放完毕而没有跳出这个动画时再次调用CrossFade将会失败 造成动画依旧停在原位 参数animator Cros
  • Unity中实现倒计时的几种方式

    1 Time time using UnityEngine public class TimeTest MonoBehaviour public float secound 10 void Update Timing private flo
  • Unity中UI框架的使用1-添加面板、显示Loading页面

    其中BasePanel和Canvas都是挂在面板的预制物上的 1 导入我们的UI框架 本篇文章中有用的是两个UIPanelType NUIManager和NBasePanel 会放在文章最后供大家使用 2 先将我们做好的Panel设置成预制
  • Unity之获取游戏物体对象或组件的几个方法

    文章目录 前言 通过物体名称获取对象 GameObject Find Transform Find 通过物体标签获取对象 GameObject FindWithTag GameObject FindGameObjectWithTag Gam
  • 【IMGUI】 各种辅助类 EditorGUIUtility、EditorUtility、GUIUtility、GUILayoutUtility

    EditorGUIUtility class in Editor 继承自 GUIUtility EditorGUI 的各种辅助程序 EditorGUIUtility currentViewWidth 我尝试打印了下这个值和position
  • unity: C#的Action Event Delegate的异同

    目录 一 Action 二 Event 三 Action和Event区别 四 Delegate 总结 Action Event Delegate的异同 前言 Action Event和Delegate都是C 语言中的重要概念 分别用于管理函
  • unity实现鼠标右键控制视角

    主要实现的功能是相机跟随主角 鼠标右击移动后 相机的视角会旋转 思路 在主角里创建空的子物体 把相机绑在空物体上 通过旋转空物体来实现视角的旋转 要把相机调整到适当位置 代码如下 public float rotateSpeed 100 设
  • Unity万向节死锁解决方案(2023/12/4)

    1 万向节死锁无法解决 这是因为它的特性就是如此 就像玻璃杯就是玻璃 这不可否认 别钻牛角尖昂 2 大多数情况下欧拉角足够用 例如 CF 摄像机不可能绕z轴旋转 x轴旋转也不会超过九十度 因为那样人物的腰子会被扭断 塔防游戏 保卫萝卜 吃鸡
  • unity3d image组件不显示

    需要将UI组件放到画布下面
  • mixamo根动画导入UE5问题:滑铲

    最近想做一个跑酷游戏 从mixamo下载滑铲动作后 出了很多动画的问题 花了两周时间 终于是把所有的问题基本上都解决了 常见问题 1 动画序列 人物不移动 2 动画序列 人物移动朝向错误 3 蒙太奇 人物移动后会被拉回 4 蒙太奇 动画移动
  • unity小球跟随音乐节奏放大缩小和改变颜色

    放在小球身上 设置对应组件即可 using System Collections using System Collections Generic using Unity VisualScripting using UnityEngine
  • 【转载】【Unity】WebSocket通信

    1 前言 Unity客户端常用的与服务器通信的方式有socket http webSocket 本文主要实现一个简单的WebSocket通信案例 包含客户端 服务器 实现了两端的通信以及客户端向服务器发送关闭连接请求的功能 实现上没有使用U
  • VS2022 | 显示Unreal Engine日志

    VS2022 显示Unreal Engine日志 视图 gt 其他窗口 gt Unreal Engine日志 视图 gt 其他窗口 gt Unreal Engine日志
  • U3D游戏开发中摇杆的制作(UGUI版)

    在PC端模拟摇杆 实现玩家通过控制摇杆让玩家移动 以下是完整代码 using System Collections using System Collections Generic using UnityEngine using Unity
  • U3D游戏开发中摇杆的制作(NGUI版)

    在PC端模拟摇杆 实现控制摇杆让玩家或者物体移动 以下是完整代码 using System Collections using System Collections Generic using UnityEngine public clas
  • 游戏开发常见操作梳理之NPC任务系统

    多数游戏存在任务系统 接下来介绍通过NPC触发任务的游戏制作代码 using System Collections using System Collections Generic using UnityEngine
  • 游戏开发常用实践操作之按动任意键触发

    接下来一些笔记会对于一些大大小小的实践操作进行记录 希望对你有所帮助 在游戏中 我们经常会遇到一些按动任意键触发的操作 接下来展示核心代码 以下是对于Unity中的操作 使用的UI是NGUI 对于核心操作没有影响 你可以自己置换 void
  • 游戏开发常见操作系列之敌人系统的开发一(U3D)

    在开发游戏的过程中 我们常常会出现一些敌人攻击我们玩家 并且实现掉血以及死亡的现象 敌人还会源源不断地生成 这是怎么制作的呢 接下来为大家提供方法 其中使用了NGUI 后续会更新其它方法 敬请期待 使用HUDText实现扣血时显示文本 直接

随机推荐

  • 螺旋矩阵的实现

    螺旋矩阵就是形如如下图的矩阵 看到矩阵知道它由四条边组成 这样的话就有这样的n 2个环 但是如果是奇数矩阵的话在最中间需要特殊处理一下 代码如下 include
  • 攻防世界之Web新手练习篇

    前言 天行健 君子以自强不息 地势坤 君子以厚德载物 周易 第一次接触CTF比较晚 学期已过近半 第一次做题就是在攻防世界 这里题目适合刚接触的萌新 写此篇博客 以为纪念 首页 目录 View source robots backup co
  • CentOS 初体验三: Yum 安装、卸载软件

    转载请标明出处 http blog csdn net zhaoyanjun6 article details 78894974 本文出自 赵彦军的博客 一 Yum 简介 Yum 全称为 Yellow dog Updater Modified
  • Unity3D服务器端使用PhysX计算物理

    本文的最终目的 当设计师在Unity3D中制作好游戏场景后 为Gameobject拖好Collider 通过我们写的工具导出这份场景的Collider配置 在服务器端能够生成一份一模一样的物理世界 从而由权威服务器去计算物理 诸如子弹有没有
  • FM/AM收音机原理

    收音机这东西很早就开始用了 但一直都没有了解过它的原理 听说是很简单 下面记录一些笔记 1 基本概念 收音机是一种小型的无线电接收机 主要用于接受无线电广播节目 收听无线电发射台 首先说一下收音机的种类 按解调方式和波长可以分为以下几类 调
  • VSCode加入Anaconda大家庭

    此文章首发于公众号Python for Finance 链接 https mp weixin qq com s rZsopAtS8UZ32aohWuhVBA 问题描述 我安装的是Anaconda 但最近发现VScode编辑ipynb非常好使
  • Ubuntu虚拟机找不到终端

    快捷键 Ctrl Alt T 即可打开终端窗口 或者按 Ctrl Alt F1 F6 均可进入终端 模拟终端 不显示桌面 想要右键打开终端 apt get install nautilus open terminal 注销系统重新登录 即可
  • 局域网场景下Android客户端实现同数据库连接通信

    实现 局域网场景下 Android客户端连接数据库 并可进行增删改查 直接连接 项目工程引入JDBC驱动 直接连接 JDBC是Java Data Base Connectivity的缩写 即 java数据库连接 一组Java语言编写的类和接
  • JXL(JExcelApi)相关资源

    1 主页 2 下载页面 Download JExcelApi 3 JXL API Online 4 全面挖掘Java Excel API 使用方法 1 5 全面挖掘Java Excel API 使用方法 2 6 使用JAVA透過JXL JE
  • 在虚拟机上安装macOS和Xcode

    最近要开发iOS软件 开发软件的操作系统需要是macOS 开发工具是Xcode 虽然实验室有苹果电脑 但是还是想在自己电脑上安装macOS虚拟机和Xcode软件 这样的话在宿舍或者在家都能开发 按照网上的教程成功安装了macOS和Xcode
  • git 提交分支报错(不能提交分支)

    git 提交新分支报错 报错信息如下 Compressing objects 100 100 100 done Writing objects 100 229 229 25 18 KiB 3 15 MiB s done Total 229
  • 淘宝x-sign算法demo示例

    用xposed hook这个方法就可以拿到对应的签名 需要可以留言 public String getMtopApiSign HashMap
  • 图文并茂:推荐算法架构——粗排

    导语 粗排是介于召回和精排之间的一个模块 是典型的精度与性能之间trade off的产物 理解粗排各技术细节 一定要时刻把精度和性能放在心中 本篇将深入重排这个模块进行阐述 一 总体架构 粗排是介于召回和精排之间的一个模块 它从召回获取上万
  • bilibili粉丝显示器

    代码地址 https github com hungtcs lab bilibili follower viewer ArduinoJSON https arduinojson org esp8266 oled ssd1306 https
  • Spirng @Conditional 条件注解的使用

    1 简介 Conditional 是 Spring 4 0 提出的一个新的注解 当标注的对象满足所有的条件时 才能注册为 Spring 中的 bean Conditional 源码中的定义如下 Target ElementType TYPE
  • C# Datagridview 标题完全居中

    DataGridView标题完全居中 标题文字居中 this dataGridView1 ColumnHeadersDefaultCellStyle Alignment DataGridViewContentAlignment Middle
  • Java 语言 TreeMap

    Java中的TreeMap是一种基于红黑树实现的排序映射表 它可以存储键值对 其中键和值都可以是任意类型的对象 TreeMap提供了快速的插入 删除和查找操作 具有高效的性能 并且可以根据键进行排序 因此在Java编程中非常常见 本文将介绍
  • 博士申请

    合适的工作难找 最新的招聘信息也不知道 AI 求职为大家精选人工智能领域最新鲜的招聘信息 助你先人一步投递 快人一步入职 南洋理工大学 南洋理工大学 Nanyang Technological University 是新加坡的一所世界著名研
  • 解决 Python 库安装提示:ModuleNotFoundError: No module named ‘windows‘. 问题解决方法

    在安装pyMouse PyKeyboard的时候报错我们可以尝试以下代码 应该有用 pip install PyUserInput
  • unity对象池系统

    当游戏场景中出现大量的可重复利用的物体时 通过Destory来销毁再创建会触发不必要的GC回收机制 浪费性能 我们可以利用unity自带的对象池系统 从而节约性能来得到同样的效果 为了使用这个对象池系统 我写了一个瞬间产生多枚子弹的测试脚本