Example #1
0
        public Transform Spawn(Transform prefab, Vector3 pos, Quaternion rot)
        {
            Transform transform;

            foreach (PrefabPool current in this._prefabPools)
            {
                if (current.prefabGO == prefab.gameObject)
                {
                    transform = current.SpawnInstance(pos, rot);
                    Transform result;
                    if (transform == null)
                    {
                        result = null;
                        return(result);
                    }
                    if (!this.dontReparent && transform.parent != this.group)
                    {
                        transform.parent = this.group;
                    }
                    this._spawned.Add(transform);
                    result = transform;
                    return(result);
                }
            }
            PrefabPool prefabPool = new PrefabPool(prefab);

            this.CreatePrefabPool(prefabPool);
            transform        = prefabPool.SpawnInstance(pos, rot);
            transform.parent = this.group;
            this._spawned.Add(transform);
            return(transform);
        }
Example #2
0
        /// <summary>
        /// <para>这是第一行</para>
        /// <para>在对象池中创建一个新的预制池并创建请求数量的实例对象(通过PrefabPool.preloadAmount设置),如果请求数量为0,将不会创建实例</para>
        /// <para>这个函数仅当你需要设置一个新的预制池时会被执行,比如在使用前的剔除或预加载</para>
        /// <para>另外,如果是第一次使用的预制池,用Active()将会自动创建默认值</para>
        ///
        /// <para>像下面这样创建预制池并设置参数      </para>
        /// <para>    PrefabPool prefabPool = new PrefabPool()</para>
        /// <para>    prefabPool.prefab = myPrefabReference;</para>
        /// <para>    prefabPool.preloadAmount = 0;</para>
        /// <para>    prefabPool.cullDespawned = True;</para>
        /// <para>    prefabPool.cullAbove = 50;</para>
        /// <para>    prefabPool.cullDelay = 30;</para>
        /// <para>//初始化内存池</para>
        /// <para>    spawnPool._perPrefabPoolOptions.Add(prefabPool);</para>
        /// <para>    spawnPool.CreatePrefabPool(spawnPool._perPrefabPoolOptions[spawnPool._perPrefabPoolOptions.Count - 1]);</para>
        /// </summary>
        /// <param name="prefabPool">A PrefabPool object</param>
        /// <returns>A List of instances spawned or an empty List</returns>
        public void CreatePrefabPool(PrefabPool prefabPool)
        {
            //判断内存池是否已经存在
            bool isAlreadyPool = this.GetPrefabPool(prefabPool.prefab) != null;

            if (!isAlreadyPool)
            {
                //给内存池对象赋值
                prefabPool.ObjectPool = this;

                //把预制池添加进列表和字典中
                this._prefabPools_List.Add(prefabPool);
                this.prefabs_Dict._Add(prefabPool.prefab.name, prefabPool.prefab);
            }

            // 预加载预制体的实例
            if (prefabPool.Preloaded != true)
            {
                if (this.logMessages)
                {
                    Debug.Log(string.Format("SpawnPool {0}: Preloading {1} {2}",
                                            this.poolName,
                                            prefabPool.preloadAmount,
                                            prefabPool.prefab.name));
                }

                prefabPool.PreloadInstances();
            }
        }
