feat: spawning particles with object pooling
This commit is contained in:
parent
858e49e1d9
commit
efac0019ba
14 changed files with 235 additions and 21 deletions
|
@ -112,3 +112,4 @@ MonoBehaviour:
|
|||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
animator: {fileID: 1908639354391246343}
|
||||
particleAnimation: {fileID: 11400000, guid: 3aa2da34174b2354d94d7764f109d1c0, type: 2}
|
||||
|
|
3
Assets/Scripts/Pooling.meta
Normal file
3
Assets/Scripts/Pooling.meta
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a956b08a87cc495ca71443493064210d
|
||||
timeCreated: 1713519317
|
5
Assets/Scripts/Pooling/IPooledObject.cs
Normal file
5
Assets/Scripts/Pooling/IPooledObject.cs
Normal file
|
@ -0,0 +1,5 @@
|
|||
namespace Pooling {
|
||||
public interface IPooledObject {
|
||||
void OnObjectSpawn();
|
||||
}
|
||||
}
|
3
Assets/Scripts/Pooling/IPooledObject.cs.meta
Normal file
3
Assets/Scripts/Pooling/IPooledObject.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 75e27a032d064219bd1f9314952bdbb8
|
||||
timeCreated: 1713534220
|
152
Assets/Scripts/Pooling/Pooler.cs
Normal file
152
Assets/Scripts/Pooling/Pooler.cs
Normal file
|
@ -0,0 +1,152 @@
|
|||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Pooling {
|
||||
public class Pooler : MonoBehaviour {
|
||||
private static Pooler _instance;
|
||||
|
||||
public static Pooler Instance {
|
||||
get {
|
||||
if (_instance != null)
|
||||
return _instance;
|
||||
|
||||
_instance = FindObjectOfType<Pooler>();
|
||||
if (_instance != null)
|
||||
return _instance;
|
||||
|
||||
GameObject obj = new("[Object Pool]");
|
||||
_instance = obj.AddComponent<Pooler>();
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<GameObject> _tempList = new();
|
||||
|
||||
private Dictionary<GameObject, List<GameObject>> _pooledObjects = new();
|
||||
private Dictionary<GameObject, GameObject> _spawnedObjects = new();
|
||||
|
||||
public static void CreatePool<T>(T prefab, int initialPoolSize) where T : Component {
|
||||
CreatePool(prefab.gameObject, initialPoolSize);
|
||||
}
|
||||
|
||||
public static void CreatePool(GameObject prefab, int initialPoolSize) {
|
||||
if (prefab == null || Instance._pooledObjects.ContainsKey(prefab))
|
||||
return;
|
||||
|
||||
List<GameObject> list = new();
|
||||
Instance._pooledObjects.Add(prefab, list);
|
||||
|
||||
if (initialPoolSize <= 0) return;
|
||||
|
||||
bool active = prefab.activeSelf;
|
||||
prefab.SetActive(false);
|
||||
Transform parent = Instance.transform;
|
||||
while (list.Count < initialPoolSize) {
|
||||
GameObject obj = Instantiate(prefab, parent);
|
||||
list.Add(obj);
|
||||
}
|
||||
prefab.SetActive(active);
|
||||
}
|
||||
|
||||
public static T Spawn<T>(T prefab, Transform parent, Vector3 position, Quaternion rotation)
|
||||
where T : Component =>
|
||||
Spawn(prefab.gameObject, parent, position, rotation).GetComponent<T>();
|
||||
|
||||
public static T Spawn<T>(T prefab, Vector3 position, Quaternion rotation) where T : Component =>
|
||||
Spawn(prefab.gameObject, null, position, rotation).GetComponent<T>();
|
||||
|
||||
public static T Spawn<T>(T prefab, Transform parent, Vector3 position) where T : Component =>
|
||||
Spawn(prefab.gameObject, parent, position, Quaternion.identity).GetComponent<T>();
|
||||
|
||||
public static T Spawn<T>(T prefab, Vector3 position) where T : Component =>
|
||||
Spawn(prefab.gameObject, null, position, Quaternion.identity).GetComponent<T>();
|
||||
|
||||
public static T Spawn<T>(T prefab, Transform parent) where T : Component =>
|
||||
Spawn(prefab.gameObject, parent, Vector3.zero, Quaternion.identity).GetComponent<T>();
|
||||
|
||||
public static T Spawn<T>(T prefab) where T : Component =>
|
||||
Spawn(prefab.gameObject, null, Vector3.zero, Quaternion.identity).GetComponent<T>();
|
||||
|
||||
public static GameObject Spawn(GameObject prefab, Transform parent, Vector3 position) =>
|
||||
Spawn(prefab, parent, position, Quaternion.identity);
|
||||
|
||||
public static GameObject Spawn(GameObject prefab, Vector3 position, Quaternion rotation) =>
|
||||
Spawn(prefab, null, position, rotation);
|
||||
|
||||
public static GameObject Spawn(GameObject prefab, Transform parent) =>
|
||||
Spawn(prefab, parent, Vector3.zero, Quaternion.identity);
|
||||
|
||||
public static GameObject Spawn(GameObject prefab, Vector3 position) =>
|
||||
Spawn(prefab, null, position, Quaternion.identity);
|
||||
|
||||
public static GameObject Spawn(GameObject prefab) =>
|
||||
Spawn(prefab, null, Vector3.zero, Quaternion.identity);
|
||||
|
||||
public static GameObject Spawn(GameObject prefab, Transform parent, Vector3 position, Quaternion rotation) {
|
||||
List<GameObject> list;
|
||||
Transform trans;
|
||||
GameObject obj;
|
||||
|
||||
if (Instance._pooledObjects.TryGetValue(prefab, out list)) {
|
||||
obj = null;
|
||||
if (list.Count > 0) {
|
||||
while (!obj && list.Count > 0) {
|
||||
obj = list[0];
|
||||
list.RemoveAt(0);
|
||||
}
|
||||
if (obj != null) {
|
||||
trans = obj.transform;
|
||||
trans.parent = parent;
|
||||
trans.localPosition = position;
|
||||
trans.localRotation = rotation;
|
||||
obj.SetActive(true);
|
||||
Instance._spawnedObjects.Add(obj, prefab);
|
||||
TryCallPooledObject(obj);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
obj = Instantiate(prefab);
|
||||
trans = obj.transform;
|
||||
trans.parent = parent;
|
||||
trans.localPosition = position;
|
||||
trans.localRotation = rotation;
|
||||
Instance._spawnedObjects.Add(obj, prefab);
|
||||
TryCallPooledObject(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
obj = Instantiate(prefab);
|
||||
trans = obj.transform;
|
||||
trans.parent = parent;
|
||||
trans.localPosition = position;
|
||||
trans.localRotation = rotation;
|
||||
TryCallPooledObject(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
private static void TryCallPooledObject(GameObject obj) {
|
||||
if(obj.TryGetComponent(out IPooledObject pooledObject))
|
||||
pooledObject.OnObjectSpawn();
|
||||
}
|
||||
|
||||
public static void Recycle<T>(T obj) where T : Component {
|
||||
Recycle(obj.gameObject);
|
||||
}
|
||||
|
||||
public static void Recycle(GameObject obj) {
|
||||
GameObject prefab;
|
||||
if (Instance._spawnedObjects.TryGetValue(obj, out prefab))
|
||||
Recycle(obj, prefab);
|
||||
else
|
||||
Destroy(obj);
|
||||
}
|
||||
|
||||
private static void Recycle(GameObject obj, GameObject prefab) {
|
||||
Instance._pooledObjects[prefab].Add(obj);
|
||||
Instance._spawnedObjects.Remove(obj);
|
||||
obj.transform.parent = Instance.transform;
|
||||
obj.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
3
Assets/Scripts/Pooling/Pooler.cs.meta
Normal file
3
Assets/Scripts/Pooling/Pooler.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b8fc72fe7498488581bb9ecd15cdb057
|
||||
timeCreated: 1713519317
|
39
Assets/Scripts/Pooling/PoolerExtensions.cs
Normal file
39
Assets/Scripts/Pooling/PoolerExtensions.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace Pooling {
|
||||
public static class PoolerExtensions {
|
||||
public static void CreatePool<T>(this T prefab) where T : Component =>
|
||||
Pooler.CreatePool(prefab, 0);
|
||||
public static void CreatePool<T>(this T prefab, int initialPoolSize) where T : Component =>
|
||||
Pooler.CreatePool(prefab, initialPoolSize);
|
||||
public static void CreatePool(this GameObject prefab) =>
|
||||
Pooler.CreatePool(prefab, 0);
|
||||
public static void CreatePool(this GameObject prefab, int initialPoolSize) =>
|
||||
Pooler.CreatePool(prefab, initialPoolSize);
|
||||
|
||||
public static T Spawn<T>(this T prefab, Transform parent, Vector3 position, Quaternion rotation) where T : Component =>
|
||||
Pooler.Spawn(prefab, parent, position, rotation);
|
||||
public static T Spawn<T>(this T prefab, Vector3 position, Quaternion rotation) where T : Component =>
|
||||
Pooler.Spawn(prefab, null, position, rotation);
|
||||
public static T Spawn<T>(this T prefab, Transform parent, Vector3 position) where T : Component =>
|
||||
Pooler.Spawn(prefab, parent, position, Quaternion.identity);
|
||||
public static T Spawn<T>(this T prefab, Vector3 position) where T : Component =>
|
||||
Pooler.Spawn(prefab, null, position, Quaternion.identity);
|
||||
public static T Spawn<T>(this T prefab, Transform parent) where T : Component =>
|
||||
Pooler.Spawn(prefab, parent, Vector3.zero, Quaternion.identity);
|
||||
public static T Spawn<T>(this T prefab) where T : Component =>
|
||||
Pooler.Spawn(prefab, null, Vector3.zero, Quaternion.identity);
|
||||
public static GameObject Spawn(this GameObject prefab, Transform parent, Vector3 position, Quaternion rotation) =>
|
||||
Pooler.Spawn(prefab, parent, position, rotation);
|
||||
public static GameObject Spawn(this GameObject prefab, Vector3 position, Quaternion rotation) =>
|
||||
Pooler.Spawn(prefab, null, position, rotation);
|
||||
public static GameObject Spawn(this GameObject prefab, Transform parent, Vector3 position) =>
|
||||
Pooler.Spawn(prefab, parent, position, Quaternion.identity);
|
||||
public static GameObject Spawn(this GameObject prefab, Vector3 position) =>
|
||||
Pooler.Spawn(prefab, null, position, Quaternion.identity);
|
||||
public static GameObject Spawn(this GameObject prefab, Transform parent) =>
|
||||
Pooler.Spawn(prefab, parent, Vector3.zero, Quaternion.identity);
|
||||
public static GameObject Spawn(this GameObject prefab) =>
|
||||
Pooler.Spawn(prefab, null, Vector3.zero, Quaternion.identity);
|
||||
}
|
||||
}
|
3
Assets/Scripts/Pooling/PoolerExtensions.cs.meta
Normal file
3
Assets/Scripts/Pooling/PoolerExtensions.cs.meta
Normal file
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ea3218d098d947b6b008751f3c2cd8f4
|
||||
timeCreated: 1713522613
|
3
Assets/Scripts/Pooling/SantJordi.Pooling.asmdef
Normal file
3
Assets/Scripts/Pooling/SantJordi.Pooling.asmdef
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"name": "SantJordi.Pooling"
|
||||
}
|
7
Assets/Scripts/Pooling/SantJordi.Pooling.asmdef.meta
Normal file
7
Assets/Scripts/Pooling/SantJordi.Pooling.asmdef.meta
Normal file
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 1e89d5d1db358ce43890b8310d696377
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -8,7 +8,8 @@
|
|||
"GUID:1220ccfff01d26041a9bb8cd7ae584af",
|
||||
"GUID:58f2f98b0cec4e74998cb65ad59190b4",
|
||||
"GUID:0c752da273b17c547ae705acf0f2adf2",
|
||||
"GUID:a8b14a26d6924d6bb65739ca56ae8187"
|
||||
"GUID:a8b14a26d6924d6bb65739ca56ae8187",
|
||||
"GUID:1e89d5d1db358ce43890b8310d696377"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
using System;
|
||||
using Pooling;
|
||||
using Presenter;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using Animation = FramedAnimator.Animation;
|
||||
using Animator = FramedAnimator.Animator;
|
||||
|
||||
namespace View.Scene {
|
||||
public class GrowParticle : MonoBehaviour {
|
||||
public class GrowParticle : MonoBehaviour, IPooledObject {
|
||||
[SerializeField] private Animator animator;
|
||||
[SerializeField] private Animation particleAnimation;
|
||||
|
||||
private void Start() {
|
||||
animator.OnAnimationEnd += _ => Destroy(gameObject);
|
||||
public void OnObjectSpawn() {
|
||||
animator.ChangeAnimation(particleAnimation);
|
||||
animator.OnAnimationEnd += _ => Pooler.Recycle(gameObject);
|
||||
animator.PlayUntil(1f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Pooling;
|
||||
using Presenter;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
@ -9,9 +10,13 @@ namespace View.Scene {
|
|||
[SerializeField] private Transform growParticlePositions;
|
||||
[SerializeField, Range(0, 180)] private float angleRange;
|
||||
|
||||
private void Awake() {
|
||||
growParticle.CreatePool();
|
||||
}
|
||||
|
||||
public void OnInputReceived() {
|
||||
float randomRotation = Random.Range(-angleRange / 2f, angleRange / 2f);
|
||||
Instantiate(growParticle, growParticlePositions.position, Quaternion.Euler(0f, 0f, randomRotation));
|
||||
growParticle.Spawn(growParticlePositions.position, Quaternion.Euler(0, 0, randomRotation));
|
||||
}
|
||||
|
||||
private void OnDrawGizmosSelected() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue