OdinTools Deep Inspect
CoPlay MCP + C# Reflection Suite for AI-Assisted Unity Development
CoPlay MCP provides Claude Code with ~86 tools for Unity authoring: scene hierarchy manipulation, component property access, prefab management, Input System, materials, play mode control, screenshots. It's a capable authoring layer for anything the AI generates directly.
It has a structural blind spot: third-party assets.
CoPlay reads public properties via standard Unity serialization. Most premium
Unity assets store their configuration in [SerializeField] private
fields with vendor-specific internal structures. For a $20K+ asset library —
Behavior Designer Pro, SensorToolkit 2, A* Pathfinding Pro, Gore Simulator,
RayFire, Malbers Animal Controller, Animancer, Dialogue System — CoPlay
provides component existence and basic property values. The actual data lives
elsewhere.
OdinTools is a suite of 13 C# editor scripts (~75+ methods)
that use System.Reflection to serialize those opaque vendor
components into JSON. Invoked via CoPlay's execute_script tool,
they give the AI complete read access to assets it didn't author —
including runtime state during Play Mode.
| Limitation (Without OdinTools) | Impact |
|---|---|
| Arrays/lists show count only | For a BehaviorTree, the tree data is the task array. count: 12 tells you nothing. |
| Only reads public properties | BD Pro tasks, sensor configs, pathfinding graphs — all [SerializeField] private |
| Single-level inspection | Malbers MAnimal: states → enter/exit settings → sub-parameters. Need depth 3–4. |
| No vendor internal structures | BD Pro serializes into private m_Data. SensorToolkit uses internal detection registries. A* stores graph data on AstarPath.active. |
| No Play Mode runtime state | Current executing BT task, active sensor detections, computed A* paths — only exist in memory |
Two Layers, One Pipeline
Layer 1 — CoPlay MCP — The Control Layer
86 tools across 17 domains. Scene hierarchy, component management, prefab
pipeline, materials, Input System, scene management, UI creation, event wiring,
package management, terrain, play mode control, screenshots, performance
profiling, AI asset generation, and critically: execute_script
— the escape hatch that enables the entire introspection layer.
Layer 2 — OdinTools Reflection Suite — The Introspection Layer
75+ custom inspection methods via System.Reflection. Deep recursive
component inspection, array/list extraction, ScriptableObject graph export,
private field access, runtime state capture, and vendor-specific integrations
for Behavior Designer, SensorToolkit, A* Pathfinding, Gore Simulator, RayFire,
Animancer, and Dialogue System. All via reflection with no compile-time
dependencies — graceful fallback if the asset isn't installed.
How They Work Together
execute_script with a file path, method name, and JSON argumentsTemp/[ToolName]/result.json with structured error handling for missing assets or inaccessible fieldsmcp__coplay-mcp__execute_script( filePath: "Assets/_Game/Scripts/Editor/OdinTools/BehaviorTreeDebugger.cs", methodName: "InspectTree", arguments: '{"gameObjectPath": "Enemy_KittySlasher"}' ) // → reads Temp/BehaviorTreeDebugger/tree_structure.json
No Hard Dependencies — Pure Reflection
The critical architectural constraint: no compile-time references to
vendor types. Every integration resolves types at runtime via
AppDomain.CurrentDomain.GetAssemblies():
private static void ResolveTypes() { if (_typesResolved) return; foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (_behaviorTreeType == null) _behaviorTreeType = assembly.GetType( "Opsive.BehaviorDesigner.Runtime.BehaviorTree"); if (_taskType == null) _taskType = assembly.GetType( "Opsive.BehaviorDesigner.Runtime.Tasks.Task"); if (_sharedVariableType == null) _sharedVariableType = assembly.GetType( "Opsive.BehaviorDesigner.Runtime.SharedVariable"); } _typesResolved = true; }
If the asset isn't installed, the type stays null and the tool returns a structured error. No compile errors, no missing package issues. The same OdinTools folder ports to any Unity project — install only the vendor assets you use.
Recursive Deep Serialization — InspectDeep
The core method in OdinInspector.cs. Takes any component on any
GameObject and serializes it to JSON with configurable recursion depth:
public static void InspectDeep( string gameObjectPath, string componentType, int maxDepth = 3) { var go = GameObject.Find(gameObjectPath); Component comp = FindComponent(go, componentType); var fields = comp.GetType().GetFields( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var visited = new HashSet<object>(); // circular reference guard foreach (var field in fields) properties[field.Name] = SerializeValueDeep(value, 0, maxDepth, visited); // → writes Temp/OdinInspector/deep_result.json }
SerializeValueDeep handles: primitives, enums,
Vector2/3/4, Quaternion, Color,
AnimationCurve, UnityObject references (with asset
paths and GUIDs), IList recursion (up to 50 items per array), and
circular reference detection. At max depth it truncates with:
{ "_truncated": true, "_type": "MAnimalState", "_reason": "Max depth 3 exceeded" }
This signals the AI to call InspectDeep again with a more
targeted path if it needs to go deeper.
13 Scripts, 75+ Methods
| Script | Target Asset | Key Methods |
|---|---|---|
BehaviorTreeDebugger | Behavior Designer Pro | InspectTree, InspectRuntimeExecution, InspectSubtree |
SensorToolkitInspector | SensorToolkit 2 | InspectSensors, InspectDetections, PulseSensor, CheckDetection |
AStarPathfindingInspector | A* Pathfinding Pro | InspectAI, InspectGraphs, InspectPath, CheckWalkable |
GoreSimulatorInspector | PampelGames Gore Simulator | InspectGoreSimulator, InspectGoreBones, InspectModules |
RayFireInspector | RayFire | Destruction state, fragments, physics config |
AnimatorInspector | Unity Animator | State machine hierarchy, transitions, parameters, blend trees |
RuntimeInspector | Any component (Play Mode) | Physics state, navmesh paths, animator runtime, rigidbody velocities |
AnimancerInspector | Animancer Pro | Playable graph, state weights and speeds |
DialogueSystemInspector | Dialogue System for Unity | Conversation graphs, node conditions |
OdinInspector | Any component | InspectDeep — generic deep serialization for unlisted assets |
AssetAuditor | Any prefab/scene | Coverage gap analysis, prioritized by component frequency |
VendorConfigSnapshot | Any vendor asset | Snapshot configs to committed JSON for diffing |
Vendor-Specific Inspectors
Behavior Designer Pro
BD Pro is a fully visual behavior tree editor. All tree data is serialized
into a private m_Data field as BehaviorData, containing
an array of Task objects (each with m_ParentIndex /
m_ChildIndices defining the tree structure), SharedVariable
objects for inter-task communication, and task-specific serialized fields.
None of this surfaces through standard component inspection.
InspectTree accesses m_Data, walks m_Tasks,
and outputs the complete tree:
{
"treeData": {
"taskCount": 12,
"tasks": [
{
"index": 0,
"type": "Selector",
"category": "Composite",
"friendlyName": "Root",
"childIndices": [1, 5],
"parentIndex": -1
},
{
"index": 1,
"type": "Sequence",
"category": "Composite",
"friendlyName": "Chase And Attack",
"childIndices": [2, 3, 4],
"parentIndex": 0,
"fields": {
"targetVariable": {
"type": "SharedGameObject",
"name": "Target",
"isShared": true,
"value": null
}
}
}
],
"variables": [
{ "type": "SharedFloat", "name": "AttackRange", "value": 2.5 },
{ "type": "SharedBool", "name": "EnemyDetected", "value": false }
]
}
}
Parent/child indices reconstruct the full tree hierarchy. Task categories (Composite/Decorator/Conditional/Action), SharedVariable bindings, and all task-specific fields are included.
InspectRuntimeExecution captures the currently executing task
via BehaviorManager.instance during Play Mode.
InspectSubtree inspects ScriptableObject-based subtrees loaded
from disk — same structure as scene inspection.
SensorToolkit 2
SensorToolkit stores sensor configuration in internal properties under the
Micosmo.SensorToolkit namespace. Detection state exists only in
runtime registries.
InspectSensors resolves Sensor,
RangeSensor, RaySensor, TriggerSensor,
LOSSensor, Signal types and outputs shape, radius,
pulse mode/interval, and detection layer masks with human-readable layer names.
InspectDetections (Play Mode) accesses the Detections
and Signals properties: every currently detected GameObject, signal
strength per detection, nearest detection, signal bounds.
PulseSensor triggers a sensor pulse and captures results.
CheckDetection checks if a specific target is detected with
signal strength data.
A* Pathfinding Pro
InspectAI finds AIPath/AILerp/RichAI
on the target and reads: maxSpeed, canSearch, canMove, destination,
reachedDestination, hasPath, velocity, remainingDistance, plus AIPath-specific
fields (maxAcceleration, rotationSpeed, slowdownDistance).
InspectGraphs accesses the AstarPath.active singleton
(note: AstarPath lives in the global namespace, not
Pathfinding) and reads per-graph: type, name, node count, grid
dimensions, node size, slope/climb limits, bounds.
InspectPath (Play Mode) captures the actual computed path:
waypoint positions, path length, steering target, distance to destination.
CheckWalkable reports walkability for any world position.
Gore Simulator
InspectGoreSimulator resolves types from
PampelGames.GoreSimulator and reads: cut/decal materials,
initialization state, all four module lists (gore, cut, explosion, ragdoll),
bone list with collider/joint/rigidbody presence, skinned mesh renderer info.
InspectGoreBones walks the hierarchy for GoreBone
components. InspectModules provides detailed module inspection.
AssetAuditor — Coverage Gap Analysis
AssetAuditor.cs scans any prefab, folder, or entire scene and
produces a coverage report: full coverage (dedicated inspector exists), partial
coverage (InspectDeep reaches it but no vendor-specific methods),
or gap (no coverage, new integration needed). Gaps are prioritized by frequency
of occurrence across the scanned scope.
Adding New Integrations
Each new asset integration follows the same template documented in
ODINTOOLS_MANIFEST.md:
[AssetName]Inspector.cs in the OdinTools folderResolveTypes() using AppDomain.CurrentDomain.GetAssemblies()Temp/[AssetName]/result.jsonODINTOOLS_MANIFEST.md
The InspectDeep generic fallback in OdinInspector.cs
covers any component that doesn't yet have a dedicated inspector — it
won't surface vendor-specific runtime state, but it will recursively serialize
all fields to the configured depth. Run AssetAuditor on the most
complex prefabs/scenes in the project and fix the highest-frequency gaps first.
Layer 2: CoPlay MCP + OdinTools Reflection — The Secret Weapon
For everything the AI needs to read, inspect, and modify that it didn't author — particularly the third-party asset library — the CoPlay MCP bridge + OdinTools reflection suite provides deep runtime visibility into opaque, binary-serialized, inspector-driven Unity components.
Most AI-assisted Unity workflows have one layer or the other. This has both, and each covers the other's blind spots.
The rule going forward: each new tool added to the stack gets an OdinTools integration following the established pattern.
Suite created January 26, 2026. 13 scripts, 75+ methods, single commit
fa3fe44e.