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); }
/// <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(); } }
/// <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); }); }
/// <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); }
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); }
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(); }
/// <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(); } }
/// <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)); } }
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); }
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(); } }
/// <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); }
/// <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); }
public void CreatePrefabPool(PrefabPool prefabPool) { }