using UnityEngine;
namespace NightclubArcadia.Core
{
///
/// Finds objects that live in a different loaded scene.
///
/// Unity cannot serialize a reference across a scene boundary — the Inspector
/// refuses it and any existing reference is nulled when the scenes are split. So a
/// level object that needs the dialogue runner, or the player, has to resolve it at
/// runtime. This is a lookup helper, not a service container: there is no
/// registration step and nothing to keep in sync.
///
/// It is deliberately thin. FindFirstObjectByType is not cheap, so callers cache
/// what they get in Awake rather than calling per frame, and an Inspector-assigned
/// reference always wins — this only fills in what the split left null.
///
public static class SceneServices
{
/// Inspector value if set, otherwise the first one in any loaded scene.
public static T Resolve(T assigned, Object context, string field) where T : Object
{
if (assigned != null)
{
return assigned;
}
var found = Object.FindFirstObjectByType();
if (found == null)
{
Debug.LogError(
$"[SceneServices] {context?.name}: could not resolve {field} ({typeof(T).Name}). " +
"Is the Systems scene loaded?", context);
}
return found;
}
static Transform player;
///
/// The player transform, by tag, cached. Null between scene loads if the
/// systems scene has not come up yet, so callers must handle null.
///
public static Transform Player
{
get
{
if (player == null)
{
var go = GameObject.FindGameObjectWithTag("Player");
player = go != null ? go.transform : null;
}
return player;
}
}
/// Drop the cache. Call when unloading a scene that held the player.
public static void Forget() => player = null;
}
}