SwiftUI+RealityKit 超初級編 – AR空間にブラウン管テレビを設置する

2024.01.16

はじめに

今回の記事は下記の続編になります。

SwiftUI+RealityKit 超初級編 – デフォルトテンプレートのコードを読み解く

こちらの記事では、デフォルトテンプレートを使用してプロジェクトを作成し、実際にどのような結果になるのか確認してみました。

今回は、Appleが無料で配布している3Dモデルを使用して、AR空間上にオブジェクトを配置するを目標に進めていきます。

環境

  • Xcode 15.2

前回までのARViewContainer

ARViewでの描画の処理を行っているARViewContainerの前回までのコードです。キューブ型のモデルを生成して、平面アンカーにそのモデルを追加し、画面上に表示をしています。

struct ARViewContainer: UIViewRepresentable {

    func makeUIView(context: Context) -> ARView {

        let arView = ARView(frame: .zero)

        // Create a cube model
        let mesh = MeshResource.generateBox(size: 0.1, cornerRadius: 0.005)
        let material = SimpleMaterial(color: .gray, roughness: 0.15, isMetallic: true)
        let model = ModelEntity(mesh: mesh, materials: [material])
        model.transform.translation.y = 0.05

        // Create horizontal plane anchor for the content
        let anchor = AnchorEntity(.plane(.horizontal, classification: .any, minimumBounds: SIMD2<Float>(0.2, 0.2)))
        anchor.children.append(model)

        // Add the horizontal plane anchor to the scene
        arView.scene.anchors.append(anchor)

        return arView

    }

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

}

今回は、このキューブの生成部分をAppleが配布している3Dモデルに置き換えていきます。

AR Quick Look

Apple - AR Quick Lookの中で配布されている3Dモデルを無料でダウンロードすることが可能です。

今回はブラウン管テレビを表示することにしました。

パソコン上でモデルの画像をクリックすると、ダウンロードすることが出来ます。

3Dモデルを表示

Xcode 14時代ではReality Composerが使用出来ていた

作成された3Dモデルの設置方法に関して、RealityKit+SwiftUIのチュートリアル系の記事や動画を見ると、Reality Composer Projectを使用してARコンテンツ、3Dオブジェクトの管理をしているものが多かったです。

過去のチュートリアルでは、Argument Reality Appテンプレートでプロジェクトを作成するとデフォルトでExperience.rcprojectというReality Composer Projectが存在しており、その中で3Dオブジェクトの管理を出来ていたようでした。

どうやら、Xcode 15.0 beat 2あたりからExperience.rcprojectが取り込まれなくなっているようで、現時点(Xcode 15.2)ではAdd Fileによる追加も出来ないようでした。

Developer Forumsでも議論中

iOSでReality Composerを使用出来ない問題の解決策はまだ出ていなさそうですが、多くの方が同じ問題を抱えていました。

今回は、別の方法でダウンロードした3Dモデルの表示を試みることにしました。

プロジェクトの配下に素材ファイルを保存

AR Quick Lookでダウンロードしたブラウン管の3Dモデルのファイルtv_retro.usdzをプロジェクトフォルダ配下に保存します。

保存する際に、ダイアログが出るのでCopy items if neededを選択するのを忘れないようにしましょう。

保存したファイルを呼び出す

ARViewContainerのコードを下記に書き換えます。

struct ARViewContainer: UIViewRepresentable {

    func makeUIView(context: Context) -> ARView {

        let arView = ARView(frame: .zero)

        // create a cube modelの処理をこの処理に書き換え
        // Create a retro tv moel
        let model = try! ModelEntity.loadModel(named: "tv_retro.usdz")

        // Create horizontal plane anchor for the content
        let anchor = AnchorEntity(.plane(.horizontal, classification: .any, minimumBounds: SIMD2<Float>(0.2, 0.2)))
        anchor.children.append(model)

        // Add the horizontal plane anchor to the scene
        arView.scene.anchors.append(anchor)

        return arView

    }

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

}

変更点としては、キューブ型のモデルを生成していた処理を削除し、ダウンロードしたモデルを呼び出す処理に変更しています。

// Create a retro tv moel
let model = try! ModelEntity.loadModel(named: "tv_retro.usdz")

※今回はdo-catchによるエラーハンドリングしておりません。必要に応じて対応してください。

これで処理は完了したので実際に表示されるか実機で動作を確認してみます。

実機で確認

平面検出して、平面上にブラウン管テレビが配置されました!

テレビの大きさを変更

テレビを配置することはできました!ただ思ったより、テレビが大きかったので小さくしたいです。

下記のようにscaleの値を変更することでスケールの倍率が変更出来ます。1がそのままの大きさで、1未満の値を渡してあげることで小さく見せることが出来ます。

// Create a retro tv moel
let model = try! ModelEntity.loadModel(named: "tv_retro.usdz")
// スケールの倍率を変更
model.scale.x = 0.005
model.scale.y = 0.005
model.scale.z = 0.005

ちなみに、model.scalemodel.transform.scaleで同様にスケールの倍率の変更が可能ですが、変数の定義のコメントを見ると、両方とも同様の値になっていることが分かりました。

/// This is the same as the ``Transform/scale`` value on the
/// ``HasTransform/transform``.
@MainActor public var scale: SIMD3<Float>

小さくしたテレビを実機で確認

スケールが小さくなったテレビを確認出来ました。

おわりに

Reality ComposerがXcode 15.2で使えないという問題に直面しましたが、その他の方で3Dモデルをプロジェクトに保存して表示することが出来ました。

さらに理解を深めていく為、引き続き学習を進めていきます。

Reality Composerについては何か進展があれば共有したいと思います。