mcpField
U
unity-xr

unity-xr

github.com/nice-wolf-studio開発4063 回インストール7 週間前に更新
リポジトリ

unity-xr について

VR、MR、AR アプリを開発する Unity 6 開発者向けの XR ガイドです。プラットフォーム設定、インタラクション、移動、デバイス入力を含む Unity の XR 構成を解説します。

主な機能

  1. 01OpenXR の設定とプラットフォーム検証
  2. 02VR・AR インタラクションコンポーネント
  3. 03移動プロバイダーと変換処理
  4. 04AR Foundation のサブシステム
  5. 05手・コントローラー・視線入力
  6. 06Editor でのインタラクションテスト

活用シーン

  1. 01対象ハードウェア向けの OpenXR 設定
  2. 02オブジェクトの把持とテレポートの実装
  3. 03AR トラッキングとジェスチャーの追加
  4. 04XR ハードウェアなしでの操作テスト

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/nice-wolf-studio/unity-claude-skills --skill unity-xr

インストール後、Claude Code で/unity-xrを入力して読み込まれたか確認します。

同梱ファイルreferences/xr-toolkit.md

詳細

Unity 6 XR 開発ガイド

出典:Unity 6.3 LTS ドキュメント(6000.3)

XR アーキテクチャの概要

Unity では、XR は次の 3 種類のアプリケーションを含むものと定義されています。

  • 仮想現実(VR) -- ユーザーを取り囲む独立した環境をアプリケーションでシミュレートします
  • 複合現実(MR) -- 仮想環境と現実世界の環境を組み合わせ、インタラクションを実現します
  • 拡張現実(AR) -- 現実世界の視界にコンテンツを重ねて表示します

Unity 6 の XR スタックは、次の要素で構成されます。

  1. XR プラグイン管理 -- プラットフォームの XR SDK を検出して読み込みます
  2. OpenXR プラグイン -- Khronos によるオープンかつロイヤリティフリーな、クロスプラットフォーム XR の標準規格です
  3. XR Interaction Toolkit(XRI) -- 高レベルのコンポーネントベースのインタラクションシステムです
  4. AR Foundation -- プロバイダープラグインアーキテクチャを備えたクロスプラットフォーム AR フレームワークです
  5. Input System -- OpenXR と XRI が必要とするアクションベースの入力システムです

XR プラグイン管理

Edit > Project Settings > XR Plug-in Management から設定します。

  • プラットフォームごとに OpenXR と必要な Feature Groups を有効にします
  • OpenXR の Features タブで Interaction Profiles(コントローラーマッピング)を選択します
  • ビルド時の互換性チェックを行うには、Project Validation を実行します
  • アクティブなランタイムが対象ハードウェアと一致していることを確認します
サポートされるランタイムとプラットフォーム
ランタイム対象グラフィックス
Windows Mixed RealityWin64DX11
Oculus PC + LinkWin64DX11
Meta QuestAndroid arm64Vulkan
Magic Leap 2Android x64Vulkan
SteamVRWin64DX11
OpenXR インタラクションプロファイル
  • Eye Gaze Interaction
  • HTC Vive Controller
  • Khronos Simple Controller
  • Microsoft Motion Controller
  • Oculus Touch Controller
  • Valve Index Controller
OpenXR スクリプティング API
// Iterate all OpenXR features
var features = OpenXRSettings.Instance.GetFeatures();
foreach (var feature in features)
{
    Debug.Log($"Feature: {feature.name}, Enabled: {feature.enabled}");
}

// Get a specific feature by type
var feature = OpenXRSettings.Instance.GetFeature<MockRuntime>();
if (feature != null)
{
    Debug.Log($"MockRuntime Enabled: {feature.enabled}");
}

// Iterate feature groups (Editor only)
var featureSets = OpenXRFeatureSetManager.FeatureSetsForBuildTarget(
    BuildTargetGroup.Standalone
);
foreach (var featureSet in featureSets)
{
    Debug.Log($"Feature Set ID: {featureSet.featureSetId}");
}

XR Interaction Toolkit

パッケージ: com.unity.xr.interaction.toolkit(Unity 6000.3 用 v3.3.1)

