I added some objects with a PhysicBodyComponent in my RealityView. So they have some physics to fall for example. Afterwards, I added some DragGesture to change the position of the objects. During the DragGesture, the object still try to fall during I change the position in the volumetric window.
import SwiftUI
import RealityKit
import RealityKitContent
struct ContentView: View {
@State private var enlarge = false
@State private var showImmersiveSpace = false
@State private var immersiveSpaceIsShown = false
@State private var newCubes = Entity()
@Environment(\.openImmersiveSpace) var openImmersiveSpace
@Environment(\.dismissImmersiveSpace) var dismissImmersiveSpace
var body: some View {
VStack {
RealityView { content, attachments in
content.add(newCubes)
var planeMaterial = PhysicallyBasedMaterial()
planeMaterial.baseColor = PhysicallyBasedMaterial.BaseColor(tint: .brown)
let planeGeometry: MeshResource = .generatePlane(width: 1, depth: 1)
let plane = ModelEntity(mesh: planeGeometry, materials: [planeMaterial])
plane.transform.translation.y = -0.5
let materialPlane = PhysicsMaterialResource.generate(friction: 0.8, restitution: 0.0)
plane.generateCollisionShapes(recursive: true)
plane.components.set(PhysicsBodyComponent(shapes: plane.collision!.shapes, mass: 0, material: materialPlane, mode: .static))
content.add(plane)
var sphereMaterial = PhysicallyBasedMaterial()
sphereMaterial.baseColor = PhysicallyBasedMaterial.BaseColor(tint: .blue)
let sphereGeometry: MeshResource = .generateSphere(radius: 0.2)
let sphere = ModelEntity(mesh: sphereGeometry, materials: [sphereMaterial])
//CollisionComponent
let collisionSphere = CollisionComponent(shapes: [.generateSphere(radius: 0.2)])
//InputTargetComponent
sphere.components.set(InputTargetComponent())
sphere.components.set(collisionSphere)
let material = PhysicsMaterialResource.generate(friction: 0.8, restitution: 0.0)
//PhysicsBodyComponent
sphere.components.set(PhysicsBodyComponent(shapes: sphere.collision!.shapes, mass: 1, material: material, mode: .dynamic))
content.add(sphere)
content.add(attachments.entity(for: "testAttachment")!)
} update: { content,attachments in
//
} attachments: {
Attachment(id: "testAttachment") {
VStack{
Text("Hallong")
}
}
}
.gesture(DragGesture().targetedToAnyEntity().onChanged({ value in
print("Angefasst")
value.entity.position = value.convert(value.location3D, from: .local, to: value.entity.parent!)
}))
.gesture(TapGesture().targetedToAnyEntity().onEnded({ value in
var cubeMaterial = PhysicallyBasedMaterial()
cubeMaterial.baseColor = PhysicallyBasedMaterial.BaseColor(tint: .red)
let cubeGeometry: MeshResource = .generateBox(size: 0.1)
let cube = ModelEntity(mesh: cubeGeometry, materials: [cubeMaterial])
//CollisionComponent
let collisionCube = CollisionComponent(shapes: [.generateBox(width: 0.1, height: 0.1, depth: 0.1)])
cube.components.set(collisionCube)
//InputTarget
cube.components.set(InputTargetComponent())
//PhysicsBodyComponent
let materialPhysicsCube = PhysicsMaterialResource.generate(friction: 0.8, restitution: 0.0)
cube.components.set(PhysicsBodyComponent(shapes: cube.collision!.shapes, mass: 1, material: materialPhysicsCube, mode: .dynamic))
newCubes.addChild(cube)
}))
}
HStack{
VStack{
Text("Hallo")
}
VStack{
Text("Zwei")
}
}
}
}
#Preview(windowStyle: .volumetric) {
ContentView()
}
How can I manage, that the force is disabled (or something else) during the DragGesture?
When the gesture is applied, you must have a Kinematic
mode active, and immediately after ending the gesture, Dynamic
mode should be turned on, in which a gravity will be activated.
var dragGesture: some Gesture {
DragGesture()
.targetedToAnyEntity()
.onChanged {
$0.entity.position = $0.convert($0.location3D, from: .local,
to: $0.entity.parent!)
$0.entity.components[PhysicsBodyComponent.self]?.mode = .kinematic
}
.onEnded {
$0.entity.components[PhysicsBodyComponent.self]?.mode = .dynamic
}
}