lul
This commit is contained in:
382
Assets/SETUP_GUIDE.md
Normal file
382
Assets/SETUP_GUIDE.md
Normal file
@@ -0,0 +1,382 @@
|
||||
# Test Scene Setup Guide
|
||||
|
||||
This guide walks you through building the PSXSplash test scene in Unity step by step. The scene exercises every major feature: player movement, collision, Lua scripting (all callbacks), cutscenes (loop + callback), UI, audio, triggers, interactables, persist, controls enable/disable, and scene transitions.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- SplashEdit package installed in Unity
|
||||
- PSXSplash native project cloned and configured in the Control Panel
|
||||
- The Lua files from `test-scene/lua/` copied into your Unity project's Assets folder
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Create the Scene
|
||||
|
||||
1. File > New Scene (Basic Built-in)
|
||||
2. Save as `TestScene` in your Scenes folder
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Build the Room
|
||||
|
||||
Create a simple enclosed room for the player to walk around in.
|
||||
|
||||
### Floor
|
||||
1. GameObject > 3D Object > Plane
|
||||
2. Name: `Floor`
|
||||
3. Position: (0, 0, 0), Scale: (3, 1, 3) (gives a 30x30 unit floor)
|
||||
4. Add component: **PSX Object Exporter**
|
||||
- Bit Depth: 8bpp
|
||||
- Collision Type: **Mesh** (nav regions will be generated from this)
|
||||
|
||||
### Walls (4 total)
|
||||
Create 4 stretched cubes around the edges:
|
||||
|
||||
| Name | Position | Scale |
|
||||
|------|----------|-------|
|
||||
| WallNorth | (0, 2, 15) | (30, 4, 0.5) |
|
||||
| WallSouth | (0, 2, -15) | (30, 4, 0.5) |
|
||||
| WallEast | (15, 2, 0) | (0.5, 4, 30) |
|
||||
| WallWest | (-15, 2, 0) | (0.5, 4, 30) |
|
||||
|
||||
For each wall:
|
||||
- Add component: **PSX Object Exporter**
|
||||
- Bit Depth: 4bpp
|
||||
- Collision Type: **Mesh**
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Add the Player
|
||||
|
||||
1. Create an empty GameObject named `PSXPlayer`
|
||||
2. Position: (0, 0, -10) (near the south wall)
|
||||
3. Add component: **PSX Player**
|
||||
- Move Speed: 2.0
|
||||
- Sprint Speed: 4.0
|
||||
- Player Height: 3.0
|
||||
- Player Radius: 1.0
|
||||
- Jump Velocity: 8.0
|
||||
- Gravity: 15.0
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Scene Exporter Setup
|
||||
|
||||
1. Select the scene root or create an empty `SceneSetup` object
|
||||
2. Add component: **PSX Scene Exporter**
|
||||
- Scene Type: **Exterior**
|
||||
- GTE Scaling: 100
|
||||
- Fog: Disabled (or enable for atmosphere)
|
||||
- Scene Lua File: Assign `scene.lua`
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Create the Objects
|
||||
|
||||
### Collectibles (3x)
|
||||
|
||||
| Name | Position | Lua File |
|
||||
|------|----------|----------|
|
||||
| Collectible1 | (-8, 1, 8) | collectible.lua |
|
||||
| Collectible2 | (0, 1, 8) | collectible.lua |
|
||||
| Collectible3 | (8, 1, 8) | collectible.lua |
|
||||
|
||||
For each:
|
||||
1. GameObject > 3D Object > Sphere, scale (0.5, 0.5, 0.5)
|
||||
2. Add **PSX Object Exporter**
|
||||
- Bit Depth: 4bpp
|
||||
- Collision Type: **Sphere**
|
||||
- Lua File: `collectible.lua`
|
||||
- Collision Radius: 2.0
|
||||
|
||||
### Spinner
|
||||
|
||||
1. GameObject > 3D Object > Cube, name: `Spinner`
|
||||
2. Position: (-8, 1, 2), Scale: (1, 1, 1)
|
||||
3. Add **PSX Object Exporter**
|
||||
- Lua File: `spinner.lua`
|
||||
- Collision Type: None
|
||||
|
||||
### Door
|
||||
|
||||
1. GameObject > 3D Object > Cube, name: `Door`
|
||||
2. Position: (8, 2, 5), Scale: (0.5, 4, 3)
|
||||
3. Add **PSX Object Exporter**
|
||||
- Collision Type: None
|
||||
- Lua File: `door.lua`
|
||||
4. Add **PSX Interactable**
|
||||
- Interaction Radius: 3.0
|
||||
- Interaction Button: Cross
|
||||
- Show Prompt: true
|
||||
- Repeatable: true
|
||||
|
||||
### Door Blocker
|
||||
|
||||
1. GameObject > 3D Object > Cube, name: `DoorBlocker`
|
||||
2. Position: (8, 2, 5), Scale: (0.5, 4, 3)
|
||||
3. Add **PSX Object Exporter**
|
||||
- Collision Type: **Mesh** (blocks the player)
|
||||
- No Lua file needed - the door script finds it by name
|
||||
|
||||
### NPC
|
||||
|
||||
1. GameObject > 3D Object > Capsule, name: `NPC`
|
||||
2. Position: (0, 1.5, 2), Scale: (1, 1.5, 1)
|
||||
3. Add **PSX Object Exporter**
|
||||
- Collision Type: None
|
||||
- Lua File: `npc.lua`
|
||||
4. Add **PSX Interactable**
|
||||
- Interaction Radius: 3.0
|
||||
- Interaction Button: Cross
|
||||
- Show Prompt: true
|
||||
- Repeatable: true
|
||||
|
||||
### Switch
|
||||
|
||||
1. GameObject > 3D Object > Cube, name: `Switch`
|
||||
2. Position: (-8, 0.5, -5), Scale: (0.5, 1, 0.5)
|
||||
3. Add **PSX Object Exporter**
|
||||
- Lua File: `switch.lua`
|
||||
4. Add **PSX Interactable**
|
||||
- Interaction Radius: 2.5
|
||||
- Interaction Button: Cross
|
||||
- Show Prompt: true
|
||||
- Repeatable: true
|
||||
|
||||
### Switch Target
|
||||
|
||||
1. GameObject > 3D Object > Cube, name: `SwitchTarget`
|
||||
2. Position: (-5, 1, -5), Scale: (2, 2, 2)
|
||||
3. Add **PSX Object Exporter**
|
||||
- Active: true (the switch script will toggle it)
|
||||
|
||||
### Movable Object
|
||||
|
||||
1. GameObject > 3D Object > Sphere, name: `Movable`
|
||||
2. Position: (5, 0.5, -5), Scale: (1, 1, 1)
|
||||
3. Add **PSX Object Exporter**
|
||||
- Lua File: `movable.lua`
|
||||
- Collision Type: None
|
||||
|
||||
### Entity Scanner
|
||||
|
||||
1. GameObject > 3D Object > Cylinder, name: `Scanner`
|
||||
2. Position: (0, 1, -8), Scale: (0.5, 1, 0.5)
|
||||
3. Add **PSX Object Exporter**
|
||||
- Lua File: `entity_scanner.lua`
|
||||
4. Add **PSX Interactable**
|
||||
- Interaction Radius: 2.5
|
||||
- Interaction Button: Cross
|
||||
- Show Prompt: true
|
||||
- Repeatable: true
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Trigger Boxes
|
||||
|
||||
### Cutscene Trigger (index 0)
|
||||
|
||||
1. Create empty GameObject, name: `CutsceneTrigger`
|
||||
2. Position: (10, 0, 0)
|
||||
3. Add **PSXTriggerBox**
|
||||
- Size: (4, 4, 4)
|
||||
- Trigger Index: 0
|
||||
|
||||
### Damage Zone (index 1)
|
||||
|
||||
1. Create empty GameObject, name: `DamageZone`
|
||||
2. Position: (-10, 0, -10)
|
||||
3. Add **PSXTriggerBox**
|
||||
- Size: (4, 2, 4)
|
||||
- Trigger Index: 1
|
||||
|
||||
### Scene Portal (index 2)
|
||||
|
||||
1. Create empty GameObject, name: `ScenePortal`
|
||||
2. Position: (0, 0, 12)
|
||||
3. Add **PSXTriggerBox**
|
||||
- Size: (3, 4, 1)
|
||||
- Trigger Index: 2
|
||||
|
||||
---
|
||||
|
||||
## Step 7: UI Canvases
|
||||
|
||||
### HUD Canvas
|
||||
|
||||
1. Create empty GameObject, name: `HUD`
|
||||
2. Add **PSXCanvas**
|
||||
- Visible: true
|
||||
|
||||
Add children with **PSXUIBox** or appropriate UI components:
|
||||
|
||||
| Name | Component | Position | Details |
|
||||
|------|-----------|----------|---------|
|
||||
| ScoreText | PSXUIText | Top-left (10, 10) | Text: "Score: 0" |
|
||||
| StatusText | PSXUIText | Bottom-left (10, 220) | Text: "Welcome!" |
|
||||
| HealthBar | PSXUIProgressBar | Top-right (220, 10) | Value: 100, Width: 80 |
|
||||
|
||||
### Dialogue Canvas
|
||||
|
||||
1. Create empty GameObject, name: `Dialogue`
|
||||
2. Add **PSXCanvas**
|
||||
- Visible: false (hidden by default)
|
||||
|
||||
Add children:
|
||||
|
||||
| Name | Component | Position | Details |
|
||||
|------|-----------|----------|---------|
|
||||
| DialogueText | PSXUIText | Center-bottom (40, 180) | Text: "" |
|
||||
|
||||
### Font
|
||||
|
||||
1. Create a **PSXFontAsset** (Right-click > Create > PSXFontAsset)
|
||||
2. Assign your font texture
|
||||
3. Reference it in the PSX Scene Exporter's font slot
|
||||
|
||||
---
|
||||
|
||||
## Step 8: Audio Clips
|
||||
|
||||
Add the following audio clips to the scene (via PSXAudioClip components or the scene exporter's audio list):
|
||||
|
||||
| Clip Name | Usage |
|
||||
|-----------|-------|
|
||||
| `collect` | Collectible pickup sound |
|
||||
| `door_open` | Door opening sound |
|
||||
| `switch_on` | Switch activation |
|
||||
| `switch_off` | Switch deactivation |
|
||||
|
||||
These names must match what the Lua scripts pass to `Audio.Play()`. Use any short WAV files - they will be converted to PS1 ADPCM during export.
|
||||
|
||||
---
|
||||
|
||||
## Step 9: Cutscenes
|
||||
|
||||
Create the following PSXCutsceneClip assets and add them to the Scene Exporter's cutscene list:
|
||||
|
||||
### ambient_spin
|
||||
|
||||
A looping animation that rotates an object continuously (used with `loop = true`).
|
||||
|
||||
- 1 track: **Object RotationY** targeting `Spinner`
|
||||
- Keyframes: frame 0 = 0.0, frame 60 = 2.0 (full rotation in 2 seconds)
|
||||
- Interpolation: Linear
|
||||
- Total frames: 60
|
||||
|
||||
### camera_flyover
|
||||
|
||||
A camera pan triggered by trigger box 0.
|
||||
|
||||
- Track 1: **Camera Position**
|
||||
- Frame 0: Player position (0, 3, -10)
|
||||
- Frame 30: Above room (0, 15, 0)
|
||||
- Frame 60: Back to player (0, 3, -10)
|
||||
- Interpolation: EaseInOut
|
||||
- Track 2: **Camera Rotation**
|
||||
- Frame 0: (0.15, 0, 0) (slight downward tilt)
|
||||
- Frame 30: (0.5, 0, 0) (looking straight down)
|
||||
- Frame 60: (0.15, 0, 0) (back to normal)
|
||||
- Interpolation: EaseInOut
|
||||
- Total frames: 60
|
||||
|
||||
### door_open
|
||||
|
||||
Animates the door object and camera for the door interaction.
|
||||
|
||||
- Track 1: **Camera Position** (pan to look at door)
|
||||
- Frame 0: (current position, captured automatically)
|
||||
- Frame 15: (7, 3, 2) (viewing angle on door)
|
||||
- Frame 45: (7, 3, 2) (hold)
|
||||
- Frame 60: (current position, blends back)
|
||||
- Interpolation: EaseInOut
|
||||
- Track 2: **Object Position** targeting `Door`
|
||||
- Frame 15: (8, 2, 5) (closed position)
|
||||
- Frame 45: (8, 6, 5) (moved up / opened)
|
||||
- Interpolation: EaseOut
|
||||
- Total frames: 60
|
||||
|
||||
---
|
||||
|
||||
## Step 10: Navigation Setup
|
||||
|
||||
1. Select the Floor and Wall objects
|
||||
2. In the PSX Scene Exporter, configure navigation:
|
||||
- Agent Radius: 1.0
|
||||
- Agent Height: 3.0
|
||||
- Max Step Height: 0.5
|
||||
- Max Slope: 45
|
||||
3. Bake navigation (this generates the nav regions from the floor mesh)
|
||||
4. Verify the blue nav region overlay covers the walkable area
|
||||
|
||||
---
|
||||
|
||||
## Step 11: Export and Build
|
||||
|
||||
1. Open the SplashEdit Control Panel (Window > SplashEdit > Control Panel)
|
||||
2. Go to the Scenes tab
|
||||
3. Add `TestScene` as Scene 0
|
||||
4. Go to the Build tab
|
||||
5. Click **Export All Scenes**
|
||||
6. Click **Build & Run** (for emulator) or **Build ISO** (for real hardware)
|
||||
|
||||
---
|
||||
|
||||
## What the Test Scene Verifies
|
||||
|
||||
| Feature | How it's tested |
|
||||
|---------|-----------------|
|
||||
| Player movement | Walk around the room |
|
||||
| Jumping | Jump with Cross button |
|
||||
| Collision | Walk into walls, they block you |
|
||||
| Nav regions | Floor constrains movement |
|
||||
| Gravity | Fall back down after jumping |
|
||||
| onCollideWithPlayer | Touch the collectible spheres |
|
||||
| onInteract | Press Cross near Door, NPC, Switch, Scanner |
|
||||
| onTriggerEnter/Exit | Walk into the trigger boxes |
|
||||
| onButtonPress/Release | Hold Square near the Movable object |
|
||||
| onUpdate | Watch the Spinner rotate continuously |
|
||||
| onCreate/onDestroy | Check debug log at scene load |
|
||||
| onEnable/onDisable | Collect an item (disables it) |
|
||||
| onSceneCreationStart/End | Check debug log |
|
||||
| Cutscene.Play | Walk into trigger box 0 |
|
||||
| Cutscene loop | ambient_spin runs from scene start |
|
||||
| Cutscene onComplete | Door cutscene re-enables controls |
|
||||
| Cutscene.Stop | Stop ambient when needed |
|
||||
| Cutscene.IsPlaying | Door script checks before playing |
|
||||
| Controls.SetEnabled | Disabled during cutscenes and dialogue |
|
||||
| Controls.IsEnabled | Available for query |
|
||||
| Camera.GetPosition | Used by movable.lua |
|
||||
| Camera.SetPosition | Tested via cutscene camera tracks |
|
||||
| Camera.SetRotation | Tested via cutscene camera tracks |
|
||||
| Entity.Find | Door finds DoorBlocker, Switch finds SwitchTarget |
|
||||
| Entity.FindByIndex | Scanner tests this |
|
||||
| Entity.ForEach | Scanner iterates all entities |
|
||||
| Entity.GetCount | Switch and Scanner log it |
|
||||
| Entity.SetActive | Collectible, Switch, Door all toggle objects |
|
||||
| Entity.IsActive | Switch checks target state |
|
||||
| Entity.Get/SetPosition | Movable object moves via Lua |
|
||||
| Entity.Get/SetRotationY | Spinner rotates via Lua |
|
||||
| Vec3 (all functions) | scene.lua tests in onSceneCreationEnd |
|
||||
| PSXMath (all functions) | scene.lua tests in onSceneCreationEnd |
|
||||
| Audio.Play | Collectible, Door, Switch play sounds |
|
||||
| UI.FindCanvas | scene.lua resolves HUD and Dialogue |
|
||||
| UI.FindElement | scene.lua resolves text and progress bar |
|
||||
| UI.SetText | Score, status, dialogue display |
|
||||
| UI.SetProgress | Health bar updates on damage |
|
||||
| UI.SetCanvasVisible | Dialogue canvas show/hide |
|
||||
| Persist.Get/Set | Score persists across scene reloads |
|
||||
| Scene.Load | Portal trigger reloads scene |
|
||||
| Scene.GetIndex | Logged on scene start |
|
||||
| Timer.GetFrameCount | Spinner logs periodically |
|
||||
| Debug.Log | Used throughout all scripts |
|
||||
| Input constants | NPC dialogue uses Input.CROSS |
|
||||
|
||||
---
|
||||
|
||||
## Debugging Tips
|
||||
|
||||
- Open the PSX Console window (Window > SplashEdit > PSX Console) to see Debug.Log output
|
||||
- In PCSX-Redux, enable the Lua console to see printf output
|
||||
- In Duckstation, check the CD-ROM debug window for drive state
|
||||
- If something doesn't work, check the debug log for error messages from the Lua scripts
|
||||
Reference in New Issue
Block a user