Files
Ipseity-Demo/Assets/_Content/TO CLEAN/DEVELOPER_GUIDE_V2.md
T

23 KiB

Unheimlich POC - Developer Guide

Unity Version: 6000.3
Last Updated: January 2025


Table of Contents

  1. Project Overview
  2. Core Systems
  3. Quick Start Guides
  4. Architecture Details
  5. Best Practices
  6. Troubleshooting

Project Overview

This is a first-person horror exploration prototype featuring seamless portals, interactive dialogues, and environmental storytelling. The project uses Unity's Universal Render Pipeline and the New Input System.

Key Features

  • Seamless portal system with recursive rendering
  • Node-based dialogue system with gaze interaction
  • Custom dialogue editors for rapid content creation
  • Dynamic room loading/unloading
  • First-person controller with smooth movement
  • Interactive objects (doors, items, NPCs)
  • Item inspection system
  • Environmental audio with portal proxying

Project Structure

/Assets/Unheimlich_POC
├── /Scenes                      # Game scenes
├── /Scripts                     # C# scripts organized by namespace
│   ├── /Audio                   # Audio systems
│   ├── /Data                    # ScriptableObject definitions
│   ├── /Editor                  # Editor tools and inspectors
│   ├── /Gameplay                # Core gameplay systems
│   │   ├── /Environment         # Doors, interactables
│   │   ├── /Items               # Inspectable items
│   │   ├── /Player              # Player components
│   │   └── /Portals             # Portal system
│   ├── /Handlers                # Input and interaction handlers
│   ├── /Interactions            # Dialogue, focus, floating words
│   ├── /Managers                # Singleton managers
│   ├── /UI                      # UI components
│   └── /Utility                 # Helper functions
├── /Prefabs                     # Reusable prefabs
│   ├── /Dialogues               # Dialogue triggers and UI
│   ├── /NPCS                    # NPC prefabs
│   ├── /Player                  # Player prefab
│   ├── /Portals                 # Portal prefabs
│   └── /Rooms                   # Room prefabs for portal loading
├── /Datas                       # ScriptableObject assets
│   ├── /Dialogues               # Conversations and nodes
│   └── /Settings                # Animation and system settings
└── /Materials                   # Materials and shaders
    ├── /Portal                  # Portal-specific materials
    └── /Shaders                 # Custom shaders

Core Systems

Portal System

The portal system creates seamless transitions between spaces by rendering real-time views through portal surfaces and teleporting objects that cross the portal plane.

How It Works

  1. Rendering: Each portal has a camera that renders the view from the linked portal's perspective
  2. Display: The rendered view is projected onto the portal's screen mesh
  3. Teleportation: Objects crossing the portal plane are teleported to the linked portal
  4. Slicing: A custom shader prevents visual artifacts by hiding geometry on the wrong side
  5. Room Loading: Rooms can be dynamically loaded/unloaded based on player distance

Key Components

Portal.cs

  • Main portal logic
  • Handles rendering, teleportation, and room loading
  • Tracks objects (PortalTravellers) entering the portal
  • Manages linked portal connection

PortalTraveller.cs

  • Required on any object that should teleport through portals
  • Handles smooth transition during crossing
  • Automatically added to player

PortalRoomManager.cs

  • Singleton that manages room loading/unloading
  • Distance-based loading (default: 15 units)
  • Supports room pooling to keep inactive rooms in memory
  • Prevents unnecessary load/unload cycles

PortalDoor.cs

  • Synchronized door between linked portals
  • Opening one door opens the corresponding door on the other side

Using the Portal Prefab

The PortalWithDoor.prefab contains a pre-configured portal ready to use:

  1. Drag PortalWithDoor.prefab into your scene

  2. Set up the portal settings:

    • Linked Portal: Leave empty if loading a room, or drag another portal for direct linking
    • Room Prefab To Load: Assign the room prefab you want to load through this portal
    • Room Spawn Point: Position where the room will be instantiated (relative to portal)
    • Linked Portal Path In Room: Path to find the linked portal within the loaded room (default: "Portal")
  3. Configure the door (optional):

    • The door automatically syncs with the linked portal's door
    • Adjust door swing direction and speed in the inspector

Creating Portal Rooms

Rooms loaded through portals should follow this structure:

RoomPrefab
├── Environment (walls, floor, props)
├── Portal (the exit portal back)
│   └── Configure to link back to original portal
└── Lighting (optional)

Best practices for room prefabs:

  • Position the portal at a logical exit point
  • Include nav mesh for AI (if needed)
  • Keep the room self-contained (all required objects inside)
  • Use relative positioning (portal spawn point defines world position)

Portal Settings Explained

Main Settings

  • Portal ID: Unique identifier for this portal (used for dynamic linking)
  • Linked Portal: Direct reference to the connected portal
  • Screen: The mesh renderer that displays the portal view
  • Recursion Limit: How many nested portal views to render (3 is usually enough)

Advanced Settings

  • Near Clip Offset: Distance from portal plane for camera near clip (prevents z-fighting)
  • Near Clip Limit: Minimum near clip distance (prevents rendering issues)
  • Transition Distance: Distance from portal to start teleportation check
  • Load Room Distance: How far ahead of the portal to spawn the room

Room Loading

  • Room Prefab To Load: The room prefab to instantiate
  • Room Spawn Point: Where to spawn it (uses portal forward direction)
  • Linked Portal Path: Hierarchy path to find the portal in the spawned room
  • Linked Portal ID: Alternative ID-based linking

Common Portal Scenarios

Two-Way Portal Between Rooms

  1. Create Portal A in Room A
  2. Create Portal B in Room B (make it a prefab)
  3. Set Portal A to load Room B prefab
  4. Portal B will auto-link to Portal A when Room B spawns

One-Way Portal (no return)

  • Don't assign a room prefab or linked portal
  • Portal only renders, doesn't teleport
  • Useful for windows or vistas

Portal Chain (A → B → C)

  • Each room prefab contains a portal to the next room
  • Last room can portal back to start or end the chain

Dialogue System

The dialogue system uses a node-based structure where conversations are built from linked DialogueNode assets. Players interact with choices by looking at them (gaze-based selection).

Architecture

DialogueConversation (ScriptableObject)

  • Container for a complete conversation
  • References the first DialogueNode to start from
  • Can contain metadata like conversation name/description

DialogueNode (ScriptableObject)

  • Single piece of dialogue with text and choices
  • Contains:
    • Dialogue text (what the NPC/narrator says)
    • List of choices (what the player can respond with)
    • Each choice has text and a reference to the next node
    • Auto-close settings for end nodes

DialogueChoiceData (Serializable Class)

  • Embedded in DialogueNode
  • Contains choice button text
  • Direct reference to next DialogueNode
  • Optional condition for advanced filtering

Flow

Player interacts with trigger
     ↓
DialogueManager.StartConversation()
     ↓
Show current node's dialogue text
     ↓
Spawn floating choice buttons (if any)
     ↓
DialogueFocusSystem.Update() (raycasts for player gaze)
     ↓
ChoiceFocusHandler.ApplyFocusFeedback() (visual feedback)
     ↓
Player focuses on choice for required time
     ↓
DialogueManager.GoToNextNode()
     ↓
Repeat or end

Quick Setup: Using the DialogueTrigger Prefab

The fastest way to add dialogue is using the pre-made DialogueTrigger.prefab:

  1. Create Your Conversation

    • Right-click in Project → Create → Unheimlich → Dialogue → Dialogue Conversation
    • Name it (e.g., CONV_WelcomeMessage)
    • Select the conversation asset in the inspector
  2. Use the Conversation Editor

    • The custom editor provides an intuitive interface for building conversations
    • Click "Create New Dialogue Node" button to add nodes directly
    • New nodes are automatically created in the same folder as the conversation
    • Nodes are automatically added to the conversation's node list
    • The editor shows conversation overview (total nodes, starting node)
  3. Build Dialogue Nodes

    • Select a node asset to edit it
    • The custom node editor provides:
      • Node Content: Dialogue text and localization key
      • Choices: List of player choices with next node references
      • Add Choice button for quick choice creation
      • Clear All Choices to reset a node
    • For end nodes (no choices):
      • Set auto-close delay (0 = manual close)
      • The editor will show "end of conversation" status
    • Warnings appear if choices are missing next node references
  4. Connect the Flow

    • Drag node assets into choice "Next Node" fields
    • The first node in the conversation list is the starting point
    • Use descriptive node names (e.g., Greeting, Quest_Accept, Goodbye)
  5. Add Trigger to Scene

    • Drag DialogueTrigger.prefab into your scene
    • Position it where you want dialogue to trigger
    • Assign your conversation to the trigger component
    • Configure trigger type (zone, interact, or NPC)

Dialogue Editor Features

The custom editors significantly speed up dialogue creation:

Conversation Editor (DialogueConversation)

  • One-click node creation with automatic naming
  • Nodes created in the same folder as the conversation
  • Conversation overview with node count and starting node
  • Visual feedback for speaker setup

Node Editor (DialogueNode)

  • Streamlined choice management (add, remove, clear all)
  • Visual warnings for invalid node configuration
  • End node detection with auto-close settings
  • Localization field support
  • Help boxes explain node behavior

Best Workflow

  1. Create the conversation asset
  2. Use "Create New Dialogue Node" to build your flow
  3. Edit each node's content and choices
  4. Link nodes by dragging references
  5. Test in play mode
  6. Iterate based on playthrough

Creating Custom Dialogue Triggers

If you need more control, you can create triggers from scratch:

Option 1: Zone Trigger (Automatic)

// Add DialogueTriggerZone component to a GameObject with a trigger collider
// Assign your DialogueConversation asset
// Dialogue starts when player enters the zone

Option 2: Interaction Trigger (Manual)

// Add NPCDialogueTrigger component to an NPC GameObject
// Make sure NPC has the "Interactable" layer
// Player presses E to start dialogue

Option 3: Scripted Trigger (Code)

DialogueManager.Instance.StartConversation(
    myConversation,              // Your DialogueConversation asset
    anchorTransform,             // Where to spawn choices (NPC head, trigger position)
    animationSettings,           // Optional: DialogueAnimationSettings preset
    customUI,                    // Optional: Use specific DialogueUI instance
    ownerObject                  // Optional: Track which object owns this dialogue
);

Dialogue Node Best Practices

Text Guidelines

  • Keep dialogue text under 200 characters for readability
  • Use line breaks for longer dialogue
  • Choice text should be 1-10 words maximum

Node Structure

  • Use descriptive node names (e.g., "GreetPlayer_Friendly")
  • End nodes should have no choices or set NextNode to null
  • Branching nodes should have 2-4 choices maximum

Auto-Close Settings

  • End nodes can auto-close after a delay
  • Set AutoCloseDelay to 0 for manual close (requires player to walk away or press ESC)
  • Set to 3-5 seconds for automatic closure

Localization

  • Use the ChoiceTextLocalizationKey field for localized text
  • Leave empty if not using localization
  • The system falls back to ChoiceText if no key is provided

Animation Presets

Dialogue animations control how choice buttons appear and behave. Create presets for consistency:

  1. Right-click → Create → Unheimlich → Animation → Dialogue Animation Settings

  2. Configure:

    • Spawn Mode: How choices are positioned (circle, player-facing, etc.)
    • Rotation: Axis and speed of floating rotation
    • Distance Scaling: Scale choices based on distance
    • Floating: Gentle up/down motion
    • Player Follow: Choices follow player position/rotation
  3. Assign preset to:

    • Specific triggers (overrides default)
    • NPCs (for character-specific style)
    • Zones (for location-specific feel)

For object descriptions (inspectable items), create separate presets:

  • Right-click → Create → Unheimlich → Animation → Object Description Settings
  • Configure spawn pattern and floating word behavior

Common Dialogue Patterns

Simple Linear Dialogue

Node: "Welcome"
└── Choice: "Thanks" → Node: "Goodbye" → null

Branching Dialogue

Node: "What brings you here?"
├── Choice: "Just exploring" → Node: "Casual_Response"
├── Choice: "I'm looking for someone" → Node: "Quest_Response"
└── Choice: "None of your business" → Node: "Rude_Response"

Loop Back Pattern

Node: "Ask_Questions"
├── Choice: "Tell me about yourself" → Node: "About_Me" → back to "Ask_Questions"
├── Choice: "What's this place?" → Node: "About_Place" → back to "Ask_Questions"
└── Choice: "Goodbye" → null

Player System

The player uses Unity's New Input System with a first-person controller.

Components

Player.cs

  • Singleton access point
  • Manages player state
  • Provides transform reference for other systems

PlayerMovement.cs

  • Character Controller-based movement
  • Walking, running, jumping
  • Ground detection
  • Slope handling

PlayerLook.cs

  • Mouse-based camera control
  • Aim lock during dialogue (optional)
  • Sensitivity settings
  • Smooth rotation

