Find the entity tapped in RealityView?

Hi! With the following code I am able to receive the location of taps in my RealityView.

How do I find out which of my entities was tapped (in order to execute an animation or movement)? I was not able to find anything close to ARView's entity(at:) unfortunately. Am I missing something, or is this not possible in the current beta of visionOS?

struct ImmersiveView: View {
        
    var tap: some Gesture {
        SpatialTapGesture()
            .onEnded { event in
                print("Tapped at \(event.location)")
            }
    }
    
    var body: some View {
        RealityView { content in
           let anchor = AnchorEntity(.plane(.horizontal, classification: .table, minimumBounds: [0.3, 0.3]))

           // adding some entities here...

           content.add(anchor)
        }
        .gesture(tap.targetedToAnyEntity())
    }
}

Accepted Reply

Hello, give something like this a try :)

var tap: some Gesture {
    SpatialTapGesture()
        .targetedToAnyEntity()
        .onEnded { value in
            // Access the tapped entity here.
            print(value.entity)
        }
}
  • OMG 🤦‍♂️

    It looks like I was applying .targetedToAnyEntity() in the wrong way / in the wrong place, and hence not seeing the entity method... Now it works :) Many thanks!

  • No worries :), it's important to keep in mind that functions called on SwiftUI Views/Gestures can actually transform the View type that you are working with. In this example, the targetedToAnyEntity function transforms the SpatialTapGesture into Gesture<EntityTargetValue<SpatialTapGesture.Value>>.

    This has the effect of providing an EntityTargetValue in the onEnded closure (instead of a normal SpatialTapGesture.Value), which gives you access to the entity that was tapped.

  • Thank you for posting this.

Add a Comment

Replies

Hello, give something like this a try :)

var tap: some Gesture {
    SpatialTapGesture()
        .targetedToAnyEntity()
        .onEnded { value in
            // Access the tapped entity here.
            print(value.entity)
        }
}
  • OMG 🤦‍♂️

    It looks like I was applying .targetedToAnyEntity() in the wrong way / in the wrong place, and hence not seeing the entity method... Now it works :) Many thanks!

  • No worries :), it's important to keep in mind that functions called on SwiftUI Views/Gestures can actually transform the View type that you are working with. In this example, the targetedToAnyEntity function transforms the SpatialTapGesture into Gesture<EntityTargetValue<SpatialTapGesture.Value>>.

    This has the effect of providing an EntityTargetValue in the onEnded closure (instead of a normal SpatialTapGesture.Value), which gives you access to the entity that was tapped.

  • Thank you for posting this.

Add a Comment

I've tried a whole bunch of variations of this and can't seem to get any gestures to fire on a RealityView. I went back and watched the video again, created a new Sample Project, combed through the HappyBeam project, tried various ways of syntactically representing gestures, tried generic vs SpatialTapGestures, etc.

Is there something obvious I'm missing?

This gesture model works fine on any of the SwiftUI elements in Windows. It's only in Immersive mode with a RealityView that nothing seems to work.

On the latest Xcode beta 4, visionOS Beta 1.

import SwiftUI
import RealityKit
import RealityKitContent

struct ImmersiveView: View {
    var body: some View {
        RealityView { content in
            // Add the initial RealityKit content
            if let scene = try? await Entity(named: "Immersive", in: realityKitContentBundle) {
                content.add(scene)
            }
        }
        .gesture(SpatialTapGesture().onEnded { _ in
            print("Hello Reality")
        })
    }
}
Add a Comment