Skip to content
Development
Skill

/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.

From plugin
meta-vr
17629 skills1 hook1 MCP
Install
$ npx -y skills add meta-quest/agentic-tools --skill hz-unity-placement --agent claude-code

How 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.md
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*

Read more
Ships withmeta-vr

Agentic skills and tools for Meta Quest and Horizon OS development.

Get the whole plugin