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; } } }