When interacting with RealityView’s realityViewCameraControls .orbit and setting a new RealityViewCameraContent .cameraTarget, the resulting camera target and camera orbit is incorrect. This can be demonstrated where one finger is orbiting the RealityView, and another pushes a button which changes the camera target. Instead of the camera facing the new target, some point in the scene is the new effective camera target and orbit point. This only occurs when an orbit interaction is currently taking place. If you stop interacting with the orbit, change target, then start orbit interacting again, everything works as expected. Though this example uses two-touches, any change of the camera target has this conflict with orbit interaction. This means interacting with orbit will result in the wrong camera view which is unexpected for users and difficult to reconcile or detect, for developers.
Expected: Interacting (orbiting) the scene while setting a new camera target with the buttons on screen (at the same time), the camera’s new target shows centred in view the orbit revolves the new target and continues to match my gestures.
Reality: Interacting (orbiting) the scene while setting a new camera target with the buttons on screen (at the same time), the camera’s new target is not centred in view, and camera is now orbiting an unexpected point in the scene, that is not my expected target.
One imperfect workaround is to force a rebuild of the view after setting a new cameraTarget. This sets all targets correctly but results in a flicker, loss of orbit controls until re-touch and ultimately is a poor user experience, but is better than the wrong target being shown unexpectedly.
Code Sample:
import SwiftUI
import RealityKit
struct RKOribtTarget: View {
@State private var target: Int = 0
@State private var rcContent: RealityViewCameraContent?
@State private var rkID: UUID = UUID()
let root = Entity()
let center = ModelEntity(mesh: .generateSphere(radius: 0.05), materials: [UnlitMaterial(color: UIColor(.gray.opacity(0.5)))])
let red = ModelEntity(mesh: .generateBox(size: 0.1), materials: [SimpleMaterial(color: .red, isMetallic: false)])
let blue = ModelEntity(mesh: .generateBox(size: 0.1), materials: [SimpleMaterial(color: .blue, isMetallic: false)])
let green = ModelEntity(mesh: .generateBox(size: 0.1), materials: [SimpleMaterial(color: .green, isMetallic: false)])
var body: some View {
VStack{
RealityView { content in
red.position.x = 0.5
blue.position.z = 0.5
green.position.y = 0.5
center.position = .init(repeating: 0.25)
content.cameraTarget = target == 0 ? root : blue
root.addChild(red)
root.addChild(blue)
root.addChild(green)
root.addChild(center)
content.add(root)
} update: { content in
switch target{
case 0:
content.cameraTarget = root
case 1:
content.cameraTarget = blue
case 2:
content.cameraTarget = red
case 3:
content.cameraTarget = green
default:
content.cameraTarget = root
}
}
.id(rkID)
.realityViewCameraControls(.orbit)
VStack{
Text("Target")
Button("Default") {
target = 0
// Force rebuilding view resets orbit target and rotation
// But shows a flicker, interaction requires touch reset
// Not an ideal workaround
// rkID = UUID()
}
.buttonStyle(.bordered)
Button("Blue") {
target = 1
// rkID = UUID()
}
.buttonStyle(.bordered)
.tint(.blue)
Button("Red") {
target = 2
// rkID = UUID()
}
.buttonStyle(.bordered)
.tint(.red)
Button("Green") {
target = 3
// rkID = UUID()
}
.buttonStyle(.bordered)
.tint(.green)
}
}
}
}
Xcode Version: Version 26.0 (17A324) iOS Version: iOS 26.5 (23F75)
Tested on devices, iPhone 12 Pro, iPhone 15 Pro