Toggle Immersive Space in Xcode

I currently try to create a game with a single scene that is shown in a single volume - still I would like to add the functionality to toggle the Immersive Space for a surrounding skybox.

As far as I understood, in Unity this is only possible by switching scenes with a bounded and an unbounded volume camera - but as I would like to use a single scene, to keep the game state as it is, I wanted to toggle the Immersive Space in Xcode.

The activation works as expected and shows the skybox around my volume. But when I want to dismiss the Immersive Space, the app crashes and I get the following error:
Thread 1: Swift runtime failure: Unexpectedly found nil while unwrapping an Optional value
It seems like this happens in the PolySpatialSceneDelegate.swift file where I don’t have access to.

Here you can see the code for the mainScene

    var mainScene: some Scene {
        ImmersiveSpace(id: "Unbounded", for: UUID.self) { uuid in
            //            Group {
            //                PolySpatialContentViewWrapper()
            //                    .environment(\.pslWindow, PolySpatialWindow(uuid.wrappedValue, "Unbounded", .init(1.000, 1.000, 1.000)))
            
            RealityView { content in
                let skybox = Entity()
                skybox.addSkybox(for: .beach)
                content.add(skybox)
            } update: { content in
                guard viewModel.destinationChanged else { return }
                guard let entity = content.entities.first else { fatalError() }
                entity.updateTexture(for: viewModel.destination)
                Task { @MainActor in
                    viewModel.destinationChanged = false
                }
            }
            //            }
        } defaultValue: { UUID() }.immersionStyle(selection: .constant(.progressive), in: .progressive)
        
        WindowGroup(id: "Bounded-1.000x1.000x1.000", for: UUID.self) { uuid in
            PolySpatialContentViewWrapper()
                .environment(\.pslWindow, PolySpatialWindow(uuid.wrappedValue, "Bounded-1.000x1.000x1.000", .init(1.000, 1.000, 1.000)))
                .overlay(...) // Here is basically a Toggle that can open and dismiss the Immersive Space
        } defaultValue: { UUID() } .windowStyle(.volumetric).defaultSize(width: 1.000, height: 1.000, depth: 1.000, in: .meters)
    }

Is there a way to fix this crash? Thanks in advance!

I found a fix for this issue. It seems like there has to exist a PolySpatialContentViewWrapper next to your RealityViewContent.

        ImmersiveSpace(id: "Unbounded", for: UUID.self) { uuid in
                PolySpatialContentViewWrapper()
                    .environment(\.pslWindow, PolySpatialWindow(uuid.wrappedValue, "Unbounded", .init(1.000, 1.000, 1.000)))

                RealityView { content in
                    let skybox = Entity()
                    skybox.addSkybox(for: .beach)
                    content.add(skybox)
                } update: { content in
                    guard viewModel.destinationChanged else { return }
                    guard let entity = content.entities.first else { fatalError() }
                    entity.updateTexture(for: viewModel.destination)
                    Task { @MainActor in
                        viewModel.destinationChanged = false
                    }
                }
        } defaultValue: { UUID() }.immersionStyle(selection: .constant(.progressive), in: .progressive)

When you then try to close Immersive Space again via Xcode, it seems that the Unity Framework does something in the background and calls the requestDismissWindow(...) function in the UnityPolySpatialApp where currently a scene session destruction gets requested via the line UIApplication.shared.requestSceneSessionDestruction(session!, options: nil). If you remove this line, it works again, that you can open and close the Immersive Space as expected without a crash. I am not sure how essential the scene destruction is for Unity, but if you just want to extend your Unity Volume with a native SwiftUI Immersive Space, then this works at least.

2 Likes