Example #3
0
        /// <summary>
        /// 从对象池中获取对象
        /// </summary>
        /// <param name="prefabId"></param>
        /// <param name="onComplete"></param>
        public void Spawn(byte prefabId, System.Action <Transform> onComplete)
        {
            Sys_PrefabEntity entity = GameEntry.DataTable.DataTableManager.Sys_PrefabDBModel.Get(prefabId);

            if (entity == null)
            {
                Debug.LogError("预设数据不存在");
                return;
            }

            GameEntry.Resource.ResourceLoaderManager.LoadMainAsset((AssetCategory)entity.AssetCategory,
                                                                   entity.AssetPath, (ResourceEntity resourceEntity) =>
            {
                GameObjectPoolEntity gameObjectPoolEntity = m_SpawnPoolDic[entity.PoolId];
                Transform prefab = ((GameObject)resourceEntity.Target).transform;
                PathologicalGames.PrefabPool prefabPool = gameObjectPoolEntity.Pool.GetPrefabPool(entity.Id);

                if (prefabPool == null)
                {
                    //先去队列里找 空闲的池
                    if (m_PrefabPoolQueue.Count > 0)
                    {
                        Debug.LogError("从队列里取");
                        prefabPool = m_PrefabPoolQueue.Dequeue();
                        prefabPool.PrefabPoolId = entity.Id;     //设置预设池编号
                        gameObjectPoolEntity.Pool.AddPrefabPool(prefabPool);

                        prefabPool.prefab   = prefab;
                        prefabPool.prefabGO = prefab.gameObject;
                        prefabPool.AddPrefabToDic(prefab.name, prefab);
                    }
                    else
                    {
                        prefabPool = new PrefabPool(prefab, entity.Id);
                        gameObjectPoolEntity.Pool.CreatePrefabPool(prefabPool, resourceEntity);
                    }

                    prefabPool.OnPrefabPoolClear = (PrefabPool pool) =>
                    {
                        //预设池加入队列
                        pool.PrefabPoolId = 0;
                        gameObjectPoolEntity.Pool.RemovePrefabPool(pool);
                        m_PrefabPoolQueue.Enqueue(pool);
                    };

                    //这些属性要从表格中读取
                    prefabPool.cullDespawned  = entity.CullDespawned == 1;
                    prefabPool.cullAbove      = entity.CullAbove;
                    prefabPool.cullDelay      = entity.CullDelay;
                    prefabPool.cullMaxPerPass = entity.CullMaxPerPass;
                }

                //拿到一个实例
                Transform retTrans = gameObjectPoolEntity.Pool.Spawn(prefab, resourceEntity);
                int instanceID     = retTrans.gameObject.GetInstanceID();
                m_InstanceIdPoolIdDic[instanceID] = (byte)entity.PoolId;
                onComplete?.Invoke(retTrans);
            });
        }
Example #4
0
        /// <summary>
        /// 获取一个资源实例.
        /// </summary>
        public Transform Spawn(Transform prefab, Vector3 pos, Quaternion rot, Transform parent)
        {
            Transform inst;
            bool      worldPositionStays;

            for (int i = 0; i < this._prefabPools.Count; i++)
            {
                if (this._prefabPools[i].prefabGO == prefab.gameObject)
                {
                    inst = this._prefabPools[i].SpawnInstance(pos, rot);
                    if (inst == null)
                    {
                        return(null);
                    }

                    worldPositionStays = !(inst is RectTransform);

                    if (parent != null)
                    {
                        inst.SetParent(parent, worldPositionStays);
                    }
                    else if (!this.dontReparent && inst.parent != this.group)
                    {
                        inst.SetParent(this.group, worldPositionStays);
                    }
                    this._spawned.Add(inst);
                    inst.gameObject.BroadcastMessage("OnSpawned", this, SendMessageOptions.DontRequireReceiver);
                    return(inst);
                }
            }

            PrefabPool newPrefabPool = new PrefabPool(prefab);

            this.CreatePrefabPool(newPrefabPool);
            inst = newPrefabPool.SpawnInstance(pos, rot);
            worldPositionStays = !(inst is RectTransform);
            if (parent != null)
            {
                inst.SetParent(parent, worldPositionStays);
            }
            else if (!this.dontReparent && inst.parent != this.group)
            {
                inst.SetParent(this.group, worldPositionStays);
            }
            this._spawned.Add(inst);
            inst.gameObject.BroadcastMessage("OnSpawned", this, SendMessageOptions.DontRequireReceiver);
            return(inst);
        }
