diff --git a/Assets/ObjectPool/Editor/PoolManagerEditor.cs b/Assets/ObjectPool/Editor/PoolManagerEditor.cs index 1217963..979cedc 100644 --- a/Assets/ObjectPool/Editor/PoolManagerEditor.cs +++ b/Assets/ObjectPool/Editor/PoolManagerEditor.cs @@ -1,5 +1,5 @@ using UnityEngine; -using System.Collections; +using ObjectPool.Scripts; using UnityEditor; namespace GameObjectPool @@ -14,7 +14,7 @@ public override void OnInspectorGUI() if (GUILayout.Button("Add Pool")) { - poolManager.m_pool.Add(new PoolSettings()); + poolManager.mPool.Add(new PoolSettings()); } if (GUILayout.Button("Regenerate pools")) diff --git a/Assets/ObjectPool/Example/Scenes/Example.unity b/Assets/ObjectPool/Example/Scenes/Example.unity index 1e1f680..d97796d 100644 --- a/Assets/ObjectPool/Example/Scenes/Example.unity +++ b/Assets/ObjectPool/Example/Scenes/Example.unity @@ -2817,20 +2817,19 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 0dda56d895cffe44dadc9670de012a1b, type: 3} m_Name: m_EditorClassIdentifier: - debug: 1 - m_pool: + mPool: - name: SpherePool prefab: {fileID: 1019533563834558, guid: a190bad6138ae9444a900486a95d3d30, type: 3} startingItemCount: 10 maxItemCount: 10 - parent: {fileID: 1906366004} + parent: {fileID: 0} allowUnrestrictedGrowth: 0 showAnalytics: 0 - name: CubePool prefab: {fileID: 1512229642624436, guid: 7aa29bc7804e6b94bb43136a04e2f70e, type: 3} startingItemCount: 10 maxItemCount: 10 - parent: {fileID: 1906366004} + parent: {fileID: 0} allowUnrestrictedGrowth: 1 showAnalytics: 0 showAnalytics: 0 diff --git a/Assets/ObjectPool/Example/Scripts/BenchMarker.cs b/Assets/ObjectPool/Example/Scripts/BenchMarker.cs new file mode 100644 index 0000000..3fef307 --- /dev/null +++ b/Assets/ObjectPool/Example/Scripts/BenchMarker.cs @@ -0,0 +1,49 @@ +using UnityEngine; + +namespace ObjectPool.Example.Scripts +{ + internal class BenchMarker : MonoBehaviour + { + #region Fields + private int _maxRuns; + private string _report; + private float[] _results; + private bool _runDiagnostics; + protected float runStart; + private float _total; + private int _totalRuns; + #endregion + + protected bool RunDiagnostics => _totalRuns < _maxRuns && _runDiagnostics; + + private void OnGUI() + { + if (_report != null) + GUI.Label( + new Rect(10, 90, 600, 20), + _report + ); + } + + protected void StartDiagnostics(int maxRuns) + { + _maxRuns = maxRuns; + _runDiagnostics = true; + _results = new float[maxRuns]; + _totalRuns = 0; + _total = 0; + } + + + protected void Run() + { + var t = Time.realtimeSinceStartup - runStart; + _results[_totalRuns] = t; + _total += _results[_totalRuns]; + _report = "Average runtime (" + (_totalRuns + 1) + " iterations): " + _total / _totalRuns + + " with a total runtime of " + _total; + _totalRuns += 1; + if (_totalRuns >= _maxRuns) _runDiagnostics = false; + } + } +} \ No newline at end of file diff --git a/Assets/ObjectPool/Example/Scripts/Benchmarker.cs.meta b/Assets/ObjectPool/Example/Scripts/BenchMarker.cs.meta similarity index 84% rename from Assets/ObjectPool/Example/Scripts/Benchmarker.cs.meta rename to Assets/ObjectPool/Example/Scripts/BenchMarker.cs.meta index f1780a9..97ff5a0 100644 --- a/Assets/ObjectPool/Example/Scripts/Benchmarker.cs.meta +++ b/Assets/ObjectPool/Example/Scripts/BenchMarker.cs.meta @@ -1,8 +1,7 @@ fileFormatVersion: 2 guid: 6b9ad2937fa2db4489af5863f635956b -timeCreated: 1522248767 -licenseType: Free MonoImporter: + externalObjects: {} serializedVersion: 2 defaultReferences: [] executionOrder: 0 diff --git a/Assets/ObjectPool/Example/Scripts/Benchmarker.cs b/Assets/ObjectPool/Example/Scripts/Benchmarker.cs deleted file mode 100644 index 7a6aef2..0000000 --- a/Assets/ObjectPool/Example/Scripts/Benchmarker.cs +++ /dev/null @@ -1,49 +0,0 @@ -using UnityEngine; - -namespace GameObjectPool -{ - class Benchmarker : MonoBehaviour - { - bool runDiagnostics; - float[] results; - int totalRuns; - int maxRuns; - string report; - float total; - protected float runstart; - - protected bool RunDiagnostics - { - get { return totalRuns < maxRuns && runDiagnostics; } - } - - protected void StartDiagnostics(int maxRuns) - { - this.maxRuns = maxRuns; - runDiagnostics = true; - results = new float[maxRuns]; - totalRuns = 0; - total = 0; - } - - - protected void Run() - { - float t = Time.realtimeSinceStartup - runstart; - results[totalRuns] = t; - total += results[totalRuns]; - report = "Average runtime (" + (totalRuns + 1) + " iterations): " + total / (float)totalRuns + " with a total runtime of " + total; - totalRuns += 1; - if (totalRuns >= maxRuns) runDiagnostics = false; - } - - void OnGUI() - { - if (report != null) - GUI.Label( - new Rect(10, 90, 600, 20), - report - ); - } - } -} diff --git a/Assets/ObjectPool/Example/Scripts/PoolDiagnostics.cs b/Assets/ObjectPool/Example/Scripts/PoolDiagnostics.cs index a55cd14..525b29b 100644 --- a/Assets/ObjectPool/Example/Scripts/PoolDiagnostics.cs +++ b/Assets/ObjectPool/Example/Scripts/PoolDiagnostics.cs @@ -1,28 +1,30 @@ +using ObjectPool.Scripts; using UnityEngine; -namespace GameObjectPool +namespace ObjectPool.Example.Scripts { - class PoolDiagnostics : Benchmarker + internal class PoolDiagnostics : BenchMarker { public string poolName = ""; - void Update() + private void Update() { if (Input.GetMouseButton(0)) StartDiagnostics(5000); if (RunDiagnostics) Run(); } - new protected void Run() + private new void Run() { - runstart = Time.realtimeSinceStartup; + runStart = Time.realtimeSinceStartup; var obj = PoolManager.Get(poolName); base.Run(); if (obj == null) return; - obj.transform.position = new Vector3( - Camera.main.ScreenToWorldPoint(Input.mousePosition).x, - Camera.main.ScreenToWorldPoint(Input.mousePosition).y, - 0 - ); + if (Camera.main != null) + obj.transform.position = new Vector3( + Camera.main.ScreenToWorldPoint(Input.mousePosition).x, + Camera.main.ScreenToWorldPoint(Input.mousePosition).y, + 0 + ); } } -} +} \ No newline at end of file diff --git a/Assets/ObjectPool/Example/Scripts/Shape.cs b/Assets/ObjectPool/Example/Scripts/Shape.cs index 144435f..c72df36 100644 --- a/Assets/ObjectPool/Example/Scripts/Shape.cs +++ b/Assets/ObjectPool/Example/Scripts/Shape.cs @@ -1,26 +1,26 @@ using UnityEngine; -namespace GameObjectPool +namespace ObjectPool.Example.Scripts { - class Shape : MonoBehaviour + internal class Shape : MonoBehaviour { public float timeOutSpeed = 0.2f; - private float timeout = 0; + private float _timeout; - void Awake() + private void Awake() { - timeout = 0; + _timeout = 0; } - void Update() + private void Update() { - timeout += Time.deltaTime * timeOutSpeed; + _timeout += Time.deltaTime * timeOutSpeed; - if (timeout >= 1f) + if (_timeout >= 1f) { - timeout = 0; + _timeout = 0; transform.gameObject.SetActive(false); } } } -} +} \ No newline at end of file diff --git a/Assets/ObjectPool/Example/Scripts/ShapeManager.cs b/Assets/ObjectPool/Example/Scripts/ShapeManager.cs index 53b088e..3ab5b1d 100644 --- a/Assets/ObjectPool/Example/Scripts/ShapeManager.cs +++ b/Assets/ObjectPool/Example/Scripts/ShapeManager.cs @@ -1,15 +1,16 @@ +using ObjectPool.Scripts; using UnityEngine; -namespace GameObjectPool +namespace ObjectPool.Example.Scripts { /// - /// This class is meant to demonstrate how to use an object pool. - /// Use the same techniques found in this class wherever you need to spawn a game object from the Object Pool. + /// This class is meant to demonstrate how to use an object pool. + /// Use the same techniques found in this class wherever you need to spawn a game object from the Object Pool. /// - class ShapeManager : MonoBehaviour + internal class ShapeManager : MonoBehaviour { - const string cubePool = "CubePool"; - const string spherePool = "SpherePool"; + private const string CubePool = "CubePool"; + private const string SpherePool = "SpherePool"; public GameObject spherePrefab; // Use the following code to add a pool at run-time (not recommended) @@ -29,29 +30,23 @@ private void Awake() */ /// - /// Listen for mouse clicks and get an object from the appropriate PoolManager. - /// After an object is returned from the PoolManager, it is passed to the SetPosition method. - /// These same techniques could be used for things such as FPS bullet spawners in an FPS game. + /// Listen for mouse clicks and get an object from the appropriate PoolManager. + /// After an object is returned from the PoolManager, it is passed to the SetPosition method. + /// These same techniques could be used for things such as FPS bullet spawners in an FPS game. /// - void Update() + private void Update() { - Vector3 location = new Vector3( + var location = new Vector3( Camera.main.ScreenToWorldPoint(Input.mousePosition).x, Camera.main.ScreenToWorldPoint(Input.mousePosition).y, 0 ); // On left mouse click, spawn a cube object from the cube pool. - if (Input.GetMouseButton(0)) - { - PoolManager.Get(cubePool, location, Random.rotation); - } + if (Input.GetMouseButton(0)) PoolManager.Get(CubePool, location, Random.rotation); // On right mouse click, spawn a sphere object from the sphere pool. - if (Input.GetMouseButton(1)) - { - PoolManager.Get(spherePool, location, Random.rotation); - } + if (Input.GetMouseButton(1)) PoolManager.Get(SpherePool, location, Random.rotation); } } -} +} \ No newline at end of file diff --git a/Assets/ObjectPool/Scripts/Pool.cs b/Assets/ObjectPool/Scripts/Pool.cs index 120405d..a3c930e 100644 --- a/Assets/ObjectPool/Scripts/Pool.cs +++ b/Assets/ObjectPool/Scripts/Pool.cs @@ -1,47 +1,20 @@ -using UnityEngine; using System.Collections.Generic; +using UnityEngine; -namespace GameObjectPool +namespace ObjectPool.Scripts { public class Pool : Queue { - PoolSettings settings; - List activeItems; + private List _activeItems; #region Properties - List ActiveItems - { - get - { - if (activeItems == null) activeItems = new List(); - return activeItems; - } - } - - public PoolSettings Settings - { - get { return settings; } - } - - public int TotalActive - { - get { return ActiveItems.Count; } - } - - public int TotalInPool - { - get { return Count; } - } - - bool GrowPool - { - get - { - return Count == 0 && (settings.allowUnrestrictedGrowth || TotalActive < settings.maxItemCount); - } - } - - bool CanDequeue => TotalInPool > 0; + private List ActiveItems => _activeItems ??= new List(); + private PoolSettings Settings { get; } + public int TotalActive => ActiveItems.Count; + public int TotalInPool => Count; + private bool GrowPool => + Count == 0 && (Settings.allowUnrestrictedGrowth || TotalActive < Settings.maxItemCount); + private bool CanDequeue => TotalInPool > 0; public GameObject Get { @@ -49,12 +22,10 @@ public GameObject Get { GameObject obj = null; if (CanDequeue) obj = Dequeue(); - if (obj == null) obj = (GrowPool) ? NewItem : null; - if (obj != null) - { - ActiveItems.Add(obj); - obj.SetActive(true); - } + if (obj == null) obj = GrowPool ? NewItem : null; + if (obj == null) return obj; + ActiveItems.Add(obj); + obj.SetActive(true); return obj; } } @@ -63,8 +34,7 @@ private GameObject NewItem { get { - var g = GameObject.Instantiate(settings.prefab); - g.transform.SetParent(settings.parent); + var g = Object.Instantiate(Settings.prefab, Settings.parent, true); g.AddComponent(); InitializePoolItem(g); g.SetActive(false); @@ -73,9 +43,9 @@ private GameObject NewItem } #endregion - public Pool(PoolSettings poolSettings) : base() + public Pool(PoolSettings poolSettings) { - settings = poolSettings; + Settings = poolSettings; InitializePool(); } @@ -83,35 +53,33 @@ private void InitializePoolItem(GameObject obj) { var pi = obj.GetComponent(); if (pi == null) return; - pi.name = settings.name; - pi.Pool = this; + pi.name = Settings.name; + pi.pool = this; } private bool GameObjectBelongsToThisPool(GameObject obj) { var pooledItem = obj.GetComponent(); - return pooledItem != null && pooledItem.name == settings.name; + return pooledItem != null && pooledItem.name == Settings.name; } private void FindExistingPoolItems() { - GameObject[] objects = Object.FindObjectsOfType(true); + var objects = Object.FindObjectsOfType(true); foreach (var obj in objects) - { if (GameObjectBelongsToThisPool(obj)) { InitializePoolItem(obj); Insert(obj); } - } } - public void InitializePool() + private void InitializePool() { FindExistingPoolItems(); - var max = settings.startingItemCount; - if (!settings.allowUnrestrictedGrowth && max > settings.maxItemCount) max = settings.maxItemCount; - for (int i = TotalInPool; i < max; i++) + var max = Settings.startingItemCount; + if (!Settings.allowUnrestrictedGrowth && max > Settings.maxItemCount) max = Settings.maxItemCount; + for (var i = TotalInPool; i < max; i++) Insert(NewItem); } @@ -122,7 +90,7 @@ private void Insert(GameObject obj) public void DeactivateAll() { - foreach (GameObject obj in ActiveItems) obj.SetActive(false); + foreach (var obj in ActiveItems) obj.SetActive(false); } public void Deactivate(GameObject obj) @@ -137,4 +105,4 @@ public void DestroyAll() foreach (var obj in this) Object.Destroy(obj); } } -} +} \ No newline at end of file diff --git a/Assets/ObjectPool/Scripts/PoolManager.cs b/Assets/ObjectPool/Scripts/PoolManager.cs index 5178cda..7f7b8d6 100644 --- a/Assets/ObjectPool/Scripts/PoolManager.cs +++ b/Assets/ObjectPool/Scripts/PoolManager.cs @@ -1,84 +1,76 @@ -using UnityEngine; using System.Collections.Generic; +using UnityEngine; -namespace GameObjectPool +namespace ObjectPool.Scripts { public class PoolManager : MonoBehaviour { #region Fields - const string ERROR_MISSING_MANAGER = "PoolManager script required."; - public bool debug = true; - public List m_pool = new List(); - public bool showAnalytics = false; - private static PoolManager instance; - private Dictionary pools; + public List mPool = new(); + public bool showAnalytics; + private Dictionary _pools; #endregion #region Properties - public static List PoolSettings - { - get { return Instance.m_pool; } - } - - private static PoolManager Instance + private static PoolManager Instance { get; set; } + private static Dictionary Pools { - get { return instance; } - } - - public static Dictionary Pools - { - get => Instance.pools ?? (Instance.pools = new Dictionary()); - private set => Instance.pools = value; + get => Instance._pools ?? (Instance._pools = new Dictionary()); + set => Instance._pools = value; } #endregion - void Start() + private void Start() { - if (instance == null) instance = this; + if (Instance == null) Instance = this; GeneratePools(false); } - public static void AddPool(PoolSettings settings) - { - PoolSettings.Add(settings); - Pools.Add(settings.name, new Pool(settings)); - } - - private static void PopulatePools() + /// + /// Display information about a PoolManager + /// + private void OnGUI() { - foreach (var settings in PoolSettings) + if (!showAnalytics) return; + for (var i = 0; i < mPool.Count; i++) { - if (!Pools.ContainsKey(settings.name)) - { - Pools.Add(settings.name, new Pool(settings)); - } + if (!mPool[i].showAnalytics) continue; + var poolName = mPool[i].name; + GUI.Label( + new Rect(10, 10 + i * 40, 400, 20), + poolName + ); + GUI.Label( + new Rect(10, 30 + i * 40, 400, 20), + "Available in Pool: " + TotalInPool(poolName) + " Active: " + TotalActive(poolName) + ); } } public static GameObject Get(string poolName, Vector3 position, Quaternion rotation, Transform parent) { - GameObject obj = Get(poolName, position, rotation); + var obj = Get(poolName, position, rotation); if (obj) obj.transform.SetParent(parent); return obj; } public static GameObject Get(string poolName, Vector3 position, Quaternion rotation) { - GameObject obj = Get(poolName, position); + var obj = Get(poolName, position); if (obj) obj.transform.rotation = rotation; return obj; } - public static GameObject Get(string poolName, Vector3 position) + private static GameObject Get(string poolName, Vector3 position) { - GameObject obj = Get(poolName); + var obj = Get(poolName); if (obj) obj.transform.position = position; return obj; } - + public static GameObject Get(string poolName, Transform transform) { - GameObject obj = Get(poolName); + var obj = Get(poolName); obj.transform.position = transform.position; obj.transform.rotation = transform.rotation; return obj; @@ -86,85 +78,50 @@ public static GameObject Get(string poolName, Transform transform) public static GameObject Get(string poolName) { - if (Pools.ContainsKey(poolName)) - { - return Instance.GetPool(poolName).Get; - } + if (Pools.ContainsKey(poolName)) return Instance.GetPool(poolName).Get; return null; } public static GameObject[] Get(string poolName, int total) { - GameObject[] objects = new GameObject[total]; - for (int i = 0; i < total; i++) - { - objects[i] = Instance.GetPool(poolName).Get; - } + var objects = new GameObject[total]; + for (var i = 0; i < total; i++) objects[i] = Instance.GetPool(poolName).Get; return objects; } - public Pool GetPool(string poolName) => Pools[poolName]; + private Pool GetPool(string poolName) + { + return Pools[poolName]; + } - public static int TotalInPool(string poolName) + private static int TotalInPool(string poolName) { var pool = Instance.GetPool(poolName); if (pool != null) return pool.TotalInPool; return 0; } - public static int TotalActive(string poolName) + private static int TotalActive(string poolName) { var pool = Instance.GetPool(poolName); if (pool != null) return pool.TotalActive; return 0; } - /// - /// Display information about a PoolManager - /// - void OnGUI() - { - if (showAnalytics) - { - for (int i = 0; i < m_pool.Count; i++) - { - if (m_pool[i].showAnalytics) - { - string name = m_pool[i].name; - GUI.Label( - new Rect(10, 10 + (i * 40), 400, 20), - name - ); - GUI.Label( - new Rect(10, 30 + (i * 40), 400, 20), - "Available in Pool: " + TotalInPool(name) + " Active: " + TotalActive(name) - ); - } - } - } - } - public void GeneratePools(bool doDestroy = true) { - if (instance == null) instance = this; - - GameObject[] objects = FindObjectsOfType(true); + if (Instance == null) Instance = this; + + var objects = FindObjectsOfType(true); if (doDestroy) - { foreach (var obj in objects) - { - if (obj.GetComponent() != null) DestroyImmediate(obj); - } - } + if (obj.GetComponent() != null) + DestroyImmediate(obj); Pools = new Dictionary(); - foreach (var settings in m_pool) - { + foreach (var settings in mPool) if (!Pools.ContainsKey(settings.name)) - { Pools.Add(settings.name, new Pool(settings)); - } - } } } -} +} \ No newline at end of file diff --git a/Assets/ObjectPool/Scripts/PoolSettings.cs b/Assets/ObjectPool/Scripts/PoolSettings.cs index c4a8923..ae6bd18 100644 --- a/Assets/ObjectPool/Scripts/PoolSettings.cs +++ b/Assets/ObjectPool/Scripts/PoolSettings.cs @@ -1,10 +1,9 @@ -using UnityEngine; using System; -using System.Collections; +using UnityEngine; -namespace GameObjectPool +namespace ObjectPool.Scripts { - [System.Serializable] + [Serializable] public class PoolSettings { public string name; @@ -12,7 +11,7 @@ public class PoolSettings public int startingItemCount; public int maxItemCount; public Transform parent; - public bool allowUnrestrictedGrowth = false; + public bool allowUnrestrictedGrowth; public bool showAnalytics; } -} +} \ No newline at end of file diff --git a/Assets/ObjectPool/Scripts/PooledItem.cs b/Assets/ObjectPool/Scripts/PooledItem.cs index e53d613..b50ac76 100644 --- a/Assets/ObjectPool/Scripts/PooledItem.cs +++ b/Assets/ObjectPool/Scripts/PooledItem.cs @@ -1,22 +1,14 @@ using UnityEngine; -namespace GameObjectPool +namespace ObjectPool.Scripts { public class PooledItem : MonoBehaviour { - public string name; + public new string name; + public Pool pool; + private Rigidbody Rigidbody { get; set; } - public Pool Pool; - - public Rigidbody Rigidbody { get; private set; } - - void OnDisable() - { - if (gameObject == null) return; - Pool?.Deactivate(gameObject); - } - - void OnEnable() + private void OnEnable() { if (Rigidbody == null) Rigidbody = GetComponent(); if (Rigidbody != null) @@ -25,5 +17,11 @@ void OnEnable() Rigidbody.angularVelocity = Vector3.zero; } } + + private void OnDisable() + { + if (gameObject == null) return; + pool?.Deactivate(gameObject); + } } -} +} \ No newline at end of file