Beispiel #1
0
        /// <summary>
        /// Unsafe回收一个Instance。如果确定它来自pool,使用此方法更有效率。
        /// 如果它不是一个instance或者它不是来自任何Pool:
        /// 如果destroyOnNotFromPool参数为true,就Destroy它;
        /// 如果destroyOnNotFromPool参数为false,
        /// 存在父对象,直到它自己被Destroy,或父对象被Destroy,
        /// 不存在父对象,直到它自己被Destroy,或切换场景被场景Destroy。
        /// </summary>
        /// <param name="instance"></param>
        /// <param name="destroyNotFromPool"></param>
        public static void DespawnUnsafe(GameObject instance, bool destroyNotFromPool = true)
        {
            if (instance == null)
            {
                return;
            }

            ReusableObject reusable = instance.GetComponent <ReusableObject>();

            if (reusable == null)
            {
                if (destroyNotFromPool)
                {
                    GameObject.Destroy(instance);
                }
            }
            else
            {
                if (!reusable.isFromPool && destroyNotFromPool)
                {
                    GameObject.Destroy(instance);
                }
                else
                {
                    reusable.Despawn(true);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// 生成一个Instance
        /// </summary>
        /// <param name="prefab"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        public GameObject Spawn(GameObject prefab, Vector3 position)
        {
            if (prefab == null)
            {
                Debug.LogErrorFormat("{0} -> Argument named 'prefab' is null.", poolName);
                return(null);
            }
            GameObject instance = GetOrCreateRecycledInstance(prefab);

            instance.transform.position = position;
            ReusableObject reusable = GetOrAddReusableObject(instance);

            instance.gameObject.SetActive(true);
            reusable.Spawn();

            if (m_EditorLog)
            {
                Debug.LogFormat(
                    "{0} -> Spawn a instance named '{1}'.",
                    poolName,
                    instance.name
                    );
            }

            return(instance);
        }
Beispiel #3
0
            /// <summary>
            /// 添加外部Instance。要保证使用的Prefab和这里的是同一个
            /// </summary>
            /// <param name="index"></param>
            /// <param name="item"></param>
            public void Insert(int index, GameObject item)
            {
                if (item == null)
                {
                    return;
                }

                if (m_Instances.Contains(item))
                {
                    return;
                }

                RenameInstance(item);
                m_Instances.Insert(index, item);

                ReusableObject reusable = GetOrAddReusableObject(item);

                reusable.isFromPool  = true;
                reusable.onDestroyed = ReusableObject_onDestroyed;
                reusable.onDespawn   = ReusableObject_onDespawn;

                if (reparentOnCreated)
                {
                    item.transform.SetParent(m_Pool.transform, false);
                }

                if (item.gameObject.activeSelf)
                {
                    reusable.Spawn();
                }
                else
                {
                    m_RecycledInstances.Add(item);
                }
            }
Beispiel #4
0
        /// <summary>
        /// 预创建Instance
        /// </summary>
        /// <param name="collection"></param>
        /// <returns></returns>
        private IEnumerator PreCreateInstance(InstanceCollection collection)
        {
            if (collection == null)
            {
                yield break;
            }

            if (m_EditorLog)
            {
                Debug.LogFormat(
                    "{0} -> {1} -> Start pre-load instances. Count('{2}').",
                    poolName,
                    collection.prefabName,
                    collection.preCount
                    );
            }

            yield return(null);

            while (collection.Count < collection.preCount)
            {
                int count = Mathf.Min(collection.preCount - collection.Count, collection.preCountPerFrame);
                for (int i = 0; i < count; i++)
                {
                    GameObject     go       = GameObject.Instantiate(collection.prefab);
                    ReusableObject reusable = GetOrAddReusableObject(go);
                    reusable.Despawn(false);
                    collection.Add(go);
                }
                yield return(null);
            }
        }
Beispiel #5
0
            /// <summary>
            /// 获取未使用Instance,如果没有,则创建一个Instance
            /// </summary>
            /// <returns></returns>
            internal GameObject GetOrCreateRecycledInstance()
            {
                GameObject instance;

                if (recycledCount > 0)
                {
                    instance = m_RecycledInstances[recycledCount - 1];
                    m_RecycledInstances.RemoveAt(recycledCount - 1);
                }
                else
                {
                    instance = GameObject.Instantiate(prefab);
                    RenameInstance(instance);
                    m_Instances.Add(instance);

                    ReusableObject reusable = GetOrAddReusableObject(instance);
                    reusable.isFromPool  = true;
                    reusable.onDestroyed = ReusableObject_onDestroyed;
                    reusable.onDespawn   = ReusableObject_onDespawn;

                    if (reparentOnCreated)
                    {
                        instance.transform.SetParent(m_Pool.transform, false);
                    }
                }

                return(instance);
            }
Beispiel #6
0
            private void ReusableObject_onDespawn(ReusableObject reusable)
            {
                m_RecycledInstances.Add(reusable.gameObject);

                if (reparentOnCreated && reusable.transform.parent != m_Pool.transform)
                {
                    reusable.transform.SetParent(m_Pool.transform, false);
                }
            }
Beispiel #7
0
        /// <summary>
        /// 获取或添加ReusableObject组件
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        public static ReusableObject GetOrAddReusableObject(GameObject instance)
        {
            ReusableObject reusable = instance.GetComponent <ReusableObject>();

            if (reusable == null)
            {
                reusable = instance.AddComponent <ReusableObject>();
            }
            return(reusable);
        }
Beispiel #8
0
            /// <summary>
            /// 移除出池子,
            /// 注意,如果它的父对象是DontDestroy,你需要手动销毁它或改变它的父对象让场景销毁它。
            /// </summary>
            /// <param name="item"></param>
            /// <returns></returns>
            public bool Remove(GameObject item)
            {
                if (!m_Instances.Contains(item))
                {
                    return(false);
                }

                ReusableObject reusable = item.GetComponent <ReusableObject>();

                reusable.isFromPool = false;
                m_RecycledInstances.Remove(item);
                return(m_Instances.Remove(item));
            }
Beispiel #9
0
        /// <summary>
        /// 回收一个Instance。
        /// true:回收成功。
        /// 有debug warning:参数instance为null,return false。
        /// 有debug error:这个GameObject不是由Pool创建的,return false。
        /// false:当没有error和warning时,instance是从其它pool里生成的,或者是没有添加到pool的外部instance。
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        public bool Despawn(GameObject instance)
        {
            if (instance == null)
            {
                Debug.LogWarningFormat("{0} -> You tryed despawn a 'null' instance.", poolName);
                return(false);
            }

            ReusableObject reusable = instance.GetComponent <ReusableObject>();

            if (reusable == null)
            {
                Debug.LogErrorFormat("{0} -> This GameObject is not a instance from pool.");
                return(false);
            }

            // 外部instance,没有加入任何pool
            if (!reusable.isFromPool)
            {
                return(false);
            }

            // 找到存在这个instance的collection
            InstanceCollection collection = m_InstanceCollections.Find(c => c.Contains(instance));

            // 没有找到,说明是其它pool里生成的
            if (collection == null)
            {
                return(false);
            }

            reusable.Despawn(true);

            if (m_EditorLog)
            {
                Debug.LogFormat(
                    "{0} -> Despawn a instance named '{1}'.",
                    poolName,
                    instance.name
                    );
            }

            return(true);
        }
Beispiel #10
0
            /// <summary>
            /// 释放集合,并销毁所有Instances
            /// </summary>
            public void Dispose()
            {
                if (m_Pool != null)
                {
                    // 从Pool中移除此collection
                    m_Pool.RemoveCollectionInternal(this);
                    m_Pool = null;
                }

                m_Prefab            = null;
                m_RecycledInstances = null;

                // Destroy所有instances
                for (int i = 0; i < m_Instances.Count; i++)
                {
                    GameObject     instance = m_Instances[i];
                    ReusableObject reusable = instance.GetComponent <ReusableObject>();
                    reusable.onDespawn   = null;
                    reusable.onDestroyed = null;
                    GameObject.Destroy(instance);
                }

                m_Instances = null;
            }
Beispiel #11
0
 private void ReusableObject_onDestroyed(ReusableObject reusable)
 {
     m_RecycledInstances.Remove(reusable.gameObject);
     m_Instances.Remove(reusable.gameObject);
 }