unity中的万能对象池

Unity中的万能对象池

在Unity开发中,对象池是一个非常常用的技术,在需要频繁创建和销毁游戏对象的场景下,使用对象池能够提高游戏运行的效率和性能。

不过,与常规的对象池不同的是,本文介绍的是一种使用泛型和接口实现的万能对象池,不仅可以复用GameObject对象,同时也能够重复使用所有继承自MonoBehaviour的组件。

实现方式

首先,定义一个接口IPoolable,它包含了两个方法,OnSpawnOnDespawn,分别代表对象被获取和归还时的操作:

public interface IPoolable
{
    void OnSpawn();
    void OnDespawn();
}

接着,定义一个泛型类ObjectPool<T>,它继承自MonoBehaviour,因为我们需要使用协程来实现对象的自动归还。ObjectPool<T>有以下属性和方法:

public class ObjectPool<T> : MonoBehaviour where T : Component, IPoolable
{
    [SerializeField]
    private T prefab;

    private Queue<T> objectQueue = new Queue<T>();

    public T Get()
    {
        if (objectQueue.Count == 0)
        {
            return Instantiate(prefab);
        }
        else
        {
            T objectToGet = objectQueue.Dequeue();
            objectToGet.gameObject.SetActive(true);
            objectToGet.OnSpawn();
            return objectToGet;
        }
    }

    public void Return(T objectToReturn)
    {
        objectToReturn.OnDespawn();
        objectToReturn.gameObject.SetActive(false);
        objectQueue.Enqueue(objectToReturn);
    }
}

其中,prefab属性为对象池内保存的对象预制体。objectQueue是一个FIFO的队列,用来存储已经使用过的对象。Get()方法会从队列中获取一个对象,如果队列为空就新建一个对象。获取到的对象需要被激活,并调用它的OnSpawn()方法。Return(objectToReturn)方法则是将对象归还至队列,调用它的OnDespawn()方法,并设置它的游戏对象为不激活状态。

最后,我们让需要使用对象池的GameObject继承自IPoolable接口,并手动实现OnSpawnOnDespawn方法。这样,我们就可以把任意继承自MonoBehaviour的组件加入到我们的对象池中,用法非常灵活。

使用示例

假设我们想要使用这个万能对象池来实现子弹的复用,现在我们需要在场景中创建一个子弹预制体,预制体上需要挂载Bullet脚本:

public class Bullet : MonoBehaviour, IPoolable
{
    public float speed = 10.0f;
    public float lifetime = 5.0f;

    private Coroutine lifetimeCoroutine;

    public void OnSpawn()
    {
        lifetimeCoroutine = StartCoroutine(LifetimeTimer());
    }

    public void OnDespawn()
    {
        StopCoroutine(lifetimeCoroutine);
    }

    private IEnumerator LifetimeTimer()
    {
        yield return new WaitForSeconds(lifetime);
        ObjectPool<Bullet>.Instance.Return(this);
    }

    void Update()
    {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    }
}

Bullet脚本实现了IPoolable接口,并在OnSpawn方法中启动了一个携程,用来计算子弹的寿命。当寿命结束时,我们需要将子弹归还到对象池中。

在我们的游戏场景中创建一个空对象,将ObjectPool脚本挂载上去:

public class ObjectPool : MonoBehaviour
{
    public static ObjectPool Instance;

    void Awake()
    {
        Instance = this;
    } 
}

在需要使用子弹的脚本中,我们只需要调用ObjectPool<Bullet>.Instance.Get()方法获取一个子弹,而不是手动使用Instantiate来创建它:

ObjectPool<Bullet>.Instance.Get();

当需要归还对象时,调用Return()方法:

ObjectPool<Bullet>.Instance.Return(bullet);

总结

这篇文章介绍了一种使用泛型和接口实现的万能对象池,可以方便灵活地复用GameObject和所有继承自MonoBehaviour的组件。这种实现方式避免了重复编写对象池代码的麻烦,大大提高开发效率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:unity中的万能对象池 - Python技术站

