With a RealityView, an entity can be rotated using a gesture detector to the entire view:
RealityView { content in
let loadedEntity = try await ModelEntity(named: modelName,
in: RealityKitContent.realityKitContentBundle)
// Add components to entity
loadedEntity.generateCollisionShapes(recursive: true)
loadedEntity.components.set(InputTargetComponent())
loadedEntity.setParent(anchor)
// Add the anchor which is the parent of the entity
content.add(anchor)
} .gesture(
drag
)
Question
This works for one model, but what if there are two models in the RealityView and each model should have a different rotation? How do we add a gesture to each model independently? Using Model3D?
This should not include building a scene in RealityComposerPro. We are talking about programmatically spawning objects in and allowing gestures.
Original post on figuring out rotation here
I created two cubes in a Reality Composer Pro scene. And placed them at a distance of 50 cm
from each other. If you do not need to build a scene in Reality Composer Pro from scratch, just add two primitives programmatically, or add two USDZ models with try? await Entity(named: String)
.
I've implemented .gesture()
modifier and .targetedToEntity()
modifier for each model.
import SwiftUI
import RealityKit
import RealityKitContent
struct ContentView: View {
@State var rotationA: Angle = .zero
@State var rotationB: Angle = .zero
@State var cubeA = Entity()
@State var cubeB = Entity()
var body: some View {
RealityView { content in
if let scene = try? await Entity(named: "Scene",
in: realityKitContentBundle) {
content.add(scene)
print(scene)
}
} update: { content in
if let scene = content.entities.first {
Task {
cubeA = scene.findEntity(named: "Cube_A") ?? Entity()
cubeA.components.set(InputTargetComponent())
cubeA.generateCollisionShapes(recursive: false)
cubeB = scene.findEntity(named: "Cube_B") ?? Entity()
cubeB.components.set(InputTargetComponent())
cubeB.generateCollisionShapes(recursive: false)
}
}
}
.gesture(
DragGesture()
.targetedToEntity(cubeA)
.onChanged { _ in
rotationA.degrees += 5.0
let m1 = Transform(pitch: Float(rotationA.radians)).matrix
let m2 = Transform(yaw: Float(rotationA.radians)).matrix
cubeA.transform.matrix = matrix_multiply(m1, m2)
// Keep starting distance between models
cubeA.position.x = -0.25
}
)
.gesture(
DragGesture()
.targetedToEntity(cubeB)
.onChanged { _ in
rotationB.degrees += 5.0
cubeB.transform = Transform(roll: Float(rotationB.radians))
// Keep starting distance between models
cubeB.position.x = 0.25
}
)
}
}
The scene hierarchy looks like this: