見出し画像

Blenderで作った3DモデルをAppleVisionProでパーティクル描写する

前回の記事の続きです。Blenderで作った3Dオブジェクトを、無事にSwiftでロードできたので、次はRealityComposerProでコンポーネント利用可能なパーティクルシステムを、Swiftで実現してみることにしました。目的は、Blenderで作った魔法の杖に、任意の動作や入力をトリガーに、パーティクル演出などができるようにして、AppleVisionProで遊べる事を目指しました。

いろいろ試行錯誤した結果、無事に実現できました。ソースコードはページ末尾になります。これをきっかけに「なぜ自分は、Appleの紹介するサンプルコードで行き詰まってしまったのか?」に気づけたので、今後の習得のヒント的にメモを残しておきたいと思います。

visionOSが難しかった理由

AppleのサイトのvisionOSのサンプルはすごく充実していますが、自分にとっては難易度が高いという印象でした。そんな中 今回、実現したいことをSwiftでチャレンジしてみた結果わかった難易度の原因は、「それぞれ異なる技術分野を理解していないままコードを読もうとしていた」に尽きると思いました。

例えば、Appleのサンプルコードでは

・Swift本来のモダンなコーディングスタイルの理解
SwiftUIという比較的新しいコンポーネントの理解
・visionOSのWindowやVolume,Immersiveなどの概念と、visionOS固有の機能の理解
RealityKitなど従来からiPhoneやiPadなどに向けてAppleが提供しているARの開発コンポーネント
・XcodeというIDEの理解

visionOS公式サイトより

などの「visionOS」に限らず、Appleの開発環境に関する様々な要素が詰まっているのですが、初見で「Apple Vision Pro」のアプリ開発にチャレンジすると、SwiftUIやRealityKitなどの技術要素にも触れることになるので、学ぶことが多く、それが難易度の高さにつながっていた気がします。

例えば「VStack」はvisionOSではなくSwiftUIの機能ですし、「RealityView」はAR関連のRealityKitというARKitのコンポーネントなので、どちらも「visionOS」の機能ではありませんが、サンプルコードだけを見ると並列で理解しないといけないので、難易度が高い印象になっていました。

技術要素を整理したらスッキリ理解できるようになってきた

Appleのサンプルコードをはじめとして、コードを読んだり活用してみようとした際に、まずキーになっているコンポーネント、例えば「Entity」という単語があれば、AppleのAPIドキュメントで調べてどんな技術要素に含まれているのか把握してからサンプルコードを読むようにしたところ、すごく理解が楽になりました。

また、SwiftやSwiftUIはモダンな記法になっているようです。自分にとっては、このスタイルの文法理解が難しかったです。そのため、AppleのAPI Documentに目を通すことに加え、ChatGPT 4o With Canvasを使ってコードをエディタ上で説明を受けたり、修正提案やコメント解説を受けながら進めることで、つまづく事を回避しました。

Apple Vision ProにBlenderの自作3Dモデルをインポートして、パーティクルで魔法のエフェクトを実装する

※ 無事に魔法の杖からMagicのパーティクルを追加できました

前回は「RealityComposerPro」を経由せずに3Dオブジェクトをロードする」でしたが、今回はRealityComposerProに登録だけしておいた3DモデルをrealityKitContentBundleを指定してロードしました。

//
//  ContentView.swift
//  AppleSamples06
//
//

import SwiftUI
import RealityKit
import RealityKitContent

struct ContentView: View {
    @State var enlarge = false
    
    var body: some View {
        VStack {
            // パーティクルのエンティティ
            let particleEntity = Entity()
            // パーティクルシステムの種類
            let presets: [ParticleEmitterComponent] = [
                .Presets.fireworks,
                .Presets.impact,
                .Presets.sparks,
                .Presets.magic,
                .Presets.rain,
                .Presets.snow
            ]
            // パーティクルシステムの種類指定
            let PARTICLE_SYSTEM_TYPE = 3;
            
            
            RealityView { content in
                // ローカルの3Dモデル (usdz形式) を指定してロード
                if let scene = try? await Entity(named: "3Dモデル名", in: realityKitContentBundle) {
                    // スケールを指定
                    scene.transform.scale = [1, 1, 1]
                    // 回転の指定処理
                    let uniformRotate = simd_quatf(angle: .pi / 2, axis: [0, 1, 0])
                    scene.transform.rotation = uniformRotate
                    // 3Dオブジェクトの位置を下方向に下げる
                    scene.position = SIMD3<Float>(0, -0.2, 0)
                    
                    // パーティクルの位置指定
                    particleEntity.transform.translation = SIMD3<Float>(x: 0, y: 0.3, z: 0)
                    // パーティクルシステムの種類指定
                    var particles = presets[PARTICLE_SYSTEM_TYPE]
                    // パーティクルのセット
                    particleEntity.components[ParticleEmitterComponent.self] = particles
                    // 3Dモデルに子としてセット
                    scene.addChild(particleEntity)
                    
                    // シーンにモデルを追加
                    content.add(scene)
                }
            }

        }
    }
}

#Preview(windowStyle: .automatic) {
    ContentView()
}

※ GitHubのコード

実装にあたってはこちらの記事を参考にしました

次はSwiftでハンドジェスチャを追加して、魔法の杖を振り回せるようにしてみたいとおもいます

Apple Vision Proアプリ開発のおともに!



この記事が気に入ったらサポートをしてみませんか?