Unity Object Pool完全体

Posted Litmin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity Object Pool完全体相关的知识,希望对你有一定的参考价值。

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



    public class ObjectPool<T>
    {
        private readonly Stack<T> stack = new Stack<T>();
        private readonly Func<T> actionOnNew;
        private readonly UnityAction<T> actionOnGet;
        private readonly UnityAction<T> actionOnRelease;

        public int CountAll { get; private set; }
        public int CountInactive { get { return stack.Count; } }
        public int CountActive { get { return CountAll - CountInactive; } }

        public ObjectPool(Func<T> onNew, UnityAction<T> onGet = null, UnityAction<T> onRelease = null)
        {
            actionOnNew = onNew;
            actionOnGet = onGet;
            actionOnRelease = onRelease;
        }

        public T Get()
        {
            T element;
            if (stack.Count == 0)
            {
                element = actionOnNew == null ? default(T) : actionOnNew.Invoke();
                CountAll++;
            }
            else
            {
                element = stack.Pop();
            }

            if (actionOnGet != null) { actionOnGet.Invoke(element); }
            return element;
        }

        public void Release(T element)
        {
            if (stack.Count > 0 && ReferenceEquals(stack.Peek(), element))
            {
                Debug.LogError("Internal error. Trying to destroy object that is already released to pool.");
            }

            if (actionOnRelease != null) { actionOnRelease.Invoke(element); }

            stack.Push(element);

            if (stack.Count > CountAll)
            {
                CountAll = stack.Count;
            }
        }
    }

 使用泛型和委托简化代码,扩展性强。

使用示例:

Bullet类:

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

public class Bullet : MonoBehaviour
{
    private int speed;

    private int damage;

    private float lifeTime = 10.0f;

    private float lifeTimer = 0;

    public delegate void BulletDestroyEvent(Bullet bullet);

    public event BulletDestroyEvent OnBulletDestroy; 
    public int Speed
    {
        get { return speed; }
        set { speed = value; }
    }

    public int Damage
    {
        get { return damage; }
        set { damage = value; }
    }
        
    public float LifeTime
    {
        get { return lifeTime; }
        set { lifeTime = value; }
    }
        

    void Start ()
    {
        
    }
    
    void Update ()
    {
        if(Input.GetKeyDown(KeyCode.Mouse1))
        {
            OnBulletDestroy.Invoke(this);
        }

        lifeTimer += Time.deltaTime;
        if(lifeTimer >= LifeTime)
        {
            lifeTimer = 0.0f;
            OnBulletDestroy.Invoke(this);
        }
    }

    void OnCollisionEnter(Collision collision)
    {
        OnBulletDestroy.Invoke(this);
    }
}

ObjectPoolManager:

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

public class ObjectPoolManager : MonoBehaviour
{
    public GameObject bulletPrefab;

    public ObjectPool<Bullet> bulletPool;

    public List<Bullet> bulletList; 
    void Start ()
    {
        bulletPool = new ObjectPool<Bullet>(BulletPoolOnNew,BulletOnGet,BulletOnRelease);
    }
    
    void Update ()
    {
        if(Input.GetKeyDown(KeyCode.Mouse0))
        {
            //generate one bullet   
            bulletList.Add(bulletPool.Get());
        }

        if(Input.GetKeyDown(KeyCode.W))
        {
            //delete one bullet
            bulletPool.Release(bulletList[0]);
        }
    }

    //pool method
    Bullet BulletPoolOnNew()
    {
        var bulletObject = Instantiate(bulletPrefab) as GameObject;

        bulletObject.GetComponent<Bullet>().OnBulletDestroy += bulletPool.Release;

        return bulletObject.GetComponent<Bullet>();
    }

    void BulletOnGet(Bullet bullet)
    {
        bullet.gameObject.SetActive(true);
    }

    void BulletOnRelease(Bullet bullet)
    {
        bullet.gameObject.SetActive(false);
    }
}

 

以上是关于Unity Object Pool完全体的主要内容,如果未能解决你的问题,请参考以下文章

unity动画一个片段播放完怎么让它不会到初始状态

Unity3D-对象池

Object Pool 对象池的C++11使用(转)

Unity3D-对象池

Unity3D-对象池

Unity3D-对象池