Reputation: 421
I am trying to add a new entity to visionOS RealityView after API call completes. I am simulating API call with a timer, and I want to add add a sphere at a new position every second. The timer adjusts location.x and the update block should add sphere at a new position. I think update block is not the right place to do this. How do I achieve this? Thanks!
import SwiftUI
import RealityKit
import RealityKitContent
struct ContentView: View {
@State var location: SIMD3<Float> = SIMD3<Float>(x: 0, y: 0, z: 0)
var body: some View {
VStack {
RealityView { content in
let data = getSphere(location: SIMD3<Float>(x: 0.2, y: 0.2, z: 0.2), color: .blue)
content.add(data)
} update: { content in
// 1 - By doing ``` location.x += 1``` the update block is trigerred
print("update triggered") // => this logs as expected
// 2 - I want to add a NEW sphere at adjusted location, it is not working though
let data = getSphere(location: SIMD3<Float>(x: location.x, y: 0.7, z: 0.2), color: .orange)
content.add(data) // not working
content.entities.append(data) // also not working
}
.onAppear {
// 3 - Simulate API call with timer
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { t in
location.x += 1.0
}
}
}
}
}
func getSphere(location: SIMD3<Float>, color: SimpleMaterial.Color) -> ModelEntity {
let sphere = ModelEntity(mesh: .generateSphere(radius: 0.03))
let material = SimpleMaterial(color: color, isMetallic: false)
sphere.model?.materials = [material]
sphere.position = location
return sphere
}
Upvotes: 1
Views: 1049
Reputation: 58143
Your code works fine. You just need to set a smaller step for the orange sphere and increase the size of the Volumetric container to the maximum (in case you're using a volume). To go beyond the limits of a volumetric window use Fully Immersive VR experience or Mixed Immersion AR style.
import SwiftUI
import RealityKit
@main struct YourApp : App {
var body: some Scene {
ImmersiveSpace(id: "mine") {
ContentView()
}
.immersionStyle(selection: .constant(.mixed), in: .mixed)
}
}
func getSphere(_ pos: SIMD3<Float>, _ col: SimpleMaterial.Color) -> ModelEntity {
let sphere = ModelEntity(mesh: .generateSphere(radius: 0.03),
materials: [SimpleMaterial(color: col, isMetallic: false)])
sphere.position = pos
return sphere
}
struct ContentView : View {
@State var location = SIMD3<Float>()
var body: some View {
RealityView { content in
let data = getSphere([0.0, 0.3, 0.2], .blue)
content.add(data)
} update: { content in
let data = getSphere([location.x, 0.2, 0.2], .orange)
content.add(data)
}
.onAppear {
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { _ in
location.x += 0.1
}
}
}
}
Upvotes: 2