Example #5
0
        public Transform Spawn(Transform prefab, Vector3 pos, Quaternion rot, Transform parent)
        {
            int       i = 0;
            Transform transform;

            while (i < this._prefabPools.Count)
            {
                if (this._prefabPools[i].prefabGO == prefab.gameObject)
                {
                    transform = this._prefabPools[i].SpawnInstance(pos, rot);
                    if (transform == null)
                    {
                        return(null);
                    }
                    if (parent != null)
                    {
                        transform.parent = parent;
                    }
                    else if (!this.dontReparent && transform.parent != this.group)
                    {
                        transform.parent = this.group;
                    }
                    this._spawned.Add(transform);
                    transform.gameObject.BroadcastMessage("OnSpawned", this, SendMessageOptions.DontRequireReceiver);
                    return(transform);
                }
                else
                {
                    i++;
                }
            }
            PrefabPool prefabPool = new PrefabPool(prefab);

            this.CreatePrefabPool(prefabPool);
            transform = prefabPool.SpawnInstance(pos, rot);
            if (parent != null)
            {
                transform.parent = parent;
            }
            else
            {
                transform.parent = this.group;
            }
            this._spawned.Add(transform);
            transform.gameObject.BroadcastMessage("OnSpawned", this, SendMessageOptions.DontRequireReceiver);
            return(transform);
        }
Example #6
0
 public void CreatePrefabPool(PrefabPool prefabPool)
 {
     if (this.GetPrefab(prefabPool.prefab) == null)
     {
         prefabPool.spawnPool = this;
         this._prefabPools.Add(prefabPool);
         if (!this.prefabs.ContainsKey(prefabPool.prefab.name))
         {
             this.prefabs._Add(prefabPool.prefab.name, prefabPool.prefab);
         }
     }
     if (this.logMessages)
     {
         UnityEngine.Debug.Log(string.Format("SpawnPool {0}: Preloading {1} {2}", this.poolName, prefabPool.preloadAmount, prefabPool.prefab.name));
     }
     prefabPool.PreloadInstances();
 }
Example #7
0
        /// <summary>
        /// Creates a new PrefabPool in this Pool and instances the requested
        /// number of instances (set by PrefabPool.preloadAmount). If preload
        /// amount is 0, nothing will be spawned and the return list will be empty.
        ///
        /// It is rare this function is needed during regular usage.
        /// This function should only be used if you need to set the preferences
        /// of a new PrefabPool, such as culling or pre-loading, before use. Otherwise,
        /// just use Spawn() and if the prefab is used for the first time a PrefabPool
        /// will automatically be created with defaults anyway.
        ///
        /// Note: Instances with ParticleEmitters can be preloaded too because
        ///       it won't trigger the emmiter or the coroutine which waits for
        ///       particles to die, which Spawn() does.
        ///
        /// Usage Example:
        ///     // Creates a prefab pool and sets culling options but doesn't
        ///     //   need to spawn any instances (this is fine)
        ///     PrefabPool prefabPool = new PrefabPool()
        ///     prefabPool.prefab = myPrefabReference;
        ///     prefabPool.preloadAmount = 0;
        ///     prefabPool.cullDespawned = True;
        ///     prefabPool.cullAbove = 50;
        ///     prefabPool.cullDelay = 30;
        ///
        ///     // Enemies is just an example. Any pool is fine.
        ///     PoolManager.Pools["Enemies"].CreatePrefabPool(prefabPool);
        ///
        ///     // Then, just use as normal...
        ///     PoolManager.Pools["Enemies"].Spawn(myPrefabReference);
        /// </summary>
        /// <param name="prefabPool">A PrefabPool object</param>
        /// <returns>A List of instances spawned or an empty List</returns>
        public void CreatePrefabPool(PrefabPool prefabPool)
        {
            // Only add a PrefabPool once. Uses a GameObject comparison on the prefabs
            //   This will rarely be needed and will almost Always run at game start,
            //   even if user-executed. This really only fails If a user tries to create
            //   a PrefabPool using a prefab which already has a PrefabPool in the same
            //   SpawnPool. Either user created twice or PoolManager went first or even
            //   second in cases where a user-script beats out PoolManager's init during
            //   Awake();
            bool isAlreadyPool = this.GetPrefabPool(prefabPool.prefab) == null ? false : true;

            // Used internally to reference back to this spawnPool for things
            //   like anchoring co-routines.
            prefabPool.spawnPool = this;
            if (!isAlreadyPool)
            {
                this._prefabPools.Add(prefabPool);

                // Add to the prefabs dict for convenience
                try
                {
                    this.prefabs._Add(prefabPool.prefab.name, prefabPool.prefab);
                }
                catch (System.Exception)
                {
                    throw new System.Exception(string.Format("对象池中已存在同名文件: {0} 。请检查配置表和对象池是否存在同名对象", prefabPool.prefab.name));
                }
            }

            // Preloading (uses a singleton bool to be sure this is only done once)
            if (prefabPool.preloaded != true)
            {
                if (this.logMessages)
                {
                    Debug.Log(string.Format("SpawnPool {0}: Preloading {1} {2}",
                                            this.poolName,
                                            prefabPool.preloadAmount,
                                            prefabPool.prefab.name));
                }

                prefabPool.PreloadInstances();
            }
        }
