# Setup guide — Dialogue and Spaces 360
## Install
1. Copy the `DialogueAndSpaces/` folder into your project's `Assets/` directory.
2. Unity will compile five assemblies:
- `DialogueAndSpaces.Dialogue.Runtime`
- `DialogueAndSpaces.Dialogue.Editor`
- `DialogueAndSpaces.Spaces360.Runtime`
- `DialogueAndSpaces.Spaces360.Editor`
- `DialogueAndSpaces.EditorCommon` (editor only)
No packages need to be installed. Targeted at the Universal 3D (URP) template on Unity 6000.6.5f1.
> This source has been reviewed but **not yet play-tested in Unity**. If you hit a compile error
> or a runtime problem, note the exact message and file — it will help fix the framework.
## Quick start — Dialogue
1. `Create → Dialogue and Spaces → Dialogue Graph`. Name it `DemoDialogue`.
2. `Window → Dialogue and Spaces → Dialogue Graph Editor`.
3. Drag `DemoDialogue` into the **Graph Asset** field.
4. **Add Entry**. This creates `entry-1` and sets `entryNodeId` automatically.
5. **Add Line**. In the properties panel set **Speaker ID** to `merchant` and text to `Hello, traveler.`
6. Right-click the right-hand port of `entry-1`, then left-click your line node — they are now connected.
7. **Add Choice**. Add options with the `+ Add option` button, then right-click the line's port and connect to the choice. For Choice and Branch nodes, connecting opens a slot menu so you choose which option / path to fill.
8. Add more Line / End nodes and connect them into a small graph: Entry → Line → Choice → Line(s) → End.
9. **Validate** to confirm there are no errors.
10. In your scene, create an empty `GameObject` named `NPC_Merchant`. Add a `DialogueHost` component, assign `DemoDialogue` to **Graph**.
11. Add a `DialogueDebugPresenter` component to the same GameObject (leave **Host** blank to auto-find).
12. Press Play. The debug presenter calls `host.Begin()` automatically in `Start()` and draws the current line / choices on screen. Click **Continue** or a choice to advance.
## Quick start — Spaces360
## Prepare Insta360 media
1. Export monoscopic equirectangular photos and videos from the Insta360 app / Insta360 Studio.
- Photos: PNG or JPG, 2:1 aspect (e.g. 6080×3040 for Insta360 X3).
- Video: MP4 with H.264 (or H.265) at 4K or less for smooth playback.
2. Import the exported files into Unity.
3. For photos, set the import settings to **Texture Type: Default**, **sRGB: checked**, and disable **Generate Mip Maps** if memory is tight.
## Build the graph
1. `Create → Dialogue and Spaces → Spaces 360 Media Catalog`. Name it `MyCatalog`.
2. In the catalog Inspector, add one entry per panorama. For a photo:
- `key` = `insta360-room`
- `kind` = `Image`
- `image` = your imported `Texture2D`
3. `Create → Dialogue and Spaces → Spaces 360 Graph`. Name it `MySpaces`.
4. `Window → Dialogue and Spaces → Spaces 360 Graph Editor`.
5. Drag `MySpaces` into **Graph** and `MyCatalog` into **Catalog**.
6. **Add Space**. Set the `Media key` to `insta360-room`.
7. In the space's Hotspots section, add a hotspot:
- `id` = `hs-door`
- `yaw` = `0` (forward, +Z) and `pitch` = `-5` (slightly down)
- `label` = `Hallway`
- `kind` = `Jump`
- `destination` = the ID of another space (create it first)
8. Repeat until you have a connected tour.
9. **Validate**.
## Wire the scene
1. Create a `Camera` named `PlayerCam`. Add a `SpacesLookController` component.
2. Create an empty `GameObject` named `SpacesHost`. Add a `Spaces360Host` component.
- Assign `graph` = `MySpaces`
- Assign `catalog` = `MyCatalog`
- Assign `playerCamera` = `PlayerCam`
- Enable `showDebugOverlay` to test hotspot jumps
3. Press Play. Left-drag to look around. Hotspots within the camera's FOV appear in the overlay; click them to navigate. The `initialYaw` of the destination space is applied automatically through the look controller.
## Yaw / pitch convention
- Yaw 0° = Unity forward (+Z). Increasing yaw rotates clockwise (toward +X), matching `Transform.eulerAngles.y`.
- Pitch -90° = straight down. Pitch +90° = straight up.
- Use `panoramaRotationY` on a space if the Insta360 export's forward direction is rotated relative to Unity's.
## JSON interchange
Both graph types are exported as plain JSON wrapped in `{ "graph": { ... } }`. Connections are **derived** from node destinations — there is no separate edge list, so the editor and runtime always agree. All node references use stable string IDs. Safe to check into version control and hand-edit.
Imports are validated in two stages:
- **Structural errors** (null records, duplicate IDs, unknown enum values, mismatched choice lengths, unsupported schema versions) are rejected outright — the asset is not modified.
- **Semantic errors** (broken destinations, missing media keys) are shown in a confirmation dialog; you can still import if you accept them.
## Troubleshooting
- **"Media key NOT found in catalog"** — the graph references a key that isn't in the catalog. Add the entry or fix the typo.
- **Video doesn't play** — the video codec isn't supported on the target platform. Re-export with H.264 at a lower profile, or use WebM on WebGL.
- **Dialogue looks fine but nothing shows** — the `DialogueHost` has no `graph` assigned, or the debug presenter's `host` reference is missing.
- **Two NPCs share state** — you created one `DialogueRunner` and shared it. Create one `DialogueRunner` per NPC by constructing it from the same `DialogueGraphAsset`.
- **Mouse look doesn't work** — your project is set to Input System only. Set Active Input Handling to `Both` (or rewrite `SpacesLookController` using the Input System).
## Known limitations
- `videoStartDelay` is a placeholder field — currently unused by the renderer.
- The skybox is global (`RenderSettings.skybox`) — other cameras in the scene will also see the panorama while it is active.
- This source has not been play-tested in Unity yet. Report issues so the framework can be fixed.