WWDC Quick Look 💓 By SwiftGGTeam
Work with Reality Composer Pro content in Xcode

Work with Reality Composer Pro content in Xcode

元の動画を見る

ハイライト

Reality Composer Pro プロジェクトの 3D コンテンツには、次の方法でアクセスできます。RealityViewこれを SwiftUI にロードし、カスタム コンポーネントおよびアタッチメント API と組み合わせて、データ駆動型 3D シーンと 2D SwiftUI ビューの間のハイブリッド インタラクションを実現します。

主な内容

Reality Composer Pro から Xcode へ

Reality Composer Pro は、RealityKit コンテンツを準備するための開発者ツールです。プロジェクトの上部の各タブは、実行時にロードできるルート エンティティを表します。

02:40

ロードシーンの使用法RealityView非同期イニシャライザ、経由Entity(named:in:)指定された名前のエンティティを Reality Composer Pro パッケージからロードします。realityKitContentBundleこれは Xcode によって自動的に生成される定数であり、ロードされたエンティティは階層全体のルート ノードになります。

##詳細

ECS アーキテクチャ

RealityKit はエンティティ コンポーネント システム (ECS) アーキテクチャを使用します。

  • エンティティ: シーン内の任意のオブジェクト。データは保存されません。
  • コンポーネント: データを保存し、動的に追加/削除できます。
  • システム: フレームごとにロジックが実行され、特定のコンポーネントをクエリして更新します

04:49

この設計はオブジェクト指向とは異なります。エンティティの「性質」は、継承階層ではなく、エンティティが所有するコンポーネントの組み合わせによって決まります。

カスタムコンポーネント

Reality Composer Pro でカスタム コンポーネントを作成すると、Xcode が対応する Swift ファイルを自動的に生成します。

07:26

例: 地形図上の名所のコンポーネントを作成する

// Design-time component
public struct PointOfInterestComponent: Component, Codable {
    public var region: Region = .yosemite
    public var name: String = "Ribbon Beach"
    public var description: String?
}

22:31

キーポイント:

  • 従わなければなりませんCodableReality Composer Pro でプロトコルを表示および編集できます
  • 単純なデータ型 (Int、String、SIMD) を直接シリアル化できます。
  • 複合型により Xcode コンパイル エラーが発生する

Attachments API

アタッチメントを使用すると、SwiftUI ビューを 3D シーンに埋め込むことができます。

12:00

RealityView3 つのパラメーターの初期化子:

RealityView { content, _ in
    // make: 加载初始场景,只执行一次
    if let entity = try? await Entity(named: "MyScene", in: realityKitContentBundle) {
        content.add(entity)
    }
} update: { content, attachments in
    // update: 状态变化时调用
    if let attachmentEntity = attachments.entity(for: "🐠") {
        content.add(attachmentEntity)
    }
} attachments: {
    // attachments: 声明要嵌入的 SwiftUI 视图
    Button { ... }
       .background(.green)
       .tag("🐠")
}

15:48

キーポイント:

  • makeクロージャは 1 回だけ実行され、シーンをロードするために使用されます。 -updateClosure は、フレームごとではなく、SwiftUI の状態が変化したときに呼び出されます。 -attachmentsViewBuilder のビューはエンティティに変換されます
  • 使用するtag更新で渡される添付ファイルを識別しますattachments.entity(for:)得る

データドリブンの動的アタッチメント

Reality Composer Pro でデータ主導型の添付ファイルを生成します。

@Observable final class AttachmentsProvider {
    var attachments: [ObjectIdentifier: AnyView] = [:]
    var sortedTagViewPairs: [(tag: ObjectIdentifier, view: AnyView)] { ... }
}

// 查询兴趣点并创建附件
static let markersQuery = EntityQuery(where: .has(PointOfInterestComponent.self))

rootEntity.scene?.performQuery(Self.markersQuery).forEach { entity in
    guard let pointOfInterest = entity.components[PointOfInterestComponent.self] else { return }
    
    let attachmentTag: ObjectIdentifier = entity.id
    let view = LearnMoreView(name: pointOfInterest.name, description: pointOfInterest.description)
                           .tag(attachmentTag)
    
    attachmentsProvider.attachments[attachmentTag] = AnyView(view)
}

20:43

キーポイント:

  • 使用するEntityQuery特定のコンポーネントを所有するすべてのエンティティをクエリします -entity.id一意の識別子として、Reality Composer Pro でタグを手動で管理することは避けてください。 -AttachmentsProvider使用@ObservableSwiftUI アップデートをトリガーする

ランタイムコンポーネント

設計時データと実行時データを分離します。

// Run-time component
public struct PointOfInterestRuntimeComponent: Component {
    public let attachmentTag: ObjectIdentifier
}

