Unity对象池的简单用法

Unity对象池的简单用法

对象池是当物体需要被大量地创建与删除同时还需要复用时所使用的方式。
对频繁创建与删除的物体不进行频繁创建与删除,因为频繁地使用instantiate函数和Destroy函数比较耗费内存。引用了一个对象池的概念,用类似SetActive的方式使物体伪创建和伪删除,当一个位置的物体消失,也就是SetActive(false)后,另一个位置需要显示时,会在需要的位置SetActive(true),以这种方式来节省内存的消耗,是一种在游戏设计中经常使用的优化策略。
举一个简单的例子
创建一个空物体,附上如下代码:

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

public class ObjectPool : MonoBehaviour
{
    public static ObjectPool instance;
     Stack<GameObject> pool=new Stack<GameObject>();
    // Start is called before the first frame update
    void Start()
    {
        instance = this;
    }
    public void Delete(GameObject g)
    {
        g.SetActive(false);
        pool.Push(g);
    }
    public GameObject Creat(GameObject prefab,Vector3 position,Quaternion qua)
    {
        GameObject g=null;
        if(pool.Count>0)
        {
            g=pool.Pop();
            g.SetActive(true);
            g.transform.position = position;
            g.transform.rotation = qua;
        }
        else
        {
            g = Instantiate(prefab, position, qua);
        }
        return g;
    }
    // Update is called once per frame
}

再创建一个空物体,附上如下代码:

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

public class PoolTest : MonoBehaviour
{
    public GameObject prefab;
    public Stack<GameObject> s = new Stack<GameObject>();
    // Start is called before the first frame update
    public void Creat(){
        s.Push(ObjectPool.instance.Creat(prefab, Vector3.one, Quaternion.identity));
    }
    public void Delete()
    {
        ObjectPool.instance.Delete(s.Pop());
    }
    // Update is called once per frame
}

将需要操作的物体设为预制体拖入PoolTest的空槽中。创建两个button,一个命名为creat,另一个命名为delete,分别给上PoolTest中的creat和delete函数。运行场景,点击按钮我们会看到已创建的物体以SetActive的方式隐藏和显示(当没有物体继续delete会报错)。
在这里插入图片描述

### 回答1: 好的,我来帮你写一个简单Unity对象池。 首先,我们需要创建一个存储对象的容器,可以是一个List或者是一个Queue,用来存储对象的实例。然后,我们可以写一个获取对象的方法,当需要使用一个对象时,从容器中获取一个对象并将其返回。如果容器中没有可用的对象,则可以通过Instantiate方法创建一个新的对象。 同样,我们还需要写一个归还对象的方法,当不再使用一个对象时,可以将其归还到容器中,以便以后使用。 以下是一个简单的代码实现: ``` using System.Collections.Generic; using UnityEngine; public class ObjectPool : MonoBehaviour { public GameObject prefab; private Queue<GameObject> objects; private void Start() { objects = new Queue<GameObject>(); } public GameObject GetObject() { if (objects.Count == 0) { GameObject obj = Instantiate(prefab); obj.SetActive(false); return obj; } else { GameObject obj = objects.Dequeue(); obj.SetActive(true); return obj; } } public void ReturnObject(GameObject obj) { obj.SetActive(false); objects.Enqueue(obj); } } ``` 希望这个代码对您有所帮助。 ### 回答2: Unity对象池是一种优化技术,用于重复使用已经创建的游戏对象,以减少对象的创建和销毁开销,提高游戏的性能。下面是一个简单Unity对象池的实现思路: 首先,我们需要定义一个对象池的类,可以称为ObjectPool。这个类需要包含以下几个关键属性和方法: 1. 对象列表:需要一个列表来存储可重复利用的游戏对象。 2. 创建对象:需要一个方法来创建游戏对象,并将其添加到对象列表中。 3. 获取对象:需要一个方法来从对象列表中获取一个可用的游戏对象,如果没有可用对象,则创建一个新的。 4. 回收对象:需要一个方法来回收一个已经使用过的游戏对象,将其重置并标记为可重用。 下面是一个简单Unity对象池的代码示例: ``` using System.Collections.Generic; using UnityEngine; public class ObjectPool : MonoBehaviour { public GameObject prefab; // 预制体对象 public int initialPoolSize; // 初始对象池的大小 private List<GameObject> objectPool; // 对象池列表 private void Start() { objectPool = new List<GameObject>(); for (int i = 0; i < initialPoolSize; i++) { CreateObject(); // 创建初始对象池游戏对象 } } private GameObject CreateObject() { GameObject obj = Instantiate(prefab); obj.SetActive(false); objectPool.Add(obj); return obj; } private GameObject GetObject() { GameObject obj = null; for (int i = 0; i < objectPool.Count; i++) { if (!objectPool[i].activeInHierarchy) { obj = objectPool[i]; break; } } if (obj == null) { obj = CreateObject(); // 如果没有可用对象,则创建一个新的 } obj.SetActive(true); return obj; } public void RecycleObject(GameObject obj) { obj.SetActive(false); } } ``` 以上就是一个简单Unity对象池的实现。你可以根据自己的需求,对其进行扩展和优化。 ### 回答3: Unity对象池是一种内存管理技术,用于重复使用对象,减少内存分配和垃圾回收的开销。以下是一个简单Unity对象池实现: 首先,创建一个新的空物体,命名为ObjectPoolManager。将下面的脚本附加到该物体上: ```csharp using System.Collections.Generic; using UnityEngine; public class ObjectPoolManager : MonoBehaviour { public static ObjectPoolManager instance; // 单例实例 private Dictionary<string, List<GameObject>> objectPools; // 对象池字典 private void Awake() { if (instance == null) { instance = this; } else { Destroy(gameObject); } objectPools = new Dictionary<string, List<GameObject>>(); } public GameObject GetObject(GameObject prefab) { string key = prefab.name; if (!objectPools.ContainsKey(key)) { objectPools[key] = new List<GameObject>(); } List<GameObject> pool = objectPools[key]; if (pool.Count > 0) { GameObject obj = pool[0]; pool.RemoveAt(0); obj.SetActive(true); return obj; } else { GameObject obj = Instantiate(prefab); obj.name = key; return obj; } } public void ReturnObject(GameObject obj) { string key = obj.name; if (!objectPools.ContainsKey(key)) { objectPools[key] = new List<GameObject>(); } List<GameObject> pool = objectPools[key]; obj.SetActive(false); pool.Add(obj); } } ``` 使用对象池的示例代码: ```csharp using UnityEngine; public class ObjectSpawner : MonoBehaviour { public GameObject prefab; private void Start() { // 获取对象池中的物体 GameObject obj = ObjectPoolManager.instance.GetObject(prefab); // 设置物体位置和旋转 obj.transform.position = transform.position; obj.transform.rotation = transform.rotation; // 使用物体 // ... // 将物体返回对象池 ObjectPoolManager.instance.ReturnObject(obj); } } ``` 以上代码实现了一个简单Unity对象池对象池的原理是通过创建对象池字典,将不同类型的对象放入对应的列表中。在需要使用对象时,先从字典中查找该类型的对象列表,如果列表中有可用对象,则从列表中取出并返回给调用者;如果列表为空,则实例化一个新对象并返回给调用者。使用完对象后,将对象设置为非激活状态,并放回对象池列表中以备下次使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值