Files
sampleproj/Assets/SETUP.md
2026-03-29 13:18:13 +02:00

160 lines
6.1 KiB
Markdown

# PSXSplash Test Scene - Unity Setup Guide
This test scene exercises every Lua API namespace and callback. Follow these steps to set it up in SplashEdit.
## Prerequisites
- Unity project with SplashEdit (the `splashedit` package)
- A font atlas configured (for UI text)
- Audio clips imported (or skip audio-related tests)
## Step 1: Create the Scene
1. Create a new Unity scene
2. Add a **PSXSceneExporter** component to a root GameObject
3. Add a **PSXPlayer** prefab (for player movement, gravity, collision)
4. Add **PSXNavRegion** components to define walkable floor areas
## Step 2: Create Lua Files
Create **LuaFile** ScriptableObjects (Assets > Create > PSXSplash > Lua File) for each script:
| Lua File Name | Script |
|---------------|--------|
| `scene` | `scene.lua` (attach to scene, not an object) |
| `collectible` | `collectible.lua` |
| `door` | `door.lua` |
| `npc` | `npc.lua` |
| `switch` | `switch.lua` |
| `spinner` | `spinner.lua` |
| `movable` | `movable.lua` |
| `entity_scanner` | `entity_scanner.lua` |
Paste each `.lua` file's content into the corresponding LuaFile asset's text field.
## Step 3: Set Up Scene Script
On the PSXSceneExporter, assign the `scene` LuaFile to the **Scene Script** field. This handles `onSceneCreationStart`, `onSceneCreationEnd`, and `onTriggerEnter/Exit`.
## Step 4: Create Game Objects
For each entity script, create a GameObject in the scene:
### Collectibles (x3)
- Create 3 GameObjects with mesh renderers (cubes, spheres, etc.)
- Add **PSXObjectExporter** to each, assign the `collectible` LuaFile
- Space them around the scene so the player can walk into them
- They use `onCollideWithPlayer` - no PSXInteractable needed
### NPC
- Create a GameObject with a character mesh
- Add **PSXObjectExporter**, assign `npc` LuaFile
- Add **PSXInteractable** component (so `onInteract` fires when player presses Cross nearby)
### Door
- Create a door mesh GameObject
- Add **PSXObjectExporter**, assign `door` LuaFile
- Add **PSXInteractable** component
- Create a second GameObject named exactly **"DoorBlocker"** (invisible wall blocking the doorway)
- Add **PSXObjectExporter** to DoorBlocker (no script needed)
- The door script finds it by name and hides it when opened
### Switch
- Create a switch/lever mesh GameObject
- Add **PSXObjectExporter**, assign `switch` LuaFile
- Add **PSXInteractable** component
- Create a second GameObject named exactly **"SwitchTarget"**
- Add **PSXObjectExporter** (no script needed)
- The switch toggles this object's active state
### Spinner
- Create a decorative mesh (pillar, gem, etc.)
- Add **PSXObjectExporter**, assign `spinner` LuaFile
- Add **PSXInteractable** component (so player can start/stop the spin)
### Movable
- Create a box/crate mesh
- Add **PSXObjectExporter**, assign `movable` LuaFile
- Add **PSXInteractable** component (interact to select, then D-pad to move)
### Entity Scanner
- Create a terminal/pedestal mesh
- Add **PSXObjectExporter**, assign `entity_scanner` LuaFile
- Add **PSXInteractable** component
## Step 5: Create Trigger Boxes
Add **PSXTriggerBox** components to empty GameObjects. The scene script handles these by index:
| Trigger Index | Purpose | Placement |
|---------------|---------|-----------|
| 0 | Cutscene zone | Near a scenic viewpoint |
| 1 | Damage zone | In a hazard area (lava, spikes, etc.) |
| 2 | Scene transition portal | At a doorway/exit |
| 3 | Heal zone | Near a health pickup area |
Trigger indices are assigned in the order they appear in the scene hierarchy.
## Step 6: Create UI Canvases
In the SplashEdit UI editor, create two canvases:
### Canvas: "HUD"
| Element Name | Type | Purpose |
|-------------|------|---------|
| ScoreText | Text | Shows "Score: 0" |
| StatusText | Text | Shows status messages |
| HealthBar | Progress | Shows health 0-100 |
### Canvas: "Dialogue"
| Element Name | Type | Purpose |
|-------------|------|---------|
| DialogueText | Text | Shows NPC dialogue lines |
Set the Dialogue canvas to **initially hidden**.
## Step 7: Create Cutscenes
Create **PSXCutsceneClip** assets for:
| Cutscene Name | Type | Description |
|---------------|------|-------------|
| `ambient_spin` | Looping | Background ambient animation (object rotation, etc.) |
| `camera_flyover` | One-shot | Camera pan across the scene (Camera Position + Rotation tracks) |
| `door_open` | One-shot | Door opening animation (Object Position track) |
| `spin_loop` | Looping | Full 360-degree rotation for the spinner object (Object Rotation track) |
## Step 8: Audio Clips
Import or create placeholder audio clips named:
- `collect` - pickup sound
- `door_open` - door opening
- `switch_on` / `switch_off` - switch toggle sounds
- `heal` - healing sound
## Step 9: Build and Test
1. Open Splash Control Panel (Window > PSXSplash > Control Panel)
2. Click **Build and Run**
3. Watch the PSX Console for Debug.Log output from all scripts
4. Walk around and interact with objects to test each callback
## What Each Script Tests
| Script | Callbacks | API Namespaces |
|--------|-----------|----------------|
| scene.lua | onSceneCreationStart, onSceneCreationEnd, onTriggerEnter, onTriggerExit | Scene, Persist, UI, Audio, Controls, Cutscene, Timer, Debug, PSXMath, Vec3 |
| collectible.lua | onCreate, onDestroy, onEnable, onDisable, onCollideWithPlayer | Entity, Audio, Persist |
| door.lua | onCreate, onInteract | Entity, Audio, Controls, Cutscene |
| npc.lua | onCreate, onInteract, onButtonPress | Input, Controls, UI |
| switch.lua | onCreate, onInteract | Entity, Audio |
| spinner.lua | onCreate, onInteract, onCollideWithPlayer | Cutscene, Entity, Timer |
| movable.lua | onCreate, onInteract, onButtonPress | Entity, Vec3, Camera, Input |
| entity_scanner.lua | onInteract | Entity, Vec3 |
## Key Design Notes
- **No onUpdate anywhere.** All logic is event-driven. Rotation uses a looping cutscene.
- **No float literals.** PS1 Lua uses integer-only numbers. Use `1/2` instead of `0.5`, `1/4` instead of `0.25`, etc.
- **Scene globals.** `scene.lua` defines `addScore()`, `setStatus()`, `startDialogue()`, `advanceDialogue()`, `isInDialogue()`, `endDialogue()` as globals. Other scripts call these directly.