InteractionHandler.cs

  • Raycast-based interaction detection
  • Highlights interactable objects
  • Triggers interaction on key press
  • Displays interaction prompts

Input Actions

Defined in InputActions asset:

  • Move: WASD / Left Stick
  • Look: Mouse / Right Stick
  • Jump: Space / South Button (A/X)
  • Interact: E / West Button (X/Square)
  • Run: Left Shift / Left Stick Click
  • Pause: ESC / Start Button

Interaction System

Objects can be made interactable by implementing the IInteractable interface:

public interface IInteractable
{
    void Interact(GameObject interactor);
    string GetInteractionPrompt();
}

Built-in Interactables

DoorInteractable

  • Opens/closes with animation
  • Optional locked state
  • Synchronized portal doors

InspectableItem

  • Player picks up and examines item
  • Camera zooms to item
  • Can merge with object descriptions

NPCDialogueTrigger

  • Starts dialogue on interaction
  • Shows interaction prompt
  • Can be combined with other NPC behaviors

Quick Start Guides

Adding a Simple Dialogue

Using the Dialogue Editor (Recommended):

  1. Right-click → Create → Unheimlich → Dialogue → Dialogue Conversation
  2. Select the conversation asset
  3. Click "Create New Dialogue Node" button in the inspector
  4. Select the newly created node
  5. Fill in dialogue text
  6. Click "Add Choice" button for each player response option
  7. For each choice, create another node (repeat step 3) and drag it to "Next Node"
  8. Build your conversation flow by linking nodes
  9. Drag DialogueTrigger.prefab into scene and assign your conversation
  10. Test in play mode

Manual Method (Alternative):

  1. Create conversation: Right-click → Unheimlich → Dialogue → Dialogue Conversation
  2. Create first node: Right-click → Unheimlich → Dialogue → Dialogue Node
  3. Fill node with text and add 1-2 choices
  4. Create additional nodes for each choice
  5. Connect choices to next nodes
  6. Drag DialogueTrigger.prefab into scene
  7. Assign conversation to trigger
  8. Done - test in play mode

Adding a Portal Between Two Rooms

  1. Create two room prefabs with geometry
  2. Add PortalWithDoor.prefab to each room
  3. In Room A's portal:
    • Set "Room Prefab To Load" to Room B
    • Position "Room Spawn Point" appropriately
  4. In Room B's portal (in the prefab):
    • Set "Room Prefab To Load" to Room A
  5. Place Room A in your starting scene
  6. Test - walking through portal loads Room B

Adding an Interactive Door

  1. Add DoorInteractable component to door GameObject
  2. Set pivot point at door hinge
  3. Configure:
    • Open angle (90 for standard door)
    • Animation speed
    • Lock state (if needed)
  4. Ensure door is on "Interactable" layer
  5. Test - press E to open/close

Architecture Details

Namespaces

The project uses organized namespaces:

Unheimlich.Audio                     # Audio systems
Unheimlich.Data.Dialogues            # Dialogue data structures
Unheimlich.Gameplay.Environment      # Doors, props
Unheimlich.Gameplay.Items            # Item systems
Unheimlich.Gameplay.Player           # Player components
Unheimlich.Gameplay.Portals          # Portal system
Unheimlich.Interactions.Core         # Base interaction
Unheimlich.Interactions.Dialogues    # Dialogue triggers
Unheimlich.Interactions.FloatingWords # Choice button system
Unheimlich.Managers                  # Singleton managers
Unheimlich.UI                        # UI components
Unheimlich.Utility                   # Helper functions

Manager Systems

DialogueManager

  • Singleton: DialogueManager.Instance
  • Manages active dialogue state
  • Coordinates between UI, focus, and data systems
  • Handles conversation lifecycle

PortalRoomManager

  • Singleton: PortalRoomManager.Instance
  • Tracks loaded rooms
  • Distance-based loading/unloading
  • Room instance pooling

Both managers:

  • Auto-initialize in scene
  • Persist only within scene (no DontDestroyOnLoad)
  • Register/unregister components as needed

Audio System

PortalAudioProxy

  • Creates virtual audio sources for sounds through portals
  • Projects audio from other side of portal
  • Maintains spatial positioning
  • Automatically manages proxy lifecycle

Usage: Attach to portal GameObject - it automatically detects audio sources in loaded rooms and creates proxies.


Best Practices

Performance