Example #8
0
        /// <summary>
        /// 从对象池中获取对象 可以废弃
        /// </summary>
        /// <param name="poolId"></param>
        /// <param name="prefab"></param>
        /// <param name="onComplete"></param>
        public void Spawn(byte poolId, Transform prefab, System.Action <Transform> onComplete)
        {
            GameObjectPoolEntity entity = m_SpawnPoolDic[poolId];

            //拿到预设池
            PathologicalGames.PrefabPool prefabPool = entity.Pool.GetPrefabPool(prefab);


            if (prefabPool == null)
            {
                prefabPool = new PathologicalGames.PrefabPool(prefab);
                prefabPool.cullDespawned = entity.CullDespawned;
                prefabPool.cullAbove     = entity.CullAbove;
                prefabPool.cullDelay     = entity.CullDelay;

                prefabPool.cullMaxPerPass = entity.CullMaxPerPass;
                entity.Pool.CreatePrefabPool(prefabPool);
            }
            if (onComplete != null)
            {
                onComplete(entity.Pool.Spawn(prefab));
            }
        }
Example #9
0
        public void Despawn(Transform instance)
        {
            bool flag = false;

            for (int i = 0; i < this._prefabPools.Count; i++)
            {
                PrefabPool prefabPool = this._prefabPools[i];
                if (prefabPool._spawned.Contains(instance))
                {
                    flag = prefabPool.DespawnInstance(instance);
                    break;
                }
                if (prefabPool._despawned.FirstOrDefault((PrefabPool.DespawnedItem x) => instance == x.transform) != null)
                {
                    UnityEngine.Debug.Log(string.Format("SpawnPool {0}: {1} has already been despawned. You cannot despawn something more than once!", this.poolName, instance.name));
                    return;
                }
            }
            if (!flag)
            {
                return;
            }
            this._spawned.Remove(instance);
        }
Example #10
0
        public void CreatePrefabPool(PrefabPool prefabPool)
        {
            bool isAlreadyPool = this.GetPrefabPool(prefabPool.prefab.gameObject) == null ? false : true;

            if (isAlreadyPool)
            {
                throw new System.Exception(string.Format
                                           (
                                               "Prefab '{0}' is already in  SpawnPool '{1}'. Prefabs can be in more than 1 SpawnPool but " +
                                               "cannot be in the same SpawnPool twice.",
                                               prefabPool.prefab,
                                               this.poolName
                                           ));
            }

            prefabPool.spawnPool = this;
            this._prefabPools.Add(prefabPool);
            this.prefabs._Add(prefabPool.prefab.name, prefabPool.prefab);

            if (prefabPool.preloaded != true)
            {
                prefabPool.PreloadInstances();
            }
        }
