zoukankan      html  css  js  c++  java
  • 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);
        }
    }
  • 相关阅读:
    [JavaScript]使用setTimeout减少多余事件
    Spring.NET教程(二)——环境搭建(基础篇) (转)
    IIS开启GZIP压缩效率对比及部署方法 (转)
    提高表格操作的十五款jQuery插件
    SQLServer和Oracle常用函数对比
    [hystar整理]Entity Framework 教程
    Remoting方法重载遇到的一个问题
    异变: input的背景background
    实时股票数据接口
    发现并解决ASP.NET内存耗尽(OOM),让服务器"永不重启"
  • 原文地址:https://www.cnblogs.com/litmin/p/7250575.html
Copyright © 2011-2022 走看看