How to specify supported volume viewpoints

We can specify one or more viewpoints that our volume should support.

Building on what we learned yesterday, we can refine this a bit. First, let’s create a list of the viewpoints we want to support. We’ll select everything except the .back value.

let supportedViewpoints = SquareAzimuth.Set(arrayLiteral: .front, .left, .right)

Then we pass this list to .supportedVolumeViewpoints

.supportedVolumeViewpoints(supportedViewpoints)

If we only want to perform an action for these viewpoints, then we can use updateStrategy: .supported). This will only call .onVolumeViewpointChange() for the ones we specified. But what if we want to do something when the user moves to an unsupported viewpoint? We can change the update strategy to .all. We can add a condition to the code to check if the user has moved to a supported or unsupported viewpoint.

.onVolumeViewpointChange(updateStrategy: .supported) { _, newValue in
    if (supportedViewpoints.contains(newValue.squareAzimuth)) {
        // Get a rotation value from the squareAzimuth
        let newRotation = simd_quatf(newValue.squareAzimuth.orientation)

        // Set the orientation of content in our scene
        subject.orientation = newRotation
        print("viewpoint supported")

    } else {
        print("viewpoint not supported")
        // DO something to indicate the unsupported viewpoint
    }
}

You can see an example in the video below. The skull will rotate to face each viewpoint except for the back.

visionOS simulator video showing an entity rotating to face all viewpoints except the back.

struct ContentView: View {

    @State var subject = Entity()

    let supportedViewpoints = SquareAzimuth.Set(arrayLiteral: .front, .left, .right)

    var body: some View {
        RealityView { content in

            guard let scene = try? await Entity(named: "Scene", in: realityKitContentBundle) else { return }
            content.add(scene)
            scene.position.y = -0.2

            guard let skull = scene.findEntity(named: "Skull") else { return }
            subject = skull

        }

        .onVolumeViewpointChange(updateStrategy: .supported) { _, newValue in

            if (supportedViewpoints.contains(newValue.squareAzimuth)) {
                // Get a rotation value from the squareAzimuth
                let newRotation = simd_quatf(newValue.squareAzimuth.orientation)

                // Set the orientation of content in our scene
                subject.orientation = newRotation
                print("viewpoint supported")

            } else {
                print("viewpoint not supported")
            }

        }
        .supportedVolumeViewpoints(supportedViewpoints)

    }
}

Support our work so we can continue to bring you new examples and articles.

Download the Xcode project with this and many more examples from Step Into Vision.
Some examples are provided as standalone Xcode projects. You can find those here.

Questions or feedback?