(0)
上一篇 2023年3月28日
下一篇 2023年3月28日

相关文章

  • IOS 指纹识别详解及实例代码

    IOS 指纹识别详解及实例代码 一、什么是IOS指纹识别? 指纹识别是一种生物识别技术,它通过采集用户的指纹信息,并对其进行特征提取和匹配,从而实现身份认证功能,是IOS系统的一个重要功能。 二、怎么使用IOS指纹识别? IOS指纹识别可以通过以下步骤实现: 1.引入依赖 在Xcode的项目中,需要添加LocalAuthentication库的依赖,通过在B…

    other 2023年6月26日
    00
  • Spring使用AOP完成统一结果封装实例demo

    下面我会详细讲解“Spring使用AOP完成统一结果封装实例demo”的完整攻略。 1. AOP介绍 AOP(Aspect-Oriented Programming)即面向切面编程,是一种编程思想。通俗来说,AOP可以在不修改原代码的情况下,通过对原代码进行额外的“切面”操作,例如:记录日志,安全检查,性能监控,事务控制等。AOP的核心思想就是将这些横切关注…

    other 2023年6月25日
    00
  • 电脑高手常用技巧应用全接解

    电脑高手常用技巧应用全接解 作为一名电脑高手,掌握一些常用技巧可以帮助我们更加高效地使用电脑。以下是电脑高手常用技巧应用全接解的详细攻略: 一、清理系统垃圾 随着我们在电脑上进行各种操作,系统会产生大量垃圾文件,日积月累会占用相当大的磁盘空间,导致电脑运行变慢。因此,我们需要定期清理系统垃圾。 在Windows系统中,可以通过以下步骤清理系统垃圾: 打开“我…

    other 2023年6月25日
    00
  • 开机显示英文:find –set-root…不能正常进入系统的解决方法

    针对“开机显示英文:find –set-root…不能正常进入系统的解决方法”,下面是详细的攻略。 问题描述 如果在开机启动时遇到以下英文提示: find –set-root –ignore-floppies /bootmgr Error 15: File not found Press any key to continue… 这表示系统没有找到…

    other 2023年6月27日
    00
  • anddesignpro入坑指南

    以下是“AndDesignPro入坑指南”的完整攻略: AndDesignPro入坑指南 AndDesignPro是一款基于Web的UI设计工具它提供了丰富的设计元素和模板,助您轻松创建漂亮的UI设计。本攻略将介绍如何使用AndDesignProUI设计。 步骤1:注册AndDesignPro账号 要使用AndDesignPro进行UI设计,您需要先注册一个…

    other 2023年5月7日
    00
  • 教你在PostgreSql中使用JSON字段的方法

    当我们在PostgreSQL中需要存储一个不规则的结构化数据时,可以使用JSON类型字段。JSON 字段在 PostgreSQL 中的好处之一是能够快速地查询、筛选、或者在应用程序中访问数据。 下面是在PostgreSQL中使用JSON字段的方法: 1.创建一个JSON类型的字段 在创建表时,可以使用json数据类型来定义一个JSON类型的字段。例如: CR…

    other 2023年6月25日
    00
  • linux下使用github

    Linux下使用GitHub的完整攻略 GitHub是一个非常流行的代码托管平台,许多开发者都在上面分享自己的代码。在Linux系统中,可以使用命令行工具来使用GitHub。本攻略将详细介绍如何在Linux系统中使用GitHub。 1. 安装Git 在使用GitHub之前,需要先安装Git。可以使用以下命令在Linux系统中安装Git: sudo apt-g…

    other 2023年5月7日
    00
  • C语言 字符串首字母转换成大写简单实例

    C语言 字符串首字母转换成大写简单实例攻略 在C语言中,要将字符串的首字母转换成大写,可以按照以下步骤进行: 导入必要的头文件: #include <stdio.h> #include <ctype.h> 定义一个函数来实现首字母转换: void capitalizeFirstLetter(char *str) { if (str !…

    other 2023年8月19日
    00
合作推广
合作推广
分享本页
返回顶部