VR と AR 向けの高レベルなコンポーネントベースのインタラクションシステムです。基盤となる要素は 3 つあります。

  1. インタラクター -- ユーザー入力を処理し、インタラクションを開始します
  2. インタラクタブル -- ユーザーが操作できるオブジェクトを定義します
  3. Interaction Manager -- インタラクターとインタラクタブルの連携を調整します
インタラクションの状態
状態説明
Hoverインタラクタブルが有効な対象であり、操作の意図を示します
Selectユーザー入力(ボタン/トリガー)によってアクティブなインタラクション(つかむ)が実行されます
Focus選択後、別のインタラクタブルが選択されるまで状態が維持されます
Activate追加のコントロールに割り当てられた、コンテキストに応じた副次的なアクションです
更新ループ
  1. インタラクターから有効な対象リストを取得します
  2. 既存のホバー/フォーカス/選択状態を検証します
  3. 無効な状態を終了します(OnSelectExiting、OnHoverExiting、OnFocusExiting)
  4. 新しい状態に入ります(OnSelectEntering、OnHoverEntering、OnFocusEntering)

処理と状態変更のどちらにおいても、インタラクタブルより先にインタラクターに通知されます。

インタラクターの種類
コンポーネント目的
XR Direct Interactor近距離での(タッチ/つかむ)インタラクション
XR Ray Interactorレイを使った遠距離インタラクション
XR Poke Interactor突く/触れるインタラクション
Near-Far Interactor近接/遠距離のハイブリッドインタラクション
XR Gaze Interactor視線によるインタラクション
XR Socket Interactorスナップポイントを使ったインタラクション
Climb Teleport Interactor登る移動
インタラクタブルの種類
コンポーネント目的
XR Grab Interactableオブジェクトをつかんで操作します
XR Simple Interactable基本的なインタラクションイベント
Climb Interactable登ることができる表面
Teleportation Anchor固定されたテレポート先
Teleportation Areaエリアベースのテレポート対象
Teleportation Multi-Anchor Volume複数のアンカーを持つボリューム
XR Grab Interactable の移動タイプ
  • 瞬間移動 -- 毎フレーム、Transform の位置/回転を設定します。レイテンシーが最も低い一方で、コライダーをすり抜けることがあります。
  • キネマティック -- FixedUpdate 中にキネマティック Rigidbody を更新します。物理演算とビジュアルを同期させます。
  • 速度トラッキング -- Rigidbody の速度/角速度を設定します。衝突の貫通を防ぎますが、遅延が発生する場合があります。
インタラクションの強度

インタラクターとインタラクタブルは、正規化された [0.0, 1.0] のアナログ選択強度を報告します。これは状態変化後に処理されます。

インタラクショングループ

グループには、優先度順に並べられた複数のメンバーインタラクターが含まれ、グループ内で一度にインタラクションできるインタラクターは1つだけです。グループのネストにも対応しています。

API の詳細については、skills/unity-xr/references/xr-toolkit.md を参照してください。

ロコモーションシステム

ロコモーションプロバイダー
プロバイダー説明
テレポーテーションプロバイダーポイントしてテレポートする移動
スナップターンプロバイダー固定角度でユーザーを回転
連続ターンプロバイダー時間をかけて滑らかに回転
連続移動プロバイダー時間をかけて滑らかに移動
グラブ移動プロバイダーコントローラーの移動と逆方向にユーザーを移動
両手グラブ移動プロバイダー2つのコントローラーによる移動、回転、スケーリング
クライムプロバイダークライムインタラクタブルを選択している間の移動
重力プロバイダー接地状態の検出を伴う重力効果
アーキテクチャ
  • ロコモーションメディエーター -- 変換リクエストを管理します。状態は Idle、Preparing、Moving、Ended です。
  • XR ボディトランスフォーマー -- 優先度に基づいて、各 Update で適用する変換をキューに登録します。
  • XR ムーバブルボディ -- XR Origin を、ボディを基準とした変換でラップします。

変換は優先度の昇順で順次適用されます。同じ優先度の変換は、キューの順序で適用されます。

AR Foundation

パッケージ: com.unity.xr.arfoundation(Unity 6000.3 向け v6.3.3)

AR Foundation は、2パッケージ構成のアーキテクチャを採用しています。

  • ベースパッケージ -- AR 機能のインターフェースを提供します(単体では機能しません)。
  • プロバイダープラグイン -- プラットフォーム固有の実装を提供します。
