Skip to content

Add PrefabDebugger - #2896

Open
dartasen wants to merge 4 commits into
SubnauticaNitrox:masterfrom
dartasen:feat/add-prefabpreviewer
Open

dartasen wants to merge 4 commits into
SubnauticaNitrox:masterfrom
dartasen:feat/add-prefabpreviewer

Conversation

@dartasen

@dartasen dartasen commented Sep 15, 2026 •

Copy link
Copy Markdown
Member

Description of Change

Requested by @tornac1234

Introduces a new debugger that allows to fetch and explore prefabs entries (pulled from PrefabDatabase class), giving the opportunity to inspect and play with those without digging in the game files or finding them in game.

Also added a QoL that selects the right tab and opens the SceneDebugger when inspecting a game object (used by SceneExtraDebugger also for ray casting)

image image

Features

  • List all prefabs available in PrefabDatabase with the following informations : Prefab name, Class ID, TechType (if available)
  • Allows to select a prefab from the list and renders it inside a cloned isolated preview object (only prefabs with renderers are displayed, ParticleRenderers aren't simulated and not needed in that PR)
  • Allows to instantiate the prefab in front of the player
  • Allows to inspect the preview prefab with the SceneDebugger (useful to inspect components for prefabs that can't be instantiated)
  • Allows to manage and inspect instantiated prefabs in a different tab

3D Preview controls

  • Rotate with right mouse dragging
  • Move the prefab in X/Y with left-drag.
  • Move it in depth with Ctrl + left-drag
  • Zoom with the mouse wheel
  • Adjust manually with sliders for: Yaw, Pitch, X position, Y position, Z position, Camera distance

PR Checklist

  • PR rebased on top of main at the time of opening
  • Has tests for the changes
  • Has a linked issue
  • Has been tested in-game
  • Has been tested on Windows

🤖 This code was created with the help of AI (especially for the IMGUI part which is a nightmare to write by hand)

@github-actions

github-actions Bot commented Sep 15, 2026 •

Copy link
Copy Markdown

Test Results

269 tests  ±0   264 ✅ ±0   12s ⏱️ +2s
  1 suites ±0     5 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 86eb4ef. ± Comparison against base commit 24730bf.

♻️ This comment has been updated with latest results.

@dartasen dartasen added Area: dev Related to development environment or dev QoL Status: Needs testing Pull Request is waiting for testing labels Sep 15, 2026
@dartasen
dartasen requested review from Measurity and tornac1234 and a lite review from Copilot September 15, 2026 21:53
@dartasen
dartasen marked this pull request as ready for review September 15, 2026 22:01

This comment was marked as outdated.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved PrefabDebugger findings include one critical spawn-lifecycle issue and six moderate correctness or usability issues.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (6)

Previously missed (2) — in code that hasn't changed since the last review.

NitroxClient/Debuggers/PrefabDebugger.cs:214

  • The PR description says the prefab list includes each prefab's TechType, but each row here renders only the name and class ID. TechType is populated and shown only for the currently selected prefab after its asynchronous load, so users cannot browse the list with that advertised information. Add a cached TechType column/value to each row, or adjust the feature contract.
    NitroxClient/Debuggers/PrefabDebugger.cs:450
  • Instantiate(..., false) creates the preview clone inactive (the same inactive-first overload used by GameObjectExtensions.InstantiateInactiveWithId), but this scan runs before the clone is activated. A MeshRenderer on the root therefore has activeSelf == false, so HasVisibleRenderer returns false and the preview/spawn controls stay disabled for otherwise renderable prefabs. Temporarily activate the behaviour-disabled clone for this scan and deactivate it afterward, or otherwise base visibility on the intended hierarchy state.

NitroxClient/Debuggers/PrefabDebugger.cs:247

  • The render texture is fixed at 640x480 (4:3), while this preview rect is sized to the debugger's remaining width and a fixed height of 540px. StretchToFill distorts the prefab whenever that rect is not 4:3, which is the normal layout for this 900px-wide window. Preserve the aspect ratio with ScaleToFit (or compute an aspect-matched draw rect).
                GUI.DrawTexture(previewRect, previewTexture, ScaleMode.StretchToFill, false);

NitroxClient/Debuggers/PrefabDebugger.cs:494

  • ParticleSystemRenderer is also a Renderer, so this predicate marks particle-only prefabs as previewable. Since this debugger does not simulate particle systems, those prefabs can show an empty preview while still enabling the renderer-dependent actions. Exclude particle renderers from the visibility/bounds test (or explicitly simulate them).
    private static bool IsRendererVisible(Renderer renderer) => renderer.enabled && renderer.gameObject.activeSelf;

NitroxClient/Debuggers/PrefabDebugger.cs:437

  • Instantiate creates an active clone before SetLayerRecursively and DisablePreviewBehaviours run. Any prefab scripts can therefore execute Awake/OnEnable with the clone still in the game scene, so disabling them afterward cannot make this preview isolated and may cause registrations or other gameplay side effects. Use a lifecycle-safe inactive instantiation/sanitization path before exposing arbitrary prefabs to the preview.
        previewObject = UnityEngine.Object.Instantiate(prefab, Vector3.zero, Quaternion.identity, false);
        previewObject.name = $"[Prefab preview] {prefab.name}";
        SetLayerRecursively(previewObject.transform, PREVIEW_LAYER);
        DisablePreviewBehaviours(previewObject);

NitroxClient/Debuggers/PrefabDebugger.cs:265

  • InstantiateSelectedPrefab can return without creating anything when Player.main or its camera is unavailable (see its guard at lines 662-665), but this unconditional tab change still leaves the explorer and hides the failure status. Return whether spawning succeeded and switch tabs only after a successful instantiation, or keep the explorer active on failure.
                if (GUILayout.Button("Spawn in front of player", GUILayout.Width(240f)))
                {
                    InstantiateSelectedPrefab();
                    ActiveTab = GetTab("Instantiated prefabs").Value;
                }
  • Files reviewed: 7/7 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread NitroxClient/Debuggers/PrefabDebugger.cs
@tornac1234

Copy link
Copy Markdown
Collaborator

Very cool feature, thanks for implementing it!

A few comments after testing it:

  • I usually test Nitrox with a window 1280x768, and the prefab debugger is bigger than that it would seem.
  • Would appreciate that "enter" also searchs.
  • Also I'd probably invert the mouse scroll direction (scrolling up should zoom I think (as an example google maps does it that way)).
  • Is the XYZ part supposed to turn around because it doesn't on my screen

@dartasen
dartasen force-pushed the feat/add-prefabpreviewer branch from 86eb4ef to 7f2fd85 Compare October 12, 2026 12:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: dev Related to development environment or dev QoL Status: Needs testing Pull Request is waiting for testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants