Before you begin: use Unity's main thread in Play Mode. The namespace is
LoadingScreenBuildPro. If your code uses a custom asmdef, referenceLoadingScreenBuildPro.Runtime. These examples come from the supplied guide; their simulated waits are teaching examples, not production initialization.
1. A menu Button#
Save as GuideLoadButton.cs. Attach it to a menu object, set Destination and connect your Button’s OnClick to BeginLoading. The explicit layout override can stay empty when a saved scene connection exists. Single scene replacement can destroy ordinary scene callback owners; use a persistent observer for state that must survive activation.
using UnityEngine;
using LoadingScreenBuildPro;
public sealed class GuideLoadButton : MonoBehaviour
{
[SerializeField] private string destination = "SampleScene";
[SerializeField] private LoadingLayout optionalOverride;
public void BeginLoading()
{
if (LoadingScreenBuilder.IsLoading) return;
var handle = LoadingScreenBuilder.LoadScene(
destination, optionalOverride);
handle.Failed += OnFailed;
}
private void OnFailed(LoadingRequestHandle handle)
{
if (handle.State != LoadingState.Cancelled)
Debug.LogException(handle.Error);
}
}2. Observe lifecycle events#
Save as GuideLoadingObserver.cs. Put one instance on a root GameObject in the startup scene. This observer persists across scene replacement and pairs subscription with unsubscription. Keep a returned handle for final results; Active becomes null when idle. Cancellation also uses the Failed notification, so inspect State.
using UnityEngine;
using LoadingScreenBuildPro;
public sealed class GuideLoadingObserver : MonoBehaviour
{
private void Awake() => DontDestroyOnLoad(gameObject);
private void OnEnable()
=> LoadingScreenBuilder.Lifecycle += OnLifecycle;
private void OnDisable()
=> LoadingScreenBuilder.Lifecycle -= OnLifecycle;
private void OnLifecycle(string milestone,
LoadingRequestHandle handle)
{
if (milestone == "OnProgress") return;
string progress = handle.Progress.HasValue
? $"{handle.Progress.Value * 100f:0}%" : "unknown";
Debug.Log($"{milestone}: {handle.Scene}, {progress}");
}
}Download GuideLoadingObserver.cs
3. Timer and transition only#
Save as GuidePresentationActions.cs, assign a layout and connect separate Buttons to the two public methods. Both examples stay in the current scene. Timer APIs remove real operation/stage requirements, but optional authored presentation policy can still apply. Use Async/Both with Scene Policy None for real custom work.
using UnityEngine;
using LoadingScreenBuildPro;
public sealed class GuidePresentationActions : MonoBehaviour
{
[SerializeField] private LoadingLayout layout;
public void PlayTimer()
{
if (!layout || LoadingScreenBuilder.IsLoading) return;
LoadingScreenBuilder.RunTimer(3f, layout);
}
public void PlayTransition()
{
if (!layout || LoadingScreenBuilder.IsLoading) return;
LoadingScreenBuilder.TransitionOnly(layout);
}
}Download GuidePresentationActions.cs
4. Signal Game Ready#
Configure a required Post Activation > Signal checkpoint with ID game.ready. Save as GuideDestinationReady.cs and attach it to the destination initializer. Replace the two-frame demonstration wait with real initialization. Keep the initializer outside held GameplayGate targets. The request-ID overload rejects stale callbacks. Alternatively, add LoadingReadySignal; automatic signaling is valid only when its wait represents actual readiness.
using System.Collections;
using UnityEngine;
using LoadingScreenBuildPro;
public sealed class GuideDestinationReady : MonoBehaviour
{
private IEnumerator Start()
{
string requestId = LoadingScreenBuilder.Active?.Id;
yield return null;
yield return null;
// Player/camera/data initialization must be finished here.
if (!string.IsNullOrEmpty(requestId))
LoadingScreenBuilder.SignalReady(
requestId, "game.ready");
}
}Download GuideDestinationReady.cs
5. Custom work and progress#
Save as GuideCustomWork.cs, assign Layout and call Begin from a Button. Keep the host alive until cleanup. Replace simulated elapsed time with your operation. ReportProgress controls the Manual display; operation.Complete() finishes the underlying work. Required gates still apply. A temporary behavior profile avoids editing shared settings. Custom operation Begin must clean up its own work if it throws.
using System.Collections;
using UnityEngine;
using LoadingScreenBuildPro;
public sealed class GuideCustomWork : MonoBehaviour
{
[SerializeField] private LoadingLayout layout;
public void Begin() => StartCoroutine(Work());
private IEnumerator Work()
{
if (!layout || LoadingScreenBuilder.IsLoading) yield break;
var policy = ScriptableObject.CreateInstance<LoadingBehaviourProfile>();
policy.completion = CompletionMode.AsyncOnly;
policy.scenePolicy = ScenePolicy.None;
policy.progressSource = ProgressSource.Manual;
var operation = new ManualLoadingOperation();
var handle = LoadingScreenBuilder.Show(new LoadingRequest
{
layout = layout, behaviour = policy, operation = operation
});
float elapsed = 0f;
while (!handle.IsDone && elapsed < 2f)
{
elapsed += Time.unscaledDeltaTime;
operation.Report(elapsed / 2f);
LoadingScreenBuilder.ReportProgress(elapsed / 2f, handle);
yield return null;
}
if (!handle.IsDone) operation.Complete();
while (!handle.IsDone) yield return null;
Destroy(policy);
}
}6. Stage task and context#
Create a required Task stage with ID prepare.data, with its intended phase, dependencies, weight and timeout. Save as GuideStageTask.cs and connect Begin to a Button. The dictionary key must equal the stage ID. Cancellation is cooperative through the token. Do not access Unity objects from background work. Retry needs both stage permission and a safely retryable task.
using System.Threading.Tasks;
using UnityEngine;
using LoadingScreenBuildPro;
public sealed class GuideStageTask : MonoBehaviour
{
[SerializeField] private string destination = "SampleScene";
public void Begin()
{
if (LoadingScreenBuilder.IsLoading) return;
var request = LoadingScreenBuilder.CreateSceneRequest(destination);
request.policy = RequestPolicy.Queue;
request.context.sceneTags.Add("forest");
request.context.playerFlags["chapter"] = "2";
request.context.input = "Gamepad";
request.tasks["prepare.data"] = new TaskLoadingStage(
token => Task.Delay(500, token));
LoadingScreenBuilder.Show(request);
}
}7. Choose a post screen per call#
Save as GuidePostScreen.cs, assign a PostLoadingLayout such as Aurora Ready and connect Begin to a Button. Set request.postLoading = null to inherit resolved design policy, or use new PostLoadingSettings { enabled = false } to disable it for this request. Assign LoadingGameplayGate targets for systems to hold. Keep required initialization outside those targets.
using UnityEngine;
using LoadingScreenBuildPro;
public sealed class GuidePostScreen : MonoBehaviour
{
[SerializeField] private string destination = "SampleScene";
[SerializeField] private PostLoadingLayout readyScreen;
public void Begin()
{
if (!readyScreen || LoadingScreenBuilder.IsLoading) return;
var request = LoadingScreenBuilder.CreateSceneRequest(destination);
request.postLoading = new PostLoadingSettings
{
enabled = true, screen = readyScreen,
waitForInput = true,
inputs = LoadingInputKind.Keyboard | LoadingInputKind.Gamepad,
pauseGameTime = true, blockGameplaySystems = true
};
LoadingScreenBuilder.Show(request);
}
public void Continue() => LoadingScreenBuilder.Continue();
}8. Drive an exported panel#
Save as GuidePanelActions.cs and assign the exported LoadingScenePanel. Wire the methods to your operation’s progress and completion. These calls update the native panel without starting a scene load. BeginPanelLoading(panel) / panel.BeginLoading() instead hides the panel and starts the saved-design loader; native hierarchy edits apply to manual panel mode.
using UnityEngine;
using LoadingScreenBuildPro;
public sealed class GuidePanelActions : MonoBehaviour
{
[SerializeField] private LoadingScenePanel panel;
public void Open()
{
if (panel) LoadingScreenBuilder.ShowPanel(panel);
}
public void Report(float value)
{
if (panel) LoadingScreenBuilder.SetPanelProgress(
panel, value, "Preparing...");
}
public void Unknown()
{
if (panel) LoadingScreenBuilder.SetPanelIndeterminate(panel);
}
public void Finish()
{
if (!panel) return;
LoadingScreenBuilder.SetPanelProgress(panel, 1f, "Ready", true);
LoadingScreenBuilder.HidePanel(panel);
}
}