Jack Johnson
Jack Johnson

Reputation: 726

Send Notification from SwiftUI Xcode 16 to trigger Reality Composer Pro Timeline Action Animation

I am using Reality Composer Pro 2.0 and Xcode 16 beta for VisionOS 2 Beta.

I am able to see and trigger RCP Animation Component animations in a RealityView in Xcode by calling playAnimation on scene.availableAnimations[0] when a swiftui button is tapped, all good there.

I want to be able to trigger new Timeline Action animations from tapping a swiftui button as well, but I'm not sure the best way to access Timeline Actions to trigger them in code.

I see that I can send a Notification from Xcode that will trigger a timeline action (as shown in screenshot), but I'm not sure how to send a notification from SwiftUI to RCP to trigger this "SpinAndMove" Timeline animation. enter image description here

If anyone could help send a notification from SwiftUI to RCP or if there's a better "best practices" method to trigger Timeline Actions from outside of RCP, it would be much appreciated!

Upvotes: 2

Views: 820

Answers (2)

Andy Jazz
Andy Jazz

Reputation: 58153

First of all, I want to say that all the laurels belong entirely to @Caroline. I just want to add to this post and publish the RCP 2.0 scene settings and the full version of the code. Here's a Hide button sends a notification to RCP 2.0 scene to activate a chosen timeline's behavior.

enter image description here

struct ContentView : View {
    @Environment(\.realityKitScene) var scene
    let rkcb = realityKitContentBundle
    let rknt = "RealityKit.NotificationTrigger"
    
    fileprivate func notify(_ scene: RealityKit.Scene) {
        let notification = Notification(name: .init(rknt),
                                    userInfo: ["\(rknt).Scene" : scene,
                                          "\(rknt).Identifier" : "notifier"])
        NotificationCenter.default.post(notification)
    }
    
    var body: some View {
        RealityView { rvc in
            if let model = try? await Entity(named: "Scene", in: rkcb) {
                rvc.add(model)
            }
        }
        .gesture(
            SpatialTapGesture()
                .targetedToAnyEntity()
                .onEnded {
                    if $0.entity.applyTapForBehaviors() {
                        print("Tapped")
                    }
                }
        )
        Button("<< Hide >>") {
            if let scene { notify(scene) }     // A miracle happens here
        }
        .font(.system(size: 125))
        .padding3D(.front)
    }
}

Upvotes: 3

Caroline
Caroline

Reputation: 4970

This was answered on the Apple developer forum: https://forums.developer.apple.com/forums/thread/756978

That post describes how to do the notification with VisionOS, but I was able to get it to work on a macOS target with:

if let scene = appModel.contentEntity?.scene {
  NotificationCenter.default.post(
    name: Notification.Name("RealityKit.NotificationTrigger"),
    object: nil,
    userInfo: [
      "RealityKit.NotificationTrigger.Scene": scene,
      "RealityKit.NotificationTrigger.Identifier": "insideFlip"
    ])
}

Where insideFlip was the Notification Name defined in Reality Composer Pro, and appModel.contentEntity?.scene was defined inside RealityView.

if let immersiveContentEntity =
    try? await Entity(named: "Immersive", in: realityKitContentBundle) {
  appModel.contentEntity = immersiveContentEntity
}

Upvotes: 3

Related Questions