Example #11
0
        /// <description>
        ///	Spawns an instance or creates a new instance if none are available.
        ///	Either way, an instance will be set to the passed position and
        ///	rotation.
        ///
        /// Detailed Information:
        /// Checks the Data structure for an instance that was already created
        /// using the prefab. If the prefab has been used before, such as by
        /// setting it in the Unity Editor to preload instances, or just used
        /// before via this function, one of its instances will be used if one
        /// is available, or a new one will be created.
        ///
        /// If the prefab has never been used a new PrefabPool will be started
        /// with default options.
        ///
        /// To alter the options on a prefab pool, use the Unity Editor or see
        /// the documentation for the PrefabPool class and
        /// SpawnPool.SpawnPrefabPool()
        ///
        /// Broadcasts "OnSpawned" to the instance. Use this to manage states.
        ///
        /// An overload of this function has the same initial signature as Unity's
        /// Instantiate() that takes position and rotation. The return Type is different
        /// though. Unity uses and returns a GameObject reference. PoolManager
        /// uses and returns a Transform reference (or other supported type, such
        /// as AudioSource and ParticleSystem)
        /// </description>
        /// <param name="prefab">
        /// The prefab used to spawn an instance. Only used for reference if an
        /// instance is already in the pool and available for respawn.
        /// NOTE: Type = Transform
        /// </param>
        /// <param name="pos">The position to set the instance to</param>
        /// <param name="rot">The rotation to set the instance to</param>
        /// <param name="parent">An optional parent for the instance</param>
        /// <returns>
        /// The instance's Transform.
        ///
        /// If the Limit option was used for the PrefabPool associated with the
        /// passed prefab, then this method will return null if the limit is
        /// reached. You DO NOT need to test for null return values unless you
        /// used the limit option.
        /// </returns>
        public Transform Spawn(Transform prefab, Vector3 pos, Quaternion rot, Transform parent)
        {
            Transform inst;

            #region Use from Pool
            for (int i = 0; i < this._prefabPools.Count; i++)
            {
                // Determine if the prefab was ever used as explained in the docs
                //   I believe a comparison of two references is processor-cheap.
                if (this._prefabPools[i].prefabGO == prefab.gameObject)
                {
                    // Now we know the prefabPool for this prefab exists.
                    // Ask the prefab pool to setup and activate an instance.
                    // If there is no instance to spawn, a new one is instanced
                    inst = this._prefabPools[i].SpawnInstance(pos, rot);

                    // This only happens if the limit option was used for this
                    //   Prefab Pool.
                    if (inst == null)
                    {
                        return(null);
                    }

                    if (parent != null)    // User explicitly provided a parent
                    {
                        inst.SetParent(parent);
                    }
                    else if (!this.dontReparent && inst.parent != this.group)    // Auto organize?
                    {
                        // If a new instance was created, it won't be grouped
                        inst.SetParent(this.group);
                    }

                    // Add to internal list - holds only active instances in the pool
                    //   This isn't needed for Pool functionality. It is just done
                    //	 as a user-friendly feature which has been needed before.
                    this._spawned.Add(inst);

                    // Notify instance it was spawned so it can manage it's state
                    inst.gameObject.BroadcastMessage(
                        "OnSpawned",
                        this,
                        SendMessageOptions.DontRequireReceiver
                        );

                    // Done!
                    return(inst);
                }
            }
            #endregion Use from Pool


            #region New PrefabPool
            // The prefab wasn't found in any PrefabPools above. Make a new one
            PrefabPool newPrefabPool = new PrefabPool(prefab);
            this.CreatePrefabPool(newPrefabPool);

            // Spawn the new instance (Note: prefab already set in PrefabPool)
            inst = newPrefabPool.SpawnInstance(pos, rot);

            if (parent != null)    // User explicitly provided a parent
            {
                inst.SetParent(parent);
            }
            else  // Auto organize
            {
                inst.SetParent(this.group);
            }


            // New instances are active and must be added to the internal list
            this._spawned.Add(inst);
            #endregion New PrefabPool

            // Notify instance it was spawned so it can manage it's state
            inst.gameObject.BroadcastMessage(
                "OnSpawned",
                this,
                SendMessageOptions.DontRequireReceiver
                );

            // Done!
            return(inst);
        }
