Description:
Currently, the UnitySingleton implementation does not persist singleton instances across scene loads when they are children of other GameObjects. This limitation arises because DontDestroyOnLoad only works for root GameObjects; it does not prevent destruction of child objects when their parent is destroyed during a scene load.
Proposed Solution:
Introduce a public boolean property, UnparentOnAwake, to the Singleton class. When set to true, this property will unparent the singleton GameObject during the OnInitializing method, ensuring it becomes a root GameObject and is not destroyed during scene transitions.
Implementation:
public abstract class PersistentMonoSingleton<T> : MonoSingleton<T> where T : MonoSingleton<T>
{
/// <summary>
/// if this is true, this singleton will auto detach if it finds itself parented on awake
/// </summary>
[Tooltip("if this is true, this singleton will auto detach if it finds itself parented on awake")]
[SerializeField] private bool UnparentOnAwake = true;
#region Protected Methods
protected override void OnInitializing()
{
if (UnparentOnAwake) {
transform.SetParent(null);
}
base.OnInitializing();
if (Application.isPlaying)
{
DontDestroyOnLoad(gameObject);
}
}
#endregion
}
Use Case:
In the video "Project Initialization - Unity Architecture," Tarodev, recommends using a preload scene to initialize all the systems your game uses, such as GameManager, SoundManager, etc. The suggested approach includes the following code:
using UnityEngine;
public static class Bootstrapper {
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
public static void Execute() {
Object.DontDestroyOnLoad(Object.Instantiate(Resources.Load("Systems")));
}
}
This code aims to load a single prefab named "Systems" that contains child GameObjects handling various behaviors. However, with the current UnitySingleton implementation, if these child GameObjects are singletons, they cannot persist across scenes because DontDestroyOnLoad does not work on child objects. By implementing the proposed UnparentOnAwake property, each system can be its own prefab, set as a child of the "Systems" GameObject, and still persist across scene loads.
Benefits:
- Allows singleton instances to persist across scenes, even when initially parented to other GameObjects.
- Provides flexibility for developers to decide whether the singleton should be unparented or not via the
UnparentOnAwake property.
- Simplifies the initialization process by allowing multiple systems to be organized under a single prefab, aligning with the preload scene approach recommended in the video.
Description:
Currently, the UnitySingleton implementation does not persist singleton instances across scene loads when they are children of other GameObjects. This limitation arises because
DontDestroyOnLoadonly works for root GameObjects; it does not prevent destruction of child objects when their parent is destroyed during a scene load.Proposed Solution:
Introduce a public boolean property,
UnparentOnAwake, to the Singleton class. When set totrue, this property will unparent the singleton GameObject during theOnInitializingmethod, ensuring it becomes a root GameObject and is not destroyed during scene transitions.Implementation:
Use Case:
In the video "Project Initialization - Unity Architecture," Tarodev, recommends using a preload scene to initialize all the systems your game uses, such as GameManager, SoundManager, etc. The suggested approach includes the following code:
This code aims to load a single prefab named "Systems" that contains child GameObjects handling various behaviors. However, with the current UnitySingleton implementation, if these child GameObjects are singletons, they cannot persist across scenes because
DontDestroyOnLoaddoes not work on child objects. By implementing the proposedUnparentOnAwakeproperty, each system can be its own prefab, set as a child of the "Systems" GameObject, and still persist across scene loads.Benefits:
UnparentOnAwakeproperty.