mcpField
A
axiom-realitykit-diag

axiom-realitykit-diag

github.com/charleswiltgen開発1.2k133 回インストール今日更新
リポジトリ

axiom-realitykit-diag について

RealityKit のシーン、AR、操作、描画、物理、同期に関する問題を調べる開発者向け診断スキルです。症状別の確認手順とデバッグ可視化、コードによる診断をまとめています。

主な機能

  1. 01症状別のRealityKit確認項目
  2. 02デバッグ可視化の案内
  3. 03表示とトラッキングの診断
  4. 04ジェスチャーと衝突の確認
  5. 05性能とマテリアルの確認
  6. 06物理と同期のトラブル対応

活用シーン

  1. 01シーンにエンティティが表示されない場合の調査
  2. 023Dジェスチャーが反応しない原因の追跡
  3. 03フレーム低下やマテリアル異常の確認
  4. 04物理やマルチプレイヤー同期の診断

インストール

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

$npx skills add https://github.com/charleswiltgen/axiom --skill axiom-realitykit-diag

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

詳細

RealityKit の診断

よくある RealityKit の問題を、所要時間の注釈付きで体系的に診断します。

この診断スキルを使うタイミング

次のような場合にこのスキルを使います。

  • エンティティを追加したのにシーンに表示されない
  • AR アンカーがトラッキングされない、またはコンテンツが浮いている
  • 3D エンティティでタップ/ドラッグジェスチャに反応しない
  • フレームレートが低下する、またはカクつく
  • マテリアルの見た目がおかしい(暗すぎる、明るすぎる、色が正しくない)
  • マルチプレイヤーのエンティティがデバイス間で同期されない
  • 物理ボディ同士が衝突しない、またはすり抜ける

RealityKit のアーキテクチャパターンとベストプラクティスについては、axiom-realitykit を参照してください。API リファレンスについては、axiom-realitykit-ref を参照してください。


必須の最初の手順:デバッグ表示を有効にする

所要時間:当てずっぽうのデバッグに何時間もかけるのに対し、10 秒

// In your RealityView or ARView setup
#if DEBUG
// Xcode: Debug → Attach to Process → Show RealityKit Statistics
// Or enable in code:
arView.debugOptions = [
    .showStatistics,       // Entity count, draw calls, FPS
    .showPhysics,          // Collision shapes
    .showAnchorOrigins,    // Anchor positions
    .showAnchorGeometry    // Detected plane geometry
]
#endif

.showPhysics で衝突形状が見えない場合、CollisionComponent がないか、設定に誤りがあります。ジェスチャや物理のデバッグを始める前に、衝突の問題を修正してください。


症状 1:エンティティが表示されない

短縮できる時間:30~60 分 → 2~5 分

Entity added but nothing appears
│
├─ Is the entity added to the scene?
│   └─ NO → Add to RealityView content:
│        content.add(entity)
│        ✓ Entities must be in the scene graph to render
│
├─ Does the entity have a ModelComponent?
│   └─ NO → Add mesh and material:
│        entity.components[ModelComponent.self] = ModelComponent(
│            mesh: .generateBox(size: 0.1),
│            materials: [SimpleMaterial(color: .red, isMetallic: false)]
│        )
│        ✓ Bare Entity is invisible — it's just a container
│
├─ Is the entity's scale zero or nearly zero?
│   └─ CHECK → Print: entity.scale
│        USD models may import with unexpected scale.
│        Try: entity.scale = SIMD3(repeating: 0.01) for meter-scale models
│
├─ Is the entity behind the camera?
│   └─ CHECK → Print: entity.position(relativeTo: nil)
│        In RealityKit, -Z is forward (toward screen).
│        Try: entity.position = SIMD3(0, 0, -0.5) (half meter in front)
│
├─ Is the entity inside another object?
│   └─ CHECK → Move to a known visible position:
│        entity.position = SIMD3(0, 0, -1)
│
├─ Is the entity's isEnabled set to false?
│   └─ CHECK → entity.isEnabled = true
│        Also check parent: entity.isEnabledInHierarchy
│
├─ Is the entity on an untracked anchor?
│   └─ CHECK → Verify anchor is tracking:
│        entity.isAnchored (should be true)
│        If using plane anchor, ensure surface is detected first
│
└─ Is the material transparent or OcclusionMaterial?
    └─ CHECK → Inspect material:
         If using PhysicallyBasedMaterial, check baseColor is not black
         If using blending = .transparent, check opacity > 0
