> ## Documentation Index
> Fetch the complete documentation index at: https://docs-unity.molca.id/llms.txt
> Use this file to discover all available pages before exploring further.

# Reference system

> ReferenceManager, ReferenceableComponent, and SceneObjectReference.

**Folder:** `Packages/com.molca.core/Runtime/ReferenceSystem/`

## When to use

Use the reference system when you need **stable, late-bound connections** between objects across scenes or prefab boundaries:

* **Cross-scene references** — link a step in one scene to an interaction in another without hard `SerializeField` references.
* **Addressable/dynamic content** — resolve references after objects are loaded at runtime.
* **VR step → interaction wiring** — `ValveStep` finds its `ValveInteraction` via `SceneObjectReference` rather than a direct drag-and-drop link.

| Type                       | Role                                                    |
| -------------------------- | ------------------------------------------------------- |
| **ReferenceManager**       | Registry of `IReferenceable` instances                  |
| **ReferenceableComponent** | Assigns stable **Ref Id** + type string on a GameObject |
| **SceneObjectReference**   | Serialized id → `Resolve<T>()` after startup            |

[Step](/core/step) implements `IReferenceable<Step>` with `RefType` `"Step"`.

## Typical pattern

1. Target: add `ReferenceableComponent`, set unique Ref Id.
2. Consumer: `SceneObjectReference` field in Inspector, then `Resolve<T>()` after `RuntimeManager.WaitForInitialization()`.

## Code

```csharp theme={null}
using Molca;
using Molca.ReferenceSystem;
using Molca.Sequence;
using UnityEngine;

public class ValveTask : MonoBehaviour
{
    [SerializeField] private SceneObjectReference targetStep;

    private async void Start()
    {
        await RuntimeManager.WaitForInitialization();
        var step = await targetStep.ResolveAsync<Step>();
        if (step != null)
            Debug.Log($"Linked step: {step.DisplayName}");
    }
}
```

Prefer **`ResolveAsync<T>()`** so registration has finished; synchronous **`Resolve<T>()`** is fine once **`RuntimeManager.IsReady`**.

## Troubleshooting

* **`Resolve<T>()` returns null:** the target `ReferenceableComponent` may not be registered yet. Use `ResolveAsync<T>()` after `RuntimeManager.WaitForInitialization()` instead.
* **Duplicate Ref Ids:** each `ReferenceableComponent` must have a unique `RefId` within its `RefType`. Duplicates cause the first registration to win; later ones are silently ignored.
* **Reference breaks after scene reload:** `ReferenceManager` clears registrations on scene changes. Re-resolve references in `OnEnable` or `Start` of the new scene.

## Related

* [Step (base class)](/core/step) — implements `IReferenceable<Step>`
* [Dependency injection](/core/dependency-injection) — `ReferenceManager` is injected via `[Inject]`
* [Valve step](/vr/steps/valve-step) — uses `SceneObjectReference` to find its interaction

## Unity Editor

<Frame caption="ReferenceableComponent + SceneObjectReference custom drawers">
  <img src="https://mintcdn.com/ptmolcateknologinusantara/jus_XMBZ8O0U_mpA/images/features/core/scene-object-reference-drawer.png?fit=max&auto=format&n=jus_XMBZ8O0U_mpA&q=85&s=19f477c0fa03e7132cdc5e62055d3fcd" alt="Scene Object Reference Drawer" width="704" height="310" data-path="images/features/core/scene-object-reference-drawer.png" />
</Frame>
