feat: persistent character system (closes #7) #31

Merged
lavarius merged 8 commits from feat/persistent-character-system into master 2026-03-12 03:06:53 +00:00
Collaborator

Implements the persistent character architecture from the plan. The character is now spawned once in Loading Screen and survives all scene transitions via DontDestroyOnLoad. Each game scene has a CharacterSpawnPoint marker that teleports the character on arrival and sets the correct zone.

Changes

New Scripts

  • CharacterSpawnPoint.cs — Empty GameObject marker with DefaultZone field. Gizmo renders a green sphere + forward arrow in the editor.
  • CharacterSceneInitializer.cs — Placed on Utility in each game scene. On Start(): disables CharacterController, teleports to spawn point, re-enables CC, calls SetZone on AnimationController + MovementManager, and calls DisableRagDollAll() to reset any lingering ragdoll state.
  • LoadingScreenController.cs — Placed on Utility in Loading Screen. Waits one frame for Awake() calls to complete, then forwards to SceneLoader.TargetScene via ScreenAnimationTransistor.

Modified Scripts

  • CharacterStore.cs — Added DontDestroyOnLoad(gameObject) in Awake() (closes #7)
  • SceneLoader.cs — Now stores TargetScene as a static property and always routes through Loading Screen first instead of loading game scenes directly
  • ScreenAnimationTransistor.cs — Added TriggerSceneChange(string sceneName) overload with Invoke-based scene load after the close animation

Scene Changes

Scene Changes
Loading Screen Added Character prefab instance + LoadingScreenController on Utility
HomeBase V2 Added CharacterSpawnPoint at character's original position (zone: Outside) + CharacterSceneInitializer on Utility
BoothMode Added CharacterSpawnPoint at origin rot:180 (zone: Booth) + CharacterSceneInitializer on Utility — Character BoothMode instance kept, needs decision on whether booth shares the persistent character or keeps its own variant
ENDScene Added CharacterSpawnPoint near room entrance (zone: Inside) + CharacterSceneInitializer on Utility — no character existed here before

⚠️ Action Required

BoothMode uses a separate Character BoothMode prefab that may have booth-specific configuration. Decide whether to:

  1. Merge booth-specific config into the main Character prefab and remove Character BoothMode from the scene, or
  2. Keep Character BoothMode as the persistent character (spawn it in Loading Screen instead of Character.prefab)

Testing Checklist

  • Play from Bootstrapper → scene loads correctly, character appears at spawn point
  • Scene transition HomeBase → (another scene) → character teleports to new spawn point
  • Zone triggers still fire correctly after teleport
  • Ragdoll resets cleanly on scene change
  • BoothMode character decision resolved
Implements the persistent character architecture from the plan. The character is now spawned once in **Loading Screen** and survives all scene transitions via `DontDestroyOnLoad`. Each game scene has a `CharacterSpawnPoint` marker that teleports the character on arrival and sets the correct zone. ## Changes ### New Scripts - **`CharacterSpawnPoint.cs`** — Empty GameObject marker with `DefaultZone` field. Gizmo renders a green sphere + forward arrow in the editor. - **`CharacterSceneInitializer.cs`** — Placed on `Utility` in each game scene. On `Start()`: disables CharacterController, teleports to spawn point, re-enables CC, calls `SetZone` on AnimationController + MovementManager, and calls `DisableRagDollAll()` to reset any lingering ragdoll state. - **`LoadingScreenController.cs`** — Placed on `Utility` in Loading Screen. Waits one frame for `Awake()` calls to complete, then forwards to `SceneLoader.TargetScene` via `ScreenAnimationTransistor`. ### Modified Scripts - **`CharacterStore.cs`** — Added `DontDestroyOnLoad(gameObject)` in `Awake()` (closes #7) - **`SceneLoader.cs`** — Now stores `TargetScene` as a `static` property and always routes through `Loading Screen` first instead of loading game scenes directly - **`ScreenAnimationTransistor.cs`** — Added `TriggerSceneChange(string sceneName)` overload with `Invoke`-based scene load after the close animation ### Scene Changes | Scene | Changes | |-------|---------| | **Loading Screen** | Added `Character` prefab instance + `LoadingScreenController` on Utility | | **HomeBase V2** | Added `CharacterSpawnPoint` at character's original position (zone: Outside) + `CharacterSceneInitializer` on Utility | | **BoothMode** | Added `CharacterSpawnPoint` at origin rot:180 (zone: Booth) + `CharacterSceneInitializer` on Utility — **`Character BoothMode` instance kept**, needs decision on whether booth shares the persistent character or keeps its own variant | | **ENDScene** | Added `CharacterSpawnPoint` near room entrance (zone: Inside) + `CharacterSceneInitializer` on Utility — no character existed here before | ## ⚠️ Action Required **BoothMode** uses a separate `Character BoothMode` prefab that may have booth-specific configuration. Decide whether to: 1. Merge booth-specific config into the main `Character` prefab and remove `Character BoothMode` from the scene, or 2. Keep `Character BoothMode` as the persistent character (spawn it in Loading Screen instead of `Character.prefab`) ## Testing Checklist - [ ] Play from Bootstrapper → scene loads correctly, character appears at spawn point - [ ] Scene transition HomeBase → (another scene) → character teleports to new spawn point - [ ] Zone triggers still fire correctly after teleport - [ ] Ragdoll resets cleanly on scene change - [ ] BoothMode character decision resolved
- CharacterStore: add DontDestroyOnLoad in Awake (closes #7)
- SceneLoader: store TargetScene statically, always route through Loading Screen
- ScreenAnimationTransistor: add TriggerSceneChange(sceneName) overload
- CharacterSpawnPoint: new marker with DefaultZone for each game scene
- CharacterSceneInitializer: new per-scene bootstrapper — teleports character to
  spawn point, applies zone to AnimationController + MovementManager, resets ragdoll
- LoadingScreenController: new — waits one frame then forwards to TargetScene

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Loading Screen:
- Added Character prefab instance (DontDestroyOnLoad source)
- Added LoadingScreenController to Utility

HomeBase V2:
- Added CharacterSpawnPoint at character start pos (zone: Outside)
- Added CharacterSceneInitializer to Utility

BoothMode:
- Added CharacterSpawnPoint at origin rot:180 (zone: Booth)
- Added CharacterSceneInitializer to Utility
- NOTE: 'Character BoothMode' prefab instance kept — needs review
  to determine if booth uses shared character or its own variant

ENDScene:
- Added CharacterSpawnPoint near room entrance (zone: Inside)
- Added CharacterSceneInitializer to Utility (no character was here before)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Utility prefab persists across scenes so Start() only fires once.
CharacterSpawnPoint is scene-specific — destroyed and recreated each
load — so its Start() fires on every scene transition as intended.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- CharacterSceneInitializer now calls StartRandomInteraction() after
  teleporting the character. Since the character persists (DDOL),
  Start() no longer fires on HomeBase entry — we trigger it manually.
- Loading Screen: add invisible Plane (CharacterFloor) at Y=-0.5 so
  the persistent character doesn't fall through the world while
  the next scene loads.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CharacterSceneInitializer now has a fallbackCharacterPrefab field.
If CharacterStore.Instance is null (direct scene load in editor or
skipped loading screen), it instantiates the prefab at the spawn
point instead of bailing out.

Assign Character.prefab on the CharacterSpawnPoint in each scene.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Enables direct-scene debugging without going through Loading Screen.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Added "Assets/TextMesh Pro/**/*.asset" exception to .gitattributes.
These are plain YAML Unity assets and should not be binary LFS objects.
Renormalized all 4 affected assets back to plain text.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
lavarius merged commit 35fd3450bf into master 2026-03-12 03:06:53 +00:00
lavarius deleted branch feat/persistent-character-system 2026-03-12 03:06:53 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lavarius/ProjectOverlay!31
No description provided.