using System.Threading.Tasks; using UnityEngine; namespace Bootstrap { /// /// Settings for the custom boot process /// public class CustomBootSettings : ScriptableObject { /// /// A list of prefabs which should be loaded during boot /// public GameObject[] BootPrefabs; /// /// Internal references to instances of the prefabs from /// private GameObject[] Instances; /// /// Runtime container object which acts as the parent for any BootPrefab instances /// private GameObject RuntimeContainer; /// /// Initialise the boot settings object asynchronously, loading each prefab in /// public async Task Initialise() { RuntimeContainer = new GameObject($"{name}_Container"); DontDestroyOnLoad(RuntimeContainer); Instances = new GameObject[BootPrefabs.Length]; // Calculate total prefabs for progress tracking int totalPrefabs = BootPrefabs.Length; float progressPerPrefab = totalPrefabs > 0 ? 1f / totalPrefabs : 1f; float currentProgress = 0f; for (var i = 0; i < BootPrefabs.Length; i++) { if (!BootPrefabs[i]) { // Report incremental progress even for null prefabs currentProgress = (i + 1) * progressPerPrefab; CustomBoot.UpdateProgress(currentProgress); continue; } var instance = GameObject.InstantiateAsync(BootPrefabs[i], RuntimeContainer.transform); while (!instance.isDone) { // Report partial progress while waiting float progressInStep = instance.progress * progressPerPrefab; float overallProgress = i * progressPerPrefab + progressInStep; CustomBoot.UpdateProgress(overallProgress); await Task.Yield(); } Instances[i] = instance.Result[0]; // Report completion of this step currentProgress = (i + 1) * progressPerPrefab; CustomBoot.UpdateProgress(currentProgress); } } /// /// Initialise the boot settings object synchronously, loading each prefab in /// public void InitialiseSync() { RuntimeContainer = new GameObject($"{name}_Container"); if (Application.isPlaying) { DontDestroyOnLoad(RuntimeContainer); } Instances = new GameObject[BootPrefabs.Length]; // Calculate total prefabs for progress tracking int totalPrefabs = BootPrefabs.Length; float progressPerPrefab = totalPrefabs > 0 ? 1f / totalPrefabs : 1f; float currentProgress = 0f; for (var i = 0; i < BootPrefabs.Length; i++) { if (!BootPrefabs[i]) { // Report incremental progress even for null prefabs currentProgress = (i + 1) * progressPerPrefab; CustomBoot.UpdateProgress(currentProgress); continue; } var instance = GameObject.Instantiate(BootPrefabs[i], RuntimeContainer.transform); Instances[i] = instance; // Report completion of this step currentProgress = (i + 1) * progressPerPrefab; CustomBoot.UpdateProgress(currentProgress); } } /// /// Destroy all loaded instances referenced by /// public void Cleanup() { foreach (var t in Instances) { if (t) { if (Application.isPlaying) { GameObject.Destroy(t); } else { GameObject.DestroyImmediate(t); } } } Instances = null; if (Application.isPlaying) { GameObject.Destroy(RuntimeContainer); } else { GameObject.DestroyImmediate(RuntimeContainer); } } } }