すばやい診断
func diagnoseVisibility(_ entity: Entity) {
    print("Name: \(entity.name)")
    print("Is enabled: \(entity.isEnabled)")
    print("In hierarchy: \(entity.isEnabledInHierarchy)")
    print("Is anchored: \(entity.isAnchored)")
    print("Position (world): \(entity.position(relativeTo: nil))")
    print("Scale: \(entity.scale)")
    print("Has model: \(entity.components[ModelComponent.self] != nil)")
    print("Children: \(entity.children.count)")
}

症状 2:アンカーがトラッキングされない

短縮できる時間:20~45 分 → 3~5 分

AR content not appearing or floating
│
├─ Is the AR session running?
│   └─ For RealityView on iOS 18+, AR runs automatically
│       For ARView, check: arView.session.isRunning
│
├─ Is SpatialTrackingSession configured? (iOS 18+)
│   └─ CHECK → Ensure tracking modes requested:
│        let config = SpatialTrackingSession.Configuration(
│            tracking: [.plane, .object])
│        let result = await session.run(config)
│        if let notSupported = result {
│            // Handle unsupported modes
│        }
│
├─ Is the anchor type appropriate for the environment?
│   ├─ .plane(.horizontal) → Need a flat surface visible to camera
│   ├─ .plane(.vertical) → Need a wall visible to camera
│   ├─ .image → Image must be in "AR Resources" asset catalog
│   ├─ .face → Front camera required (not rear)
│   └─ .body → Full body must be visible
│
├─ Is minimumBounds too large?
│   └─ CHECK → Reduce minimum bounds:
│        AnchorEntity(.plane(.horizontal, classification: .any,
│            minimumBounds: SIMD2(0.1, 0.1)))  // Smaller = detects sooner
│
├─ Is the device supported?
│   └─ CHECK → Plane detection requires A12+ chip
│       Face tracking requires TrueDepth camera
│       Body tracking requires A12+ chip
│
└─ Is the environment adequate?
    └─ CHECK → AR needs:
         - Adequate lighting (not too dark)
         - Textured surfaces (not blank walls)
         - Stable device position during initial detection

症状 3:ジェスチャに反応しない

短縮できる時間:15~30 分 → 2~3 分

Tap/drag on entity does nothing
│
├─ Does the entity have a CollisionComponent?
│   └─ NO → Add collision shapes:
│        entity.generateCollisionShapes(recursive: true)
│        // or manual:
│        entity.components[CollisionComponent.self] = CollisionComponent(
│            shapes: [.generateBox(size: SIMD3(0.1, 0.1, 0.1))])
│        ✓ Collision shapes are REQUIRED for gesture hit testing
│
├─ [visionOS] Does the entity have InputTargetComponent?
│   └─ NO → Add it:
│        entity.components[InputTargetComponent.self] = InputTargetComponent()
│        ✓ Required on visionOS for gesture input
│
├─ Is the gesture attached to the RealityView?
│   └─ CHECK → Gesture must be on the view, not the entity:
│        RealityView { content in ... }
│            .gesture(TapGesture().targetedToAnyEntity().onEnded { ... })
│
├─ Is the collision shape large enough to hit?
│   └─ CHECK → Enable .showPhysics to see shapes
│        Shapes too small = hard to tap.
│        Try: .generateBox(size: SIMD3(repeating: 0.1)) minimum
│
├─ Is the entity behind another entity?
│   └─ CHECK → Front entities may block gestures on back entities
│        Ensure collision is on the intended target
│
└─ Is the entity enabled?
    └─ CHECK → entity.isEnabled must be true
         Disabled entities don't receive input
すばやい診断
func diagnoseGesture(_ entity: Entity) {
    print("Has collision: \(entity.components[CollisionComponent.self] != nil)")
    print("Has input target: \(entity.components[InputTargetComponent.self] != nil)")
    print("Is enabled: \(entity.isEnabled)")
    print("Is anchored: \(entity.isAnchored)")

    if let collision = entity.components[CollisionComponent.self] {
        print("Collision shapes: \(collision.shapes.count)")
    }
}

症状 4:パフォーマンスの問題