対応プラットフォーム
プラットフォームプロバイダープラグイン
AndroidGoogle ARCore XR Plug-in
iOSApple ARKit XR Plug-in
visionOSApple visionOS XR Plug-in
HoloLens 2OpenXR Plug-in
Meta QuestUnity OpenXR: Meta
Android XRUnity OpenXR: Android XR
機能サブシステム
機能マネージャーコンポーネント
セッション管理ARSession
デバイストラッキングARTrackedPoseDriver
カメラARCameraManager
平面検出ARPlaneManager
画像トラッキングARTrackedImageManager
顔トラッキングARFaceManager
ボディトラッキングARHumanBodyManager
オブジェクトトラッキングARTrackedObjectManager
ポイントクラウドARPointCloudManager
レイキャスティングARRaycastManager
アンカーARAnchorManager
メッシュ生成ARMeshManager
環境プローブAREnvironmentProbeManager
オクルージョンAROcclusionManager
バウンディングボックス検出ARBoundingBoxManager
参加者ARParticipantManager
AR ジェスチャーインタラクション(XRI)
  • TouchscreenGestureInputController -- 画面のタッチをジェスチャーイベントにマッピングします。
  • ARTransformer -- 配置、選択、移動、回転、スケーリングのジェスチャーを処理します。
  • スクリーンスペース入力コンポーネントは XRRayInteractor に入力を渡します。

ハンドトラッキング

ハンドトラッキングデバイスは、HandTracking 特性と CommonUsages.HandData 機能を公開します。

Hand handData;
if (device.TryGetFeatureValue(CommonUsages.handData, out handData))
{
    // Get wrist bone
    Bone rootBone;
    if (handData.TryGetRootBone(out rootBone))
    {
        Vector3 wristPosition;
        rootBone.TryGetPosition(out wristPosition);
    }

    // Get finger bones (up to 21 bones per hand)
    List<Bone> fingerBones = new List<Bone>();
    if (handData.TryGetFingerBones(HandFinger.Index, fingerBones))
    {
        foreach (Bone bone in fingerBones)
        {
            Vector3 bonePosition;
            bone.TryGetPosition(out bonePosition);
        }
    }
}

各ボーンには、位置、向き、親/子への参照が含まれます。

コントローラーとハプティクス

入力デバイスへのアクセス
using UnityEngine.XR;

// Get devices by role
var devices = new List<InputDevice>();
InputDevices.GetDevicesWithRole(InputDeviceRole.RightHanded, devices);

if (devices.Count > 0)
{
    var device = devices[0];

    // Read trigger button
    bool triggerPressed;
    if (device.TryGetFeatureValue(CommonUsages.triggerButton,
        out triggerPressed) && triggerPressed)
    {
        // Handle trigger press
    }

    // Read joystick axis
    Vector2 axis;
    if (device.TryGetFeatureValue(CommonUsages.primary2DAxis, out axis))
    {
        // Use axis.x, axis.y
    }
}
一般的な入力の用途
用途型説明
primary2DAxisVector2サムスティック/タッチパッド
triggerfloatトリガー軸(0~1)
gripfloatグリップ軸(0~1)
triggerButtonboolトリガーが押されている
gripButtonboolグリップが押されている
primaryButtonboolA/X ボタン
secondaryButtonboolB/Y ボタン
menuButtonboolメニューボタン
userPresenceboolユーザーがヘッドセットを装着している
触覚フィードバック
HapticCapabilities capabilities;
if (device.TryGetHapticCapabilities(out capabilities))
{
    if (capabilities.supportsImpulse)
    {
        uint channel = 0;
        float amplitude = 0.5f;  // 0-1
        float duration = 1.0f;   // seconds
        device.SendHapticImpulse(channel, amplitude, duration);
    }
}
アイトラッキング
Eyes eyeData;
if (device.TryGetFeatureValue(CommonUsages.eyesData, out eyeData))
{
    // Access left/right eye positions, gaze direction, blink amounts
}
デバイスのライフサイクル
// Subscribe to connection events
InputDevices.deviceConnected += OnDeviceConnected;
InputDevices.deviceDisconnected += OnDeviceDisconnected;

