本記事では3DモデルにMixamoでアニメーションを適用し、RealityViewで表示・再生する方法を紹介します。
(※技適特例届け出済み)
デモ
3Dモデルをタップすると、アニメーションを再生するようにしています。
アニメーションの編集方法
-
フリーの3Dモデルをダウンロードします。
(今回はこちらのサイトからゾンビのモデルをダウンロードしました。) -
Mixamoを使用して、ダウンロードしたモデルに好みのアニメーションを適用させます。
今回は攻撃をするアニメーションを適用させました。
(Mixamoは、3Dキャラクターにアニメーションを適用できるAdobe社のオンラインサービスです。) -
Reality Converterを使用して、アニメーション適用後のモデルにテクスチャを適用させ、USD*(Universal Scene Description)形式で出力します。
実装
Reality ConverterでエクスポートしたUSDZファイルをXcodeプロジェクトにインポートし、RealityKitを使用して表示させます。
struct ImmersiveView: View {
@StateObject var vm: ImmersiveViewModel = ImmersiveViewModel()
@State var entity = try! Entity.loadModel(named: "attack_zombie")
var body: some View {
RealityView { content in
entity.generateCollisionShapes(recursive: false)
entity.components.set(InputTargetComponent())
content.add(entity)
}
.gesture(tapGesture)
}
private var tapGesture: some Gesture {
TapGesture()
.targetedToAnyEntity()
.onEnded { value in
let entity = value.entity
entity.playAnimation(self.entity.availableAnimations[0])
}
}
}
RealityKit内でModelEntityを追加し、TapGestureを使用してEntityのアニメーションを再生する処理をしています。
また、RealitiyViewでイベントの入力を受け取るには、ModelEntityにInputTargetComponentとCollisionComponentの両方を設定する必要があります。
You can add a gesture to a RealityView, like any other SwiftUI view, and it will hit test against entities in that view. To receive input, the entity must have both an input target component and a collision component. When a touch event is handled by RealityView, it will ignore any entities that don't have both collision and an input target. Only this last entity has both components, so gestures added to this RealityView will only react to input directed at this entity.
引用: Build spatial experiences with RealityKit - WWDC23
参考資料