ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Object Pool Manager for Dynamic Game Assets

C# (Unity)

Goal -- WPM

Ready
Exercise Algorithm Area
1using System.Collections.Generic;
2using UnityEngine;
3
4public class PooledObject : MonoBehaviour
5{
6public ObjectPool Pool { get; set; }
7
8public void ReturnToPool()
9{
10if (Pool != null)
11{
12Pool.ReturnObject(this);
13}
14else
15{
16Debug.LogWarning("PooledObject returned to pool but its pool reference is null. Destroying.");
17Destroy(gameObject);
18}
19}
20}
21
22public class ObjectPool
23{
24private GameObject prefab;
25private List<PooledObject> activeObjects = new List<PooledObject>();
26private Stack<PooledObject> inactiveObjects = new Stack<PooledObject>();
27private Transform parentTransform;
28
29public ObjectPool(GameObject prefab, int initialSize, Transform parentTransform)
30{
31this.prefab = prefab;
32this.parentTransform = parentTransform;
33
34for (int i = 0; i < initialSize; i++)
35{
36CreateNewObject();
37}
38}
39
40private PooledObject CreateNewObject()
41{
42GameObject instance = GameObject.Instantiate(prefab, parentTransform);
43instance.SetActive(false);
44var pooledObj = instance.AddComponent<PooledObject>();
45pooledObj.Pool = this;
46inactiveObjects.Push(pooledObj);
47return pooledObj;
48}
49
50public PooledObject GetObject()
51{
52if (inactiveObjects.Count == 0)
53{
54Debug.LogWarning("Object pool is empty. Creating a new object.");
55return CreateNewObject();
56}
57
58PooledObject obj = inactiveObjects.Pop();
59obj.gameObject.SetActive(true);
60activeObjects.Add(obj);
61return obj;
62}
63
64public void ReturnObject(PooledObject obj)
65{
66if (obj == null || obj.Pool != this)
67{
68Debug.LogWarning("Attempted to return an invalid or already pooled object. Destroying.");
69if (obj != null) Destroy(obj.gameObject);
70return;
71}
72
73if (activeObjects.Contains(obj))
74{
75obj.gameObject.SetActive(false);
76inactiveObjects.Push(obj);
77activeObjects.Remove(obj);
78}
79else
80{
81Debug.LogWarning("Object was not found in the active list. It might have been destroyed or already returned. Destroying.");
82Destroy(obj.gameObject);
83}
84}
85
86public void ClearPool()
87{
88foreach (var obj in activeObjects)
89{
90if (obj != null) Destroy(obj.gameObject);
91}
92activeObjects.Clear();
93
94while (inactiveObjects.Count > 0)
95{
96var obj = inactiveObjects.Pop();
97if (obj != null) Destroy(obj.gameObject);
98}
99}
100}
101
102public class ObjectPoolManager : MonoBehaviour
103{
104private Dictionary<GameObject, ObjectPool> pools = new Dictionary<GameObject, ObjectPool>();
105public int initialPoolSize = 10;
106public Transform poolContainer;
107
108void Awake()
109{
110if (poolContainer == null)
111{
112poolContainer = new GameObject("ObjectPoolContainer").transform;
113poolContainer.SetParent(this.transform);
114}
115}
116
117public void RegisterPool(GameObject prefab)
118{
119if (!pools.ContainsKey(prefab))
120{
121pools.Add(prefab, new ObjectPool(prefab, initialPoolSize, poolContainer));
122}
123}
124
125public GameObject GetObject(GameObject prefab)
126{
127if (!pools.ContainsKey(prefab))
128{
129Debug.LogWarning("Prefab not found in pools. Registering it first.");
130RegisterPool(prefab);
131}
132
133PooledObject pooledObj = pools[prefab].GetObject();
134return pooledObj.gameObject;
135}
136
137public void ReturnObject(GameObject obj)
138{
139if (obj == null) return;
140
141var pooledObj = obj.GetComponent<PooledObject>();
142if (pooledObj != null)
143{
144pooledObj.ReturnToPool();
145}
146else
147{
148Debug.LogWarning("Object is not a pooled object. Destroying.");
149Destroy(obj);
150}
151}
152
153void OnDestroy()
154{
155// Clean up all pooled objects when the manager is destroyed
156foreach (var pool in pools.Values)
157{
158pool.ClearPool();
159}
160pools.Clear();
161}
162}
Algorithm description viewbox

