Files
AppleHillsProduction/Assets/Scripts/Bootstrap/CustomBootSettings.cs

138 lines
4.8 KiB
C#

using System.Threading.Tasks;
using UnityEngine;
namespace Bootstrap
{
/// <summary>
/// Settings for the custom boot process
/// </summary>
public class CustomBootSettings : ScriptableObject
{
/// <summary>
/// A list of prefabs which should be loaded during boot
/// </summary>
public GameObject[] BootPrefabs;
/// <summary>
/// Internal references to instances of the prefabs from <see cref="BootPrefabs"/>
/// </summary>
private GameObject[] Instances;
/// <summary>
/// Runtime container object which acts as the parent for any BootPrefab instances
/// </summary>
private GameObject RuntimeContainer;
/// <summary>
/// Initialise the boot settings object asynchronously, loading each prefab in <see cref="BootPrefabs"/>
/// </summary>
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);
}
}
/// <summary>
/// Initialise the boot settings object synchronously, loading each prefab in <see cref="BootPrefabs"/>
/// </summary>
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);
}
}
/// <summary>
/// Destroy all loaded instances referenced by <see cref="Instances"/>
/// </summary>
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);
}
}
}
}