Portals

  • Limit recursion to 3 levels (more tanks performance)
  • Use occlusion culling on portal cameras
  • Don't place portals facing each other at close range
  • Disable portal rendering when not visible

Dialogues

  • Keep choice count to 2-4 per node
  • Use animation presets instead of per-instance settings
  • Reuse DialogueNodes where possible

Room Loading

  • Keep room prefabs optimized (low poly)
  • Use room pooling for frequently visited areas
  • Set appropriate load/unload distances

Organization

Dialogue Assets

  • Group conversations by character or location in folders
  • Use prefixes: CONV_ for conversations, NODE_ for individual nodes
  • Name nodes descriptively (e.g., NODE_Shopkeeper_Greeting)

Prefabs

  • Keep room prefabs self-contained
  • Use variants for different states (open/closed doors, etc.)
  • Nest prefabs (NPC prefab inside Room prefab)

Scenes

  • One main scene with essentials (Player, Managers, UI)
  • Room prefabs for everything else
  • Use Scene references for cross-scene data

Dialogue Design

Structure

  • Start simple: linear dialogue for testing
  • Add branches after core flow works
  • End nodes should have clear outcomes
  • Avoid dead-ends (always provide exit choice)

Usability

  • Choice text must be clear and concise
  • Don't put more than 5 choices on one node
  • Position choice anchors carefully (near speaker's head)
  • Test all dialogue paths

Portal Setup

Linking

  • Use direct references when possible (simpler debugging)
  • Use ID-based linking for dynamic scenarios
  • Always set a room spawn point (never rely on default position)
  • Test both directions of portal travel

Visuals

  • Position portal screen mesh to align with doorway
  • Match portal door to environment art style
  • Add particle effects or audio cues for activated portals

Troubleshooting

Dialogue Issues

Choices don't appear

  • Check DialogueNode has choices assigned
  • Verify NextNode references aren't null (unless it's an end node)
  • Ensure ChoiceText is filled in
  • Check DialogueManager exists in scene

Can't select choices with gaze

  • Verify DialogueFocusSystem is active
  • Check choice anchor is positioned correctly
  • Ensure player camera is tagged "MainCamera"
  • Lower focus time requirement for testing

Dialogue doesn't start

  • Confirm conversation asset has a valid first node
  • Check trigger collider is set to "Trigger"
  • Verify player is on correct layer for detection
  • Look for errors in Console

Portal Issues

Portal shows black/nothing

  • Check linked portal reference is set
  • Ensure portal camera exists (auto-created on Awake)
  • Verify render texture is created
  • Check both portals have screen mesh assigned

Teleportation doesn't work

  • Confirm object has PortalTraveller component
  • Check portal collider is set to "Trigger"
  • Verify linked portal exists and is active
  • Ensure portals aren't too close to each other

Room doesn't load

  • Confirm PortalRoomManager exists in scene
  • Check room prefab assignment
  • Verify load distance settings
  • Look for errors during room instantiation
  • Ensure linked portal path in room is correct

Performance issues with portals

  • Lower recursion limit (try 1-2)
  • Reduce portal camera far clip plane
  • Simplify room geometry
  • Check for multiple portals rendering same view

General Issues

Input not working

  • Verify Input System package is installed
  • Check InputActions asset is assigned to player
  • Ensure input actions are enabled
  • Try reimporting InputActions asset

Objects not interactable

  • Confirm object has "Interactable" layer
  • Check InteractionHandler raycast layer mask
  • Verify IInteractable interface is implemented
  • Ensure collider exists on object

Audio not playing through portals

  • Add PortalAudioProxy to portal GameObject
  • Check audio sources are in loaded room
  • Verify audio settings (3D sound, spatial blend)
  • Check PortalRoomManager is loading rooms

Additional Resources

For more detailed examples and patterns, see:

  • /Pages/Guide - Nouveau Système de Dialogue.md - Dialogue system deep dive
  • /Pages/Tutorial - Créer un dialogue en 2 minutes.md - Quick dialogue tutorial
  • /Pages/Exemples - Structures de Dialogue Avancées.md - Advanced dialogue patterns

For implementation details:

  • Check inline code comments in manager scripts
  • Review prefab configurations for reference setups
  • Examine existing dialogue nodes and conversations in /Datas/Dialogues

Need Help? Check console for error messages - most issues will log helpful information. Enable Gizmos in Scene view to see portal connections and trigger volumes. Use the Unity Profiler to diagnose performance issues.