You need to call a Spatial Tap Gesture
Like this
.gesture(
SpatialTapGesture()
.targetedToEntity(entity)
.onEnded { value in
print("you touch me")
}
)
Here is a full example with a mesh cube you can touch it with your finger to animate and jump up , using double tap it would jump up more
import SwiftUI
import RealityKit
struct Cube: View {
@State var z: Float = 0.0
@State private var subs: [EventSubscription] = []
@State private var contentEntity = Entity()
@State var cube1 = ModelEntity()
var body: some View {
RealityView { content, attachments in
content.add(setupContentEntity())
cube1 = addCube(name: "Cube1", posision: SIMD3(x: 1, y: 1, z: -2), color: .red)
if let attachment = attachments.entity(for: "cube1_label") {
attachment.position = [0, -0.35, 0]
cube1.addChild(attachment)
}
} attachments: {
Attachment(id: "cube1_label") {
Text("Cube1")
.font(.system(size: 48))
}
}
.gesture(
SpatialTapGesture()
.targetedToEntity(cube1)
.onEnded { value in
print(value)
playAnimation(entity: cube1)
}
)
}
func setupContentEntity() -> Entity {
return contentEntity
}
func getTargetEntity(name: String) -> Entity? {
return contentEntity.children.first { $0.name == name}
}
func addCube(name: String, posision: SIMD3<Float>, color: UIColor) -> ModelEntity {
let entity = ModelEntity(
mesh: .generateBox(size: 0.5, cornerRadius: 0),
materials: [SimpleMaterial(color: color, isMetallic: false)],
collisionShape: .generateBox(size: SIMD3<Float>(repeating: 0.5)),
mass: 0.0
)
entity.name = name
entity.position = posision
entity.components.set(InputTargetComponent(allowedInputTypes: .indirect))
entity.components.set(CollisionComponent(shapes: [ShapeResource.generateBox(size: SIMD3<Float>(repeating: 0.5))], isStatic: true))
entity.components.set(HoverEffectComponent())
contentEntity.addChild(entity)
return entity
}
func playAnimation(entity: Entity) {
let goUp = FromToByAnimation<Transform>(
name: "goUp",
from: .init(scale: .init(repeating: 1), translation: entity.position),
to: .init(scale: .init(repeating: 1), translation: entity.position + .init(x: 0, y: 0.4, z: 0)),
duration: 0.2,
timing: .easeOut,
bindTarget: .transform
)
let pause = FromToByAnimation<Transform>(
name: "pause",
from: .init(scale: .init(repeating: 1), translation: entity.position + .init(x: 0, y: 0.4, z: 0)),
to: .init(scale: .init(repeating: 1), translation: entity.position + .init(x: 0, y: 0.4, z: 0)),
duration: 0.1,
bindTarget: .transform
)
let goDown = FromToByAnimation<Transform>(
name: "goDown",
from: .init(scale: .init(repeating: 1), translation: entity.position + .init(x: 0, y: 0.4, z: 0)),
to: .init(scale: .init(repeating: 1), translation: entity.position),
duration: 0.2,
timing: .easeOut,
bindTarget: .transform
)
let goUpAnimation = try! AnimationResource
.generate(with: goUp)
let pauseAnimation = try! AnimationResource
.generate(with: pause)
let goDownAnimation = try! AnimationResource
.generate(with: goDown)
let animation = try! AnimationResource.sequence(with: [goUpAnimation, pauseAnimation, goDownAnimation])
entity.playAnimation(animation, transitionDuration: 0.5)
}
}