Example #12
0
        /// <description>
        ///	Spawns an instance or creates a new instance if none are available.
        ///	Either way, an instance will be set to the passed position and
        ///	rotation.
        ///
        /// Detailed Information:
        /// Checks the Data structure for an instance that was already created
        /// using the prefab. If the prefab has been used before, such as by
        /// setting it in the Unity Editor to preload instances, or just used
        /// before via this function, one of its instances will be used if one
        /// is available, or a new one will be created.
        ///
        /// If the prefab has never been used a new PrefabPool will be started
        /// with default options.
        ///
        /// To alter the options on a prefab pool, use the Unity Editor or see
        /// the documentation for the PrefabPool class and
        /// SpawnPool.SpawnPrefabPool()
        ///
        /// Broadcasts "OnSpawned" to the instance. Use this to manage states.
        ///
        /// An overload of this function has the same initial signature as Unity's
        /// Instantiate() that takes position and rotation. The return Type is different
        /// though. Unity uses and returns a GameObject reference. PoolManager
        /// uses and returns a Transform reference (or other supported type, such
        /// as AudioSource and ParticleSystem)
        /// </description>
        /// <param name="prefab">
        /// The prefab used to spawn an instance. Only used for reference if an
        /// instance is already in the pool and available for respawn.
        /// NOTE: Type = Transform
        /// </param>
        /// <param name="pos">The position to set the instance to</param>
        /// <param name="rot">The rotation to set the instance to</param>
        /// <param name="parent">An optional parent for the instance</param>
        /// <returns>
        /// The instance's Transform.
        ///
        /// If the Limit option was used for the PrefabPool associated with the
        /// passed prefab, then this method will return null if the limit is
        /// reached. You DO NOT need to test for null return values unless you
        /// used the limit option.
        /// </returns>
        public Transform Active(Transform prefab, Vector3 pos, Quaternion rot, Transform parent)
        {
            Transform inst;

            #region 若对象在预制池中
            for (int i = 0; i < this._prefabPools_List.Count; i++)
            {
                if (this._prefabPools_List[i].referenceOfPrefab == prefab.gameObject)
                {
                    //显示一个实例,若没有实例可以显示,就创建一个新的
                    inst = this._prefabPools_List[i].ActiveInstance(pos, rot);

                    //若开启了限制选项,返回空
                    if (inst == null)
                    {
                        return(null);
                    }

                    //通过参数设置父物体
                    if (parent != null)
                    {
                        inst.parent = parent;
                    }
                    else if (!this.thisNotFather && inst.parent != this.CloneFather)
                    {
                        //设置父物体
                        inst.parent = this.CloneFather;
                    }

                    //加入到显示列表
                    this._active_List.Add(inst);

                    // 广播信息
                    inst.gameObject.BroadcastMessage(
                        "OnSpawned",
                        this,
                        SendMessageOptions.DontRequireReceiver
                        );

                    return(inst);
                }
            }
            #endregion Use from Pool

            #region 若不在池中,创建新预制池对象
            PrefabPool newPrefabPool = new PrefabPool(prefab);
            this.CreatePrefabPool(newPrefabPool);

            //显示实例
            inst = newPrefabPool.ActiveInstance(pos, rot);

            //根据参数,设置父物体
            if (parent != null)
            {
                inst.parent = parent;
            }
            else
            {
                inst.parent = this.CloneFather;
            }


            // 加入显示列表
            this._active_List.Add(inst);
            #endregion New PrefabPool

            // 广播信息
            inst.gameObject.BroadcastMessage(
                "OnSpawned",
                this,
                SendMessageOptions.DontRequireReceiver
                );

            return(inst);
        }
Example #13
0
 public void CreatePrefabPool(PrefabPool prefabPool)
 {
 }