-
Introduction:
I was Loading my single-tons in the first scene,
But StackOverflow exception occured.
(on a function with name containing ‘enter’ and ‘main’ and ‘thread’)
And then, My engine suddenly quit. -
Reproducible codes :
StartLoad.cs
using UnityEngine;
using UnityEngine.SceneManagement;
public class StartLoad : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
GameObject.Find("ObjectPoolManager").GetComponent<ObjectPoolManager>().LoadScene("MainScreen");
}
}
ObjectPool.cs : Used In ObjectPoolManager.cs
using UnityEngine;
using System.Collections.Generic;
[System.Serializable]
public class ObjectPool<Type> : IPool where Type : IPoolable
{
[SerializeField]
private List<GameObject> DisabledGameObjects;
[SerializeField]
private List<GameObject> EnabledGameObjects;
[SerializeField]
private int capacity;
[SerializeField]
private bool isDontDestroyOnLoad;
public ObjectPool(int capacity = 100, bool isDontDestroyOnLoad = true)
{
this.capacity = capacity; DisabledGameObjects = new List<GameObject>(); EnabledGameObjects = new List<GameObject>(); this.isDontDestroyOnLoad = isDontDestroyOnLoad;
}
public GameObject Instantiate(GameObject original, Transform parent)
{
GameObject gameObject;
if (DisabledGameObjects.Count == 0)
{
if (EnabledGameObjects.Count < capacity)
{
gameObject = Object.Instantiate(original, parent);
}
else
{
throw new System.Exception($"ObjectPool is Full.\ncapacity : {capacity}");
}
}
else
{
gameObject = DisabledGameObjects[0];
DisabledGameObjects.Remove(gameObject);
gameObject.SetActive(true);
gameObject.GetComponent<Type>().Start();
}
EnabledGameObjects.Add(gameObject);
gameObject.transform.SetParent(parent);
return gameObject;
}
public void Destroy(GameObject gameObject)
{
EnabledGameObjects.Remove(gameObject);
DisabledGameObjects.Add(gameObject);
gameObject.transform.SetParent(null);
if (isDontDestroyOnLoad)
{
Object.DontDestroyOnLoad(gameObject);
}
gameObject.SetActive(false);
}
public void DestroyEverything()
{
foreach(GameObject gameObject in EnabledGameObjects)
{
Destroy(gameObject);
}
}
}
public interface IPoolable
{
public void Start();
}
public interface IPool
{
public GameObject Instantiate(GameObject original, Transform parent);
public void Destroy(GameObject gameObject);
public void DestroyEverything();
}
ObjectPoolManager.cs
using System.Collections.Generic;
using UnityEngine;
public class ObjectPoolManager : MonoBehaviour
{
[SerializeField]
private List<IPool> objectPools = new List<IPool>();
[SerializeField]
private List<string> poolNames = new List<string>();
void Start()
{
DontDestroyOnLoad(gameObject);
}
// Update is called once per frame
void Update()
{
}
void OnEnable()
{
}
public IPool newPool<T>(string name) where T : IPoolable
{
IPool pool = new ObjectPool<T>();
objectPools.Add(pool);
poolNames.Add(name);
return pool;
}
public IPool GetPool(string name)
{
for (int i = 0; i < poolNames.Count; i++)
{
if (poolNames[i] == name)
{
return objectPools[i];
}
}
return null;
}
public IPool GetOrNewPool<T>(string name) where T : IPoolable
{
IPool pool = GetPool(name);
if (pool == null)
{
return newPool<T>(name);
}
else
{
return pool;
}
}
public void LoadScene(string scene)
{
foreach (IPool pool in objectPools)
{
pool.DestroyEverything();
}
GameObject.Find("ObjectPoolManager").GetComponent<ObjectPoolManager>().LoadScene(scene);
}
}
Although, there is my fault, putting function in Update()