SceneXRay
See every dependency in your scene — serialized references, UnityEvent targets, ScriptableObjects and materials — as an interactive graph you can drill into, arrange and keep. Plus missing-reference detection, dependency cycles, a health score and a build guard for CI.
Everything runs in the editor. Nothing is compiled into your build, no runtime component is added to any scene, and no package needs installing.
Copy one folder. There is no bootstrap call, no scene setup and no package manifest to edit.
The window opens on the full graph of the loaded scenes. From there you drill in.
Everything is reachable from the keyboard; the status bar at the bottom always shows the current bindings, node counts and zoom.
| Input | Action |
|---|---|
| Double-click / Enter | Focus the node — show its ego network |
| Backspace / Alt+← | Back to the previous view (camera and layout restored) |
| Alt+→ | Forward |
| Esc | Up one level — back, or out of focus into the full graph |
| = / − | Grow / shrink the focus radius (1–3 hops) |
| ←↑↓→ | Move the selection between cards, camera follows |
| Ctrl+wheel | Zoom · MMB drag or Alt+drag pan |
| A / F | Fit everything / frame the selection |
| 0 | Reset zoom to 100% |
| Ctrl+Z / Ctrl+Y | Undo / redo node arrangement |
| Ctrl+S | Save this scene's arrangement |
| Ctrl+F | Jump to the search field |
| Right-click | Focus · expand · select in Hierarchy/Project · view references · find missing |
Focus replaces the full graph with the neighbourhood of one object. History behaves like a browser: every step remembers its camera, page and focus parameters.
| Control | Meaning |
|---|---|
| R (1–3) | How many hops away from the center to include |
| Dir · Both | Undirected neighbourhood — everything connected |
| Dir · Out | Only what the center depends on |
| Dir · In | Only what references the center |
| Breadcrumbs | All › Player › Weapon — click any level to jump straight back |
| Show All | Leave focus, restoring the full-graph arrangement you had |
The Layout menu picks how nodes are placed. The choice is remembered per user, and Re-layout now re-runs it on whatever is on screen.
| Mode | Best for |
|---|---|
| Auto | Default — Tree for the full graph, Radial while focused |
| Tree | Reading direction: layered left→right columns by dependency depth, barycenter-ordered rows |
| Force | Dense scenes: keeps the columns but hard-packs rows so nothing overlaps |
| Radial | One object under investigation: rings by hop distance around the center |
Automatic layouts are a starting point. Once you have dragged the graph into the shape that matches how you think about the scene, keep it.
| Menu · Layout | What happens |
|---|---|
| Save my layout Ctrl+S | Stores every node position for the active scene |
| Restore my layout | Re-applies it — nodes added since keep their computed position |
| Auto-restore on open | On by default: reopening the scene brings your arrangement back |
| Delete saved layout | Forget it and fall back to automatic layouts |
Colour carries the link type; position carries the direction; hovering carries the detail.
| On the card | Meaning |
|---|---|
| Icon + name | The object or asset the node stands for |
| Second line | Hierarchy path (or asset folder) — disambiguates same-named objects |
| Blue badge | Number of links touching this node |
| Left colour bar | Hierarchy root the object belongs to |
| Amber ring | Current focus center |
Every serialized ObjectReference on every component of every GameObject in the loaded scenes, including fields hidden from the Inspector, plus persistent UnityEvent targets found through reflection.
| Link type | Source | Example |
|---|---|---|
| Direct | serialized GameObject / Component field | PlayerController.visualRoot → Visual |
| UnityEvent | persistent listener target + method | Button.m_OnClick → GameManager.Restart() |
| Asset | any referenced project asset | MeshRenderer → M_Player |
| Missing | reference whose target no longer exists | Spawner.target → Missing |
| In code | opt-in C# lookup by type, name or tag | HUD → FindWithTag("Player") |
Noise control
| Rule | Why |
|---|---|
| Ignored Components | Transform, RectTransform by default — parenting is not a dependency |
m_Script skipped | Every MonoBehaviour points at its own script asset; the component name is already on the link |
| Self-references skipped | Button.targetGraphic → Image on the same object is not a link between objects |
| Built-ins excluded | Opt in with Include Built-in Assets if you want Default-Material and friends |
The score in the toolbar is a single number for "is this scene wired sanely". Click it for the breakdown.
| Signal | Meaning |
|---|---|
| Missing references | Serialized fields pointing at deleted objects — the usual cause of null-refs at runtime |
| Cycles | A → B → C → A dependency loops, listed with the full path |
| God objects | Objects with more than 10 links — the usual refactor candidates |
Fix Missing
Tools ▸ SceneXRay ▸ Fix Missing lists every broken reference with its component and property. Selecting a row pings the object; Fix All rebinds each one to a scene object whose name matches the property name, which resolves the common "renamed the object, lost the link" case. Everything it changes goes through Undo.
The fastest answer to "who uses this?" without leaving the Inspector. Enabled by default, toggled in settings.
| Selected | You get |
|---|---|
| Scene GameObject | References — what it points at · Referenced By — what points at it |
| Prefab asset | What the whole prefab tree references, plus the scene objects using the prefab |
| ScriptableObject / material | Referenced By — every scene object that pulls the asset in |
| Tool | Use |
|---|---|
| Toolbar search | Filter the graph by node name, component type, link type or hierarchy depth |
| Global Search | Find references to any object across loaded scenes and the project — drag an object in or pick from suggestions |
| Bookmarks | Ctrl+Shift+Alt+J pins the selection, …+K opens the list. Survives editor restarts via GlobalObjectId |
Compare two scene assets structurally, or take the current graph into documentation and tooling.
| Command | Result |
|---|---|
| Advanced ▸ Scene Diff | Compares the dependency links of two scene assets without opening them |
| Export | JSON · CSV · self-contained interactive HTML · Mermaid · Markdown |
Project Settings ▸ SceneXRay. Stored in ProjectSettings/SceneXRaySettings.asset, so the team shares them.
| Group | Setting | Effect |
|---|---|---|
| Overlay | Enable / Animate | Dependency lines drawn in the Scene View for the selected object |
| Colors | Direct · UnityEvent · Missing · Asset · In Code · Line Width | Applies to both the overlay and the graph edges, live — no refresh needed |
| Inspector | Inspector Integration | The References / Referenced By strip |
| Graph | Max Nodes In Graph | Page size for very large scenes |
| Scanning | Ignored Components | Component types the scanner skips entirely |
| Scanning | Scan Asset References | Record links to project assets (materials, clips, ScriptableObjects…) |
| Scanning | Include Built-in Assets | Also record Unity's built-ins — noisy, off by default |
| Scanning | Scan Code Dependencies | Opt-in C# lookup scan; off by default because it reads script source files |
| Scanning | Max Code Targets · Script Nodes | Caps broad lookups and controls whether referenced classes appear as cards |
| Build | Build Guard · Fail Build On Missing Refs | Block a build when the scene has broken references |
| Language | English / Українська | Editor UI language |
Run the same analysis headlessly and fail the pipeline on broken wiring.
| Behaviour | Detail |
|---|---|
| Output | Every link as JSON: source path, target, property, component, link type |
| Exit code | 0 clean · 1 when a quality gate fails or the scene is missing |
| Build guard | Off by default. Enable Build Guard to scan before a build: interactive builds ask for confirmation, batchmode fails only when Fail Build On Missing Refs is on |
Two editor-only assemblies, four namespaces, no external references.
| Assembly | Platforms | References |
|---|---|---|
SceneXRay.Editor | Editor only | none · autoReferenced: false |
SceneXRay.Editor.Tests | Editor only | SceneXRay.Editor · gated by UNITY_INCLUDE_TESTS |
Where data is written
| Path | Content |
|---|---|
ProjectSettings/SceneXRaySettings.asset | Shared team settings |
UserSettings/SceneXRay/Layouts/ | Your saved graph arrangements |
Library/SceneXRay/ | Scan cache and bookmarks |
The tool is UI-first, but the scanning and graph layers are plain static classes you can drive from your own editor scripts.
| Symptom | Cause / fix |
|---|---|
| Graph is empty | Press Refresh. If the scene really has no serialized cross-references there is nothing to draw — check with Selected Only off. |
| Ctrl+Shift+Alt+X does nothing | Something else in the editor has claimed the chord. Rebind it under Edit ▸ Shortcuts ▸ Main Menu ▸ Tools/SceneXRay/Open Graph View; the menu item itself always works. |
| Materials / SOs are missing from the graph | Scan Asset References is off, or the asset is a Unity built-in — enable Include Built-in Assets. |
| Too many nodes to read | Focus an object instead of showing all, lower Max Nodes In Graph, or filter by link type. |
| Layout keeps resetting | Save it: Layout ▸ Save my layout and keep Auto-restore on open enabled. |
| Inspector strip missing | Inspector Integration is off in settings, or the object has no links. |
| Stale data after editing the scene | Enable Live Mode, or press Refresh — the index rebuilds on a debounce. |