/hz-unity-placement
Ensures accurate object placement in Unity projects targeting Meta Quest and Horizon OS by using Renderer and Collider bounds when objects are added, moved, or positioned relative to other objects.
$ npx -y skills add meta-quest/agentic-tools --skill hz-unity-placement --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/hz-unity-placement
Context preview
The summary Claude sees to decide when to auto-load this skill.
Ensures accurate object placement in Unity projects targeting Meta Quest and Horizon OS by using Renderer and Collider bounds when objects are added, moved, or positioned relative to other objects.
SKILL.md
hz-unity-placement.SKILL.mdname: hz-unity-placement
license: Apache-2.0
description: Ensures accurate object placement in Unity projects targeting Meta Quest and Horizon OS by using Renderer and Collider bounds when objects are added, moved, or positioned relative to other objects.
Unity Object Placement with Bounding Boxes
This skill ensures that when placing, moving, or positioning Unity GameObjects relative to other objects, proper bounding box calculations are used to prevent overlaps and ensure accurate placement.
When to use this skill
Use this skill automatically whenever:
- Placing an object relative to another (on top of, beside, above, below, in front of, behind)
- Moving objects to specific positions near other objects
- Instantiating prefabs in relation to existing scene objects
- Positioning imported models relative to scene objects
- Any spatial relationship between GameObjects is specified
Automatic Triggers (invoke WITHOUT user asking)
**IMPORTANT**: Proactively invoke this skill immediately when you detect ANY of these patterns:
Placement Language Triggers
- User says **"place X on Y"** or **"put X on Y"**
- User says **"place X next to Y"** or **"put X beside Y"**
- User says **"place X to the left/right of Y"**
- User says **"place X in front of/behind Y"**
- User says **"place X above/below Y"**
- User says **"position X near/around Y"**
- User says **"arrange X on/around Y"**
- User requests **"X meters/units to the left/right/front/back of Y"**
Multi-Object Scenarios
- **Before ANY** GameObject position modification involving multiple objects and spatial relationships
- When importing models that will be positioned relative to existing objects
- When arranging/organizing multiple objects in a scene
- When setting up object hierarchies with spatial relationships
Distance-Based Placement
- User specifies distances: "2 meters to the left", "0.5 units above", etc.
- Combine specified distance with bounding box calculations
- Example: "1 meter to the right" = `refMax.x + 1.0 + targetExtents.x`
Example Scenarios
Auto-Invoke Skill (Do These Immediately)
**Example 1**: "Place all objects on the tables"
- **Action**: Invoke unity-placement skill immediately
- **Why**: Multiple objects being placed relative to tables
**Example 2**: "Put the mug on the table"
- **Action**: Invoke unity-placement skill
- **Why**: Single object placement with "on" relationship
**Example 3**: "Place the lamp next to the clock"
- **Action**: Invoke unity-placement skill
- **Why**: "next to" indicates horizontal spatial relationship
- **Process**: Get both bounds, place lamp beside clock using `refMax.x + targetExtents.x`
**Example 4**: "Position the book 0.5 meters to the left of the pen"
- **Action**: Invoke unity-placement skill
- **Why**: Distance-based placement with spatial relationship
- **Process**: Get bounds, calculate: `penMin.x - 0.5 - bookExtents.x`
Don't Invoke Skill (Direct Operations)
**Example 1**: "Move object to [5, 10, 3]"
- **Why**: Direct coordinates provided, no relative positioning
**Example 2**: "Set the cube's position to (0, 0, 0)"
- **Why**: Absolute position, no reference object
Core principle
**ALWAYS get bounding box information before calculating positions.**
Never assume object sizes - always retrieve actual bounds from Renderer or Collider components using whatever Unity MCP tools are available.
Instructions
Step 1: Identify the objects involved
When the user requests object placement: 1. Identify the **target object** (the one being placed/moved) 2. Identify the **reference object** (the one it's being placed relative to) 3. Note the desired **spatial relationship** (on, beside, above, etc.)
Step 2: Get bounding box information
For BOTH objects, retrieve bounds using available Unity MCP tools:
1. Find each object in the scene by name or path 2. Query the object's components to extract bounds information 3. Look for `MeshRenderer` or `Collider` components and their `bounds` property
**Understanding bounds types in Unity:**
| Property | Space | Accounts for rotation? | Use when | |----------|-------|----------------------|----------| | `Renderer.bounds` | **World** | Yes (AABB enclosing rotated mesh) | Placing objects in the scene — preferred for placement | | `Renderer.localBounds` | **Local** | No (ignores rotation) | Comparing intrinsic object sizes without rotation effects | | `Collider.bounds` | **World** | Yes (AABB enclosing rotated collider) | Placing objects when no Renderer exists |
**Always prefer world-space bounds** (`Renderer.bounds` or `Collider.bounds`) for placement. These already account for the object's position, rotation, and scale — no manual conversion needed.
Step 3: Use world bounds directly (or convert from local)
**If using world-space bounds** (preferred — from `Renderer.bounds` or `Collider.bounds`):
The values are ready to use directly:
worldCenter = bounds.center // already in world space
worldMin = bounds.min // already in world space
worldMax = bounds.max // already in world space
size = bounds.size // world-space AABB dimensions
extents = bounds.extents // half of size
**If using local bounds** (from `Renderer.localBounds` or manual component data):
Convert to world space by adding the object's position:
worldCenter = position + localBounds.center
worldMin = worldCenter - (localBounds.size / 2)
worldMax = worldCenter + (localBounds.size / 2)
**Note on rotation:** Local bounds ignore rotation. If converting from local bounds on a rotated object, the calculated AABB will not reflect the actual world-space footprint. Prefer world-space bounds whenever possible.
Store these values for each object:
- `worldCenter`: [x, y, z]
- `size`: [width, height, depth]
- `extents`: [width/2, height/2, depth/2]
Step 4: Calculate placement position
Based on the spatial relationship, calculate the target position:
**On top of*
Read more
name: hz-unity-placement license: Apache-2.0 description: Ensures accurate object placement in Unity projects targeting Meta Quest and Horizon OS by using Renderer and Collider bounds when objects are added, moved, or positioned relative to other objects.
Unity Object Placement with Bounding Boxes
This skill ensures that when placing, moving, or positioning Unity GameObjects relative to other objects, proper bounding box calculations are used to prevent overlaps and ensure accurate placement.
When to use this skill
Use this skill automatically whenever:
- Placing an object relative to another (on top of, beside, above, below, in front of, behind)
- Moving objects to specific positions near other objects
- Instantiating prefabs in relation to existing scene objects
- Positioning imported models relative to scene objects
- Any spatial relationship between GameObjects is specified
Automatic Triggers (invoke WITHOUT user asking)
**IMPORTANT**: Proactively invoke this skill immediately when you detect ANY of these patterns:
Placement Language Triggers
- User says **"place X on Y"** or **"put X on Y"**
- User says **"place X next to Y"** or **"put X beside Y"**
- User says **"place X to the left/right of Y"**
- User says **"place X in front of/behind Y"**
- User says **"place X above/below Y"**
- User says **"position X near/around Y"**
- User says **"arrange X on/around Y"**
- User requests **"X meters/units to the left/right/front/back of Y"**
Multi-Object Scenarios
- **Before ANY** GameObject position modification involving multiple objects and spatial relationships
- When importing models that will be positioned relative to existing objects
- When arranging/organizing multiple objects in a scene
- When setting up object hierarchies with spatial relationships
Distance-Based Placement
- User specifies distances: "2 meters to the left", "0.5 units above", etc.
- Combine specified distance with bounding box calculations
- Example: "1 meter to the right" = `refMax.x + 1.0 + targetExtents.x`
Example Scenarios
Auto-Invoke Skill (Do These Immediately)
**Example 1**: "Place all objects on the tables"
- **Action**: Invoke unity-placement skill immediately
- **Why**: Multiple objects being placed relative to tables
**Example 2**: "Put the mug on the table"
- **Action**: Invoke unity-placement skill
- **Why**: Single object placement with "on" relationship
**Example 3**: "Place the lamp next to the clock"
- **Action**: Invoke unity-placement skill
- **Why**: "next to" indicates horizontal spatial relationship
- **Process**: Get both bounds, place lamp beside clock using `refMax.x + targetExtents.x`
**Example 4**: "Position the book 0.5 meters to the left of the pen"
- **Action**: Invoke unity-placement skill
- **Why**: Distance-based placement with spatial relationship
- **Process**: Get bounds, calculate: `penMin.x - 0.5 - bookExtents.x`
Don't Invoke Skill (Direct Operations)
**Example 1**: "Move object to [5, 10, 3]"
- **Why**: Direct coordinates provided, no relative positioning
**Example 2**: "Set the cube's position to (0, 0, 0)"
- **Why**: Absolute position, no reference object
Core principle
**ALWAYS get bounding box information before calculating positions.**
Never assume object sizes - always retrieve actual bounds from Renderer or Collider components using whatever Unity MCP tools are available.
Instructions
Step 1: Identify the objects involved
When the user requests object placement: 1. Identify the **target object** (the one being placed/moved) 2. Identify the **reference object** (the one it's being placed relative to) 3. Note the desired **spatial relationship** (on, beside, above, etc.)
Step 2: Get bounding box information
For BOTH objects, retrieve bounds using available Unity MCP tools:
1. Find each object in the scene by name or path 2. Query the object's components to extract bounds information 3. Look for `MeshRenderer` or `Collider` components and their `bounds` property
**Understanding bounds types in Unity:**
| Property | Space | Accounts for rotation? | Use when | |----------|-------|----------------------|----------| | `Renderer.bounds` | **World** | Yes (AABB enclosing rotated mesh) | Placing objects in the scene — preferred for placement | | `Renderer.localBounds` | **Local** | No (ignores rotation) | Comparing intrinsic object sizes without rotation effects | | `Collider.bounds` | **World** | Yes (AABB enclosing rotated collider) | Placing objects when no Renderer exists |
**Always prefer world-space bounds** (`Renderer.bounds` or `Collider.bounds`) for placement. These already account for the object's position, rotation, and scale — no manual conversion needed.
Step 3: Use world bounds directly (or convert from local)
**If using world-space bounds** (preferred — from `Renderer.bounds` or `Collider.bounds`):
The values are ready to use directly:
worldCenter = bounds.center // already in world space worldMin = bounds.min // already in world space worldMax = bounds.max // already in world space size = bounds.size // world-space AABB dimensions extents = bounds.extents // half of size
**If using local bounds** (from `Renderer.localBounds` or manual component data):
Convert to world space by adding the object's position:
worldCenter = position + localBounds.center worldMin = worldCenter - (localBounds.size / 2) worldMax = worldCenter + (localBounds.size / 2)
**Note on rotation:** Local bounds ignore rotation. If converting from local bounds on a rotated object, the calculated AABB will not reflect the actual world-space footprint. Prefer world-space bounds whenever possible.
Store these values for each object:
- `worldCenter`: [x, y, z]
- `size`: [width, height, depth]
- `extents`: [width/2, height/2, depth/2]
Step 4: Calculate placement position
Based on the spatial relationship, calculate the target position:
**On top of*
Agentic skills and tools for Meta Quest and Horizon OS development.
Repo: meta-quest/agentic-tools
Other skills on meta-vr.
- /hz-android-2d-porting
Guides porting existing Android 2D apps to Meta Quest and Horizon OS — input adaptation, panel layout, and design requirements. Use when adapting a mobile Android app for Quest.
Open skill - /hz-api-upgrade
Upgrades Meta Quest apps to newer Horizon OS SDK versions — migration guides, deprecated API replacements, changelog. Use when updating SDK versions or fixing deprecated API warnings.
Open skill - /hz-immersive-designer
Guides design of comfortable, intuitive VR/MR experiences for Meta Quest and Horizon OS — comfort guidelines, interaction patterns, spatial layout, accessibility. Use during UX design review or when evaluating comfort and accessibility.
Open skill - /hz-iwsdk-webxr
Builds WebXR experiences for Meta Quest and Horizon OS using the Immersive Web SDK (IWSDK) — ECS architecture, Three.js integration, spatial UI. Use when creating web-based VR/MR apps for Quest Browser.
Open skill - /hz-new-project-creation
Scaffolds new Meta Quest and Horizon OS projects with recommended settings for Unity, Unreal, Android/Spatial SDK, or WebXR. Use when creating a new Quest app from scratch.
Open skill - /hz-perfetto-debug
Analyzes Meta Quest and Horizon OS VR performance using Perfetto traces — frame timing, CPU/GPU bottlenecks, render pass analysis. Use when profiling frame drops, jank, or thermal issues on Quest devices.
Open skill