// Always validate before use
if (device.isValid)
{
    // Safe to read features
}
トラッキングの原点
var subsystems = new List<XRInputSubsystem>();
SubsystemManager.GetInstances<XRInputSubsystem>(subsystems);
if (subsystems.Count > 0)
{
    subsystems[0].TrySetTrackingOriginMode(TrackingOriginModeFlags.Floor);

    // Get play area boundary
    List<Vector3> boundaryPoints = new List<Vector3>();
    if (subsystems[0].TryGetBoundaryPoints(boundaryPoints))
    {
        // Points are floor-level, clockwise-ordered
    }
}

一般的なパターン

基本的な XR リグのセットアップ
  1. シーンに XR Origin を追加します(カメラのオフセットとボディトラッキングを提供します)
  2. XR Interaction Manager を追加します(単一のインスタンスですべてのインタラクションを調整します)
  3. カメラとコントローラーに Tracked Pose Driver を追加します
  4. コントローラーの GameObject に Interactors を追加します
  5. インタラクティブなオブジェクトに Interactables を追加します
オブジェクトをつかむパターン
// On the grabbable object:
// 1. Add Rigidbody
// 2. Add Collider
// 3. Add XR Grab Interactable component
// Configure Movement Type based on needs:
//   - Instantaneous: lowest latency, no physics
//   - Kinematic: physics-synced, moderate latency
//   - Velocity Tracking: full physics, potential lag
推奨されるグラブ階層
Grab Interactable (Rigidbody, XRGrabInteractable)
  ├── Visuals (MeshFilter, MeshRenderer)
  ├── Collider (BoxCollider, MeshCollider)
  └── Visual Feedback (Affordance providers)
XR Interaction Simulator

XR Interaction Simulator コンポーネントを使用すると、物理デバイスなしでエディター内のインタラクションをテストできます。

避けるべきパターン

  • Interaction Manager がない -- すべての Interactor と Interactable には、共有の Interaction Manager が必要です。設定を忘れると、何も表示されずに失敗します。
  • OpenXR でレガシー Input Manager を使用する -- OpenXR には新しい Input System パッケージが必要です。レガシーな Input.GetAxis() は動作しません。
  • デバイスの検証を省略する -- 機能を読み取る前に、必ず InputDevice.isValid を確認してください。デバイスはいつでも切断される可能性があります。
  • ソケットの Attach Ease In Time を無視する -- Socket Interactor のビジュアルにちらつきが発生します。軽減するには、Attach Ease In Time を少なくとも 0.15 に設定してください。
  • XR プロバイダーでマウス/ワールド空間 UI を使用する -- XR Plug-in Providers を有効にすると、標準のマウスとワールド空間 UI が機能しなくなります。代わりに XR UI Input Module を使用してください。
  • コンピュートシェーダーのサポートを確認しない -- コンピュートシェーダーに対応していないプラットフォームでは、GPU ベースの機能が何も表示されずに失敗する可能性があります。SystemInfo.supportsComputeShaders を確認してください。
  • ビネットなしでテレポートする -- Tunneling Vignette Controller を使用せずに瞬時にテレポートすると、乗り物酔いが発生します。
  • UI Toolkit で Poke Interactor を使用する -- 既知の制限事項です。代わりに、Tracked Device Graphic Raycaster を使用した Canvas ベースの UI を使用してください。

主要 API クイックリファレンス

クラス名前空間目的
XROriginUnity.XR.CoreUtilsカメラリグとトラッキング空間
XRInteractionManagerUnityEngine.XR.Interaction.Toolkitインタラクションの調整
XRBaseInteractorUnityEngine.XR.Interaction.ToolkitInteractor の基底クラス
XRBaseInteractableUnityEngine.XR.Interaction.ToolkitInteractable の基底クラス
XRGrabInteractableUnityEngine.XR.Interaction.Toolkitつかめるオブジェクト
InputDeviceUnityEngine.XR物理 XR デバイス
InputDevicesUnityEngine.XRデバイスの検出
CommonUsagesUnityEngine.XR標準入力機能名
OpenXRSettingsUnityEngine.XR.OpenXROpenXR の設定
ARSessionUnityEngine.XR.ARFoundationAR セッションの管理
ARPlaneManagerUnityEngine.XR.ARFoundation平面の検出
ARAnchorManagerUnityEngine.XR.ARFoundation空間アンカー

関連スキル

  • unity-input -- Input System パッケージ、アクションマップ、バインディング
  • unity-graphics -- レンダリングパイプライン、XR 向けのシェーダーに関する考慮事項

追加リソース

コメント