RealityKit + ARKit 3 + SwiftUI で宙に浮く Hello World テキスト in 拡張現実


概要

  • iOS の RealityKit を使って拡張現実で Hello World テキストが宙に浮くアプリを作る
  • ARKit 3 は裏側で動作しているが今回は直接操作はしない
  • UI 部分の構築に SwiftUI を使用する
  • Storyboard の状態を修正せず、ソースコードだけで実現する

環境

  • Xcode 11.0
  • RealityKit
  • ARKit 3
  • Swift 5.1
  • SwiftUI
  • iPhone X + iOS 13.0

プロジェクトの作成

Xcode にてテンプレートから iOS + Argumented Reality App を選択する。

以下のオプションを選択する。

  • Language: Swift
  • Content Technology: RealityKit
  • User Interface: SwiftUI

AppDelegate.swift と ContentView.swift という Swift のソースコードが用意される。

ソースコード

ContentView.swift を以下の内容に修正する。

import SwiftUI
import RealityKit

struct ContentView : View {
    var body: some View {
        return ARViewContainer().edgesIgnoringSafeArea(.all)
    }
}

struct ARViewContainer: UIViewRepresentable {

    func makeUIView(context: Context) -> ARView {

        // RealityKit のメインとなるビュー
        let arView = ARView(frame: .zero)

        // デバッグ用設定
        // 処理の統計情報と、検出した3D空間の特徴点を表示する。
        arView.debugOptions = [.showStatistics, .showFeaturePoints]

        // シーンにアンカーを追加する
        let anchor = AnchorEntity(plane: .horizontal, minimumBounds: [0.15, 0.15])
        arView.scene.anchors.append(anchor)

        // テキストを作成
        let textMesh = MeshResource.generateText(
            "Hello, world!", 
            extrusionDepth: 0.1,
            font: .systemFont(ofSize: 1.0), // 小さいとフォントがつぶれてしまうのでこれぐらいに設定
            containerFrame: CGRect.zero,
            alignment: .left,
            lineBreakMode: .byTruncatingTail)
        // 環境マッピングするマテリアルを設定
        let textMaterial = SimpleMaterial(color: UIColor.yellow, roughness: 0.0, isMetallic: true)
        let textModel = ModelEntity(mesh: textMesh, materials: [textMaterial])
        textModel.scale = SIMD3<Float>(0.1, 0.1, 0.1) // 10分の1に縮小
        textModel.position = SIMD3<Float>(0.0, 0.0, -0.2) // 奥0.2m
        anchor.addChild(textModel)

        // 立方体を作成
        let boxMesh = MeshResource.generateBox(size: 0.1)
        // 光源を無視する単色を設定
        let boxMaterial = UnlitMaterial(color: UIColor.red)
        let boxModel = ModelEntity(mesh: boxMesh, materials: [boxMaterial])
        boxModel.position = SIMD3<Float>(-0.2, 0.0, 0.0) // 左0.2m
        anchor.addChild(boxModel)

        // 球体を作成
        let sphereMesh = MeshResource.generateSphere(radius: 0.1)
        // 環境マッピングするマテリアルを設定
        let sphereMaterial = SimpleMaterial(color: UIColor.white, roughness: 0.0, isMetallic: true)
        let sphereModel = ModelEntity(mesh: sphereMesh, materials: [sphereMaterial])
        sphereModel.position = SIMD3<Float>(0.0, 0.0, 0.0)
        anchor.addChild(sphereModel)

        return arView
    }

    func updateUIView(_ uiView: ARView, context: Context) {}
}

実機での実行結果

実機 (iPhone X + iOS 13.0) にインストールして実行してみる。

実空間を背景にして Hello World テキスト、赤い立方体、金属的な球体が合成されて表示されている。

裏側からは反転した Hello World テキストになっている。

球体には環境マッピングで周囲の景色が写り込んでいる。

参考資料