Object Pool Manager for Dynamic Game Assets

Algorithm description:

This C# code provides an `ObjectPoolManager` for Unity, designed to efficiently manage frequently used game objects like projectiles or enemies. It utilizes an `ObjectPool` class to pre-allocate and reuse instances, reducing the overhead of `Instantiate` and `Destroy` calls. The system ensures that objects are activated and deactivated correctly, and handles cases where the pool might need to grow or when invalid objects are returned.

Algorithm explanation:

The `ObjectPoolManager` acts as a central hub, maintaining a dictionary of `ObjectPool` instances, keyed by their prefabs. Each `ObjectPool` manages a collection of `PooledObject` instances, using a `Stack` for inactive objects and a `List` for active ones. When `GetObject` is called, it either retrieves an inactive object from the stack or creates a new one if the pool is empty. `ReturnObject` deactivates the object and pushes it back onto the inactive stack. The `ClearPool` method ensures all managed objects are destroyed on cleanup. Time complexity for `GetObject` and `ReturnObject` is O(1) on average, assuming stack/list operations are amortized O(1). Space complexity is O(N*S) where N is the number of unique prefabs and S is the initial pool size, plus any dynamically created objects. Edge cases include empty pools, returning null objects, returning objects not managed by the pool, and ensuring proper cleanup via `OnDestroy`.

Pseudocode:

Class PooledObject (MonoBehaviour):
  Pool reference
  Method ReturnToPool():
    If Pool is not null, call Pool.ReturnObject(this)
    Else, destroy GameObject

Class ObjectPool:
  Prefab
  ActiveObjects list
  InactiveObjects stack
  ParentTransform

  Constructor(prefab, initialSize, parentTransform):
    Initialize members
    Loop initialSize times:
      Call CreateNewObject()

  Method CreateNewObject():
    Instantiate prefab, set parent, set active to false
    Add PooledObject component, set its Pool reference
    Push new object onto InactiveObjects stack
    Return new object

  Method GetObject():
    If InactiveObjects is empty:
      Log warning, call CreateNewObject(), return it
    Pop object from InactiveObjects stack
    Set object active to true
    Add object to ActiveObjects list
    Return object

  Method ReturnObject(obj):
    If obj is null or its Pool reference is incorrect:
      Log warning, destroy GameObject if not null
      Return
    If obj is in ActiveObjects:
      Set obj active to false
      Push obj onto InactiveObjects stack
      Remove obj from ActiveObjects list
    Else:
      Log warning, destroy GameObject

  Method ClearPool():
    For each active object, destroy its GameObject
    Clear ActiveObjects list
    While InactiveObjects is not empty, pop and destroy GameObject

Class ObjectPoolManager (MonoBehaviour):
  Pools dictionary (prefab -> ObjectPool)
  InitialPoolSize
  PoolContainer transform

  Awake():
    Create PoolContainer if null

  Method RegisterPool(prefab):
    If prefab not in Pools, create new ObjectPool and add to dictionary

  Method GetObject(prefab):
    If prefab not in Pools, call RegisterPool(prefab)
    Get ObjectPool for prefab
    Call its GetObject() method
    Return the GameObject

  Method ReturnObject(obj):
    If obj is null, return
    Get PooledObject component from obj
    If pooledObj is not null, call pooledObj.ReturnToPool()
    Else, destroy obj

  OnDestroy():
    For each pool in Pools.Values:
      Call pool.ClearPool()
    Clear Pools dictionary