短縮できる時間:1~3 時間 → 10~20 分

Frame rate dropping or stuttering
│
├─ How many entities are in the scene?
│   └─ CHECK → Print entity count:
│        var count = 0
│        func countEntities(_ entity: Entity) {
│            count += 1
│            for child in entity.children { countEntities(child) }
│        }
│        Under 100: unlikely to be entity count
│        100-500: review for optimization
│        500+: definitely needs optimization
│
├─ Are mesh/material resources shared?
│   └─ NO → Share resources across identical entities:
│        let sharedMesh = MeshResource.generateBox(size: 0.05)
│        let sharedMaterial = SimpleMaterial(color: .white, isMetallic: false)
│        // Reuse for all instances
│        ✓ RealityKit batches entities with identical resources
│
├─ Is a System creating components every frame?
│   └─ CHECK → Look for allocations in update():
│        Creating ModelComponent, CollisionComponent, or materials
│        every frame causes GC pressure.
│        Cache resources, only update when values change.
│
├─ Are collision shapes mesh-based?
│   └─ CHECK → Replace generateCollisionShapes(recursive: true)
│        with simple shapes (box, sphere, capsule) for dynamic entities
│
├─ Is generateCollisionShapes called repeatedly?
│   └─ CHECK → Call once during setup, not every frame
│
├─ Are there too many physics bodies?
│   └─ CHECK → Dynamic bodies are most expensive.
│        Convert distant/static objects to .static mode.
│        Remove physics from non-interactive entities.
│
└─ Is the model polygon count too high?
    └─ CHECK → Decimate models for real-time use.
         Target: <100K triangles total for mobile AR.
         Use LOD (Level of Detail) for distant objects.

症状 5:マテリアルの見た目がおかしい

短縮できる時間:15~45 分 → 5~10 分

Colors, lighting, or textures look incorrect
│
├─ Is the scene too dark?
│   └─ CHECK → Missing environment lighting:
│        Add DirectionalLightComponent or EnvironmentResource
│        In AR, RealityKit uses real-world lighting automatically
│        In non-AR, you must provide lighting explicitly
│
├─ Is the baseColor set?
│   └─ CHECK → PhysicallyBasedMaterial defaults to white
│        material.baseColor = .init(tint: .red)
│        If using a texture, verify it loaded:
│        try TextureResource(named: "albedo")
│
├─ Is metallic set incorrectly?
│   └─ CHECK → metallic = 1.0 makes surfaces mirror-like
│        Most real objects: metallic = 0.0
│        Only metals (gold, silver, chrome): metallic = 1.0
│
├─ Is the texture semantic wrong?
│   └─ CHECK → Use correct semantic:
│        .color for albedo/baseColor textures
│        .raw for data textures (metallic, roughness)
│        .normal for normal maps
│        .hdrColor for HDR textures
│
├─ Is the model upside down or inside out?
│   └─ CHECK → Try:
│        material.faceCulling = .none (shows both sides)
│        If that fixes it, the model normals are flipped
│
└─ Is blending/transparency unexpected?
    └─ CHECK → material.blending
         Default is .opaque
         For transparency: .transparent(opacity: ...)

症状 6:物理が機能しない

短縮できる時間:20~40 分 → 5~10 分

Objects pass through each other or don't collide
│
├─ Do both entities have CollisionComponent?
│   └─ NO → Both sides of a collision need CollisionComponent
│
├─ Does the moving entity have PhysicsBodyComponent?
│   └─ NO → Add physics body:
│        entity.components[PhysicsBodyComponent.self] = PhysicsBodyComponent(
│            mode: .dynamic)
│
├─ Are collision groups/filters configured correctly?
│   └─ CHECK → Entities must be in compatible groups:
│        Default: group = .default, mask = .all
│        If using custom groups, verify mask includes the other group
│
├─ Is the physics mode correct?
│   ├─ Two .static bodies → Never collide (both immovable)
│   ├─ .dynamic + .static → Correct (common setup)
│   ├─ .dynamic + .dynamic → Both move on collision
│   └─ .kinematic + .dynamic → Kinematic pushes dynamic
│
├─ Is the collision shape appropriate?
│   └─ CHECK → .showPhysics debug option
│        Shape may be too small, offset, or wrong type
│
└─ Are entities on different anchors?
    └─ CHECK → "Physics bodies and colliders affect only
         entities that share the same anchor" (Apple docs)
         Move entities under the same anchor for physics interaction