// 在创建附件后添加运行时组件
let runtimeComponent = PointOfInterestRuntimeComponent(attachmentTag: attachmentTag)
entity.components.set(runtimeComponent)

25:38

ランタイムコンポーネントは必要ありませんCodable、Reality Composer Pro では表示されません。

オーディオの再生

Reality Composer Pro でオーディオ セットを再生します。

func playOceanSound() {
    guard let entity = entity.findEntity(named: "OceanEmitter"),
        let resource = try? AudioFileResource(named: "/Root/Resources/Ocean_Sounds_wav",
                                   from: "DioramaAssembled.usda",
                                   in: RealityContent.realityContentBundle) else { return }
    
    let audioPlaybackController = entity.prepareAudio(resource)
    audioPlaybackController.play()
}

28:55

キーポイント:

  • findEntity(named:)オーディオエンティティを見つける -AudioFileResourceフルパス、ソース usda ファイル、バンドルが必要です -prepareAudio戻るAudioPlaybackController、再生/一時停止/停止をサポート

シェーダーグラフのマテリアル制御

コードでシェーダー グラフ マテリアルのパラメーターを操作します。

@State private var sliderValue: Float = 0.0

Slider(value: $sliderValue, in: (0.0)...(1.0))
    .onChange(of: sliderValue) { _, _ in
        guard let terrain = rootEntity.findEntity(named: "DioramaTerrain"),
                var modelComponent = terrain.components[ModelComponent.self],
                var shaderGraphMaterial = modelComponent.materials.first 
                    as? ShaderGraphMaterial else { return }
        do {
            try shaderGraphMaterial.setParameter(name: "Progress", value: .float(sliderValue))
            modelComponent.materials = [shaderGraphMaterial]
            terrain.components.set(modelComponent)
        } catch { }
    }

31:02

キーポイント:

  • コマンドを押しながらノード選択「プロモート」をクリックして、Reality Composer Pro のパラメータを公開します -ShaderGraphMaterial.setParameter(name:value:)ランタイム値を設定する
  • 変更後にマテリアルを保存し直す必要があるModelComponent、コンポーネントをエンティティに保存し直します。

オーディオとスライダーの連携

static let audioQuery = EntityQuery(where: .has(RegionSpecificComponent.self) 
                                    && .has(AmbientAudioComponent.self))

rootEntity?.scene?.performQuery(Self.audioQuery).forEach({ audioEmitter in
    guard var audioComponent = audioEmitter.components[AmbientAudioComponent.self],
          let regionComponent = audioEmitter.components[RegionSpecificComponent.self]
    else { return }

    let gain = regionComponent.region.gain(forSliderValue: sliderValue)
    audioComponent.gain = gain
    audioEmitter.components.set(audioComponent)
})

31:57

重要なポイント

  1. Reality Composer Pro を 3D コンテンツのデータ ソースとして使用します

    • やるべきこと: データを保存するカスタム コンポーネントを使用して、Reality Composer Pro に非表示のエンティティをマーカーとして配置します。
    • 実行する価値がある理由: デザイナーは位置と属性を個別に調整でき、コードは変更に自動的に適応します。
    • 開始方法: 作成するCodableカスタム コンポーネント。エンティティに追加され、Reality Composer Pro でプロパティが入力されます。
  2. 3D シーンで SwiftUI 情報カードをホバーします

    • 内容: Attachments API を使用して、関心のある地点上に 2D ボタンまたは情報パネルを表示します。
    • 実行する価値がある理由: SwiftUI の豊富な UI 機能と RealityKit の 3D ポジショニングを組み合わせる
    • 開始方法: 作成するAttachmentsProvider、使用EntityQuery添付ファイルを動的に生成するRealityViewアップデートに位置付けられる
  3. スライダーを使用して 3D シーンのマテリアルとオーディオ トランジションを制御します

    • 内容: 地形の変形とオーディオのフェードの両方を制御するスライダーを作成します。
    • 価値がある理由: コードによってシェーダー グラフ パラメーターとオーディオ ゲインを制御して、臨場感あふれるトランジション エフェクトを作成できます。
    • 開始方法: Reality Composer Pro でシェーダー グラフ パラメーターをプロモートするには、次を使用します。onChange資料も更新して、AmbientAudioComponent
  4. USD アセットを .rkassets ディレクトリに配置します

    • 何をすべきか: USD ファイルを Swift パッケージの .rkassets ディレクトリに置きます。
    • 実行する価値がある理由: Xcode は、実行時により速く読み込まれる形式にコンパイルされます。
    • 開始方法: Swift パッケージに .rkassets ディレクトリを作成し、そこに USD ファイルを移動します。

関連セッション

コメント

GitHub Issues · utterances