using System.Collections.Generic;
using Unity.Pipeline.Config;
using UnityEngine;
namespace Unity.Pipeline
{
///
/// Creates the runtime Pipeline driver automatically when a Player boots (or Play Mode is
/// entered in the Editor) — no scene setup required. Reads RuntimePipelineConfig (JSON-backed
/// in the Editor, a build-baked Resources asset in a Player) and the build-baked
/// RuntimePipelineBuildInfo from Resources; does nothing if no config exists or the config
/// has the server disabled.
///
public static class RuntimePipelineBootstrap
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void RuntimeBootstrap()
{
Bootstrap();
}
///
/// The driver created by , or null if it has not run yet (or created
/// nothing because there was no usable config). Reachable for tests and manual control.
///
public static RuntimePipelineDriver Instance { get; internal set; }
///
/// Core bootstrap logic, split out from the attributed entry point so tests can invoke it
/// directly instead of waiting for a real domain/Player boot. Returns the created driver,
/// or null if the server should not start (no config asset, or disabled). Idempotent: a
/// second call returns the existing rather than creating a duplicate.
///
/// The created (or already-existing) driver, or null if the server should not start.
public static RuntimePipelineDriver Bootstrap()
{
if (Instance != null)
return Instance;
var config = RuntimePipelineConfig.Load();
if (config == null || !config.enableInBuilds)
{
#if UNITY_EDITOR
// The runtime server is a player-build feature, but in-editor code reload still
// needs the [CodeReload] targets registered for this Play session — the driver
// would do it in Awake; with no driver, do it here so a save can bind.
RuntimePipelineDriver.RegisterDiscoveredCodeReloadMethods();
#endif
return null;
}
var buildInfo = RuntimePipelineBuildInfo.Load();
IReadOnlyList roots = buildInfo != null
? (IReadOnlyList)buildInfo.allowedReloadRoots
: System.Array.Empty();
// Empty when there's no build info (e.g. play mode never built): the driver then rejects
// every push, which is the correct strict default outside a real signed build.
string pushPublicKey = buildInfo != null ? buildInfo.pushPublicKey : "";
var go = new GameObject("Pipeline Runtime Driver") { hideFlags = HideFlags.DontSave };
var driver = go.AddComponent();
driver.Initialize(config, roots, pushPublicKey);
Instance = driver;
return driver;
}
}
}