症状 7:マルチプレイヤーの同期に関する問題

短縮できる時間:30~60 分 → 10~15 分

Entities not appearing on other devices
│
├─ Does the entity have SynchronizationComponent?
│   └─ NO → Add it:
│        entity.components[SynchronizationComponent.self] =
│            SynchronizationComponent()
│
├─ Is the MultipeerConnectivityService set up?
│   └─ CHECK → Verify MCSession is connected before syncing
│
├─ Are custom components Codable?
│   └─ NO → Non-Codable components don't sync
│        struct MyComponent: Component, Codable { ... }
│
├─ Does the entity have an owner?
│   └─ CHECK → Only the owner can modify synced properties
│        Request ownership before modifying:
│        entity.requestOwnership { result in ... }
│
└─ Is the entity anchored?
    └─ CHECK → Unanchored entities may not sync position correctly
         Use a shared world anchor for reliable positioning

よくある間違い

間違い所要時間修正方法
インタラクティブなエンティティに CollisionComponent がない15~30 分entity.generateCollisionShapes(recursive: true)
visionOS で InputTargetComponent がない10~20 分InputTargetComponent() を追加する
間違ったビュー(RealityView 以外)にジェスチャを設定している10~15 分.gesture() を RealityView に設定する
USD モデルのエンティティのスケールが不適切15~30 分単位を確認する:メートルかセンチメートルか
非 AR シーンにライティングがない10~20 分DirectionalLightComponent を追加する
System にエンティティの参照を保存しているクラッシュのデバッグに30~60 分毎フレーム EntityQuery で検索する
コンポーネントが登録されていない10~15 分アプリの初期化時に registerComponent() を呼び出す
システムが登録されていない10~15 分シーンの読み込み前に registerSystem() を呼び出す
異なるアンカー間の物理演算20~40 分相互作用するエンティティを同じアンカーの下に配置する
毎フレーム generateCollisionShapes を呼び出しているパフォーマンスの低下セットアップ時に一度だけ呼び出す

診断クイックリファレンス

症状最初に確認すること短縮できる時間
表示されないModelComponent があるか?スケールは 0 より大きいか?30~60 分
ジェスチャに反応しないCollisionComponent があるか?15~30 分
トラッキングされないアンカーの種類は環境に合っているか?20~45 分
フレーム落ちエンティティ数は?リソースは共有されているか?1~3 時間
色がおかしいライティングはあるか?Metallic の値は?15~45 分
衝突しない両方に CollisionComponent があるか?同じアンカーか?20~40 分
同期しないSynchronizationComponent はあるか?Codable に準拠しているか?30~60 分
シミュレータでは正常、デバイスではクラッシュMetal の機能か?テクスチャ形式か?15~30 分

症状 8:シミュレータでは動作するが、デバイスではクラッシュする

所要時間:15~30 分(モデルの問題と誤診されることがよくあります)

Q1: Is the crash a Metal error (MTLCommandBuffer, shader compilation)?
├─ YES → Simulator uses software rendering, device uses real GPU
│   Common causes:
│   - Custom Metal shaders with unsupported features
│   - Texture formats not supported on device GPU
│   - Exceeding device texture size limits (max 8192x8192 on older)
│   Fix: Check device GPU family, use supported formats
│
└─ NO → Check next

Q2: Is it an out-of-memory crash?
├─ YES → Simulator has more RAM available
│   Common: Large USDZ files with uncompressed textures
│   Fix: Compress textures, reduce polygon count, use LOD
│   Check: USDZ file size (keep < 50MB for reliable loading)
│
└─ NO → Check next

Q3: Is it an AR-related crash (camera, tracking)?
├─ YES → Simulator has no real camera/sensors
│   Fix: Test AR features on device only, use simulator for UI/layout
│
└─ NO → Check device capabilities
    - A12+ required for RealityKit
    - LiDAR for scene reconstruction
    - TrueDepth for face tracking

リソース

WWDC:2019-603、2019-605、2023-10080、2024-10103

ドキュメント:/realitykit、/realitykit/entity、/realitykit/collisioncomponent、/realitykit/physicsbodycomponent

スキル:axiom-realitykit、axiom-realitykit-ref

コメント