skip to Main Content

I’m rendering a scene using Metal and I have a custom renderer that’s passed into a CompositorLayer. I want to use gestures something like

 .onTapGesture {
      print("test")
  }

Currently, the problem is that I can’t wrap the CompositorLayer in a view, so I don’t have access to the gestures API. How can I get access to the gestures API? Ideally, I want the model/mesh in the scene to act like the view.

   ImmersiveSpace(id: "ImmersiveSpace") {
      CompositorLayer(configuration: ContentStageConfiguration()) { layerRenderer in
        let renderer = Renderer(layerRenderer)
        Context.render.layerRenderer = layerRenderer
        Context.state.scene = GameScene()
        renderer.startRenderLoop()
      }
    }.immersionStyle(selection: .constant(.full), in: .full)

Ideally I’d like the code to look something like this

struct Model {
    onTapGesture() {
     
    }
}

2

Answers


  1. Chosen as BEST ANSWER

    You can't use the built in gestures provided by SwiftUI. So you need to manually figure out gestures via HandTrackingProvider.

    @MainActor
    class HandGesture: ObservableObject, @unchecked Sendable {
      let session = ARKitSession()
      var handTracking = HandTrackingProvider()
      var worldTracking = WorldTrackingProvider()
      @Published var latestHandTracking: HandsUpdates = .init(left: nil, right: nil)
     
      
      func start() async {
        do {
          if HandTrackingProvider.isSupported {
            print("ARKitSession starting.")
            try await session.run([handTracking, worldTracking])
          }
        } catch {
          print("ARKitSession error:", error)
        }
      }
      
      func publishHandTrackingUpdates() async {
        for await update in handTracking.anchorUpdates {
          switch update.event {
          case .updated:
            // Do work here
          default:
            break
          }
        }
      }
      
      func monitorSessionEvents() async {
        for await event in session.events {
          switch event {
          case .authorizationChanged(let type, let status):
            if type == .handTracking && status != .allowed {
              // Stop the game, ask the user to grant hand tracking authorization again in Settings.
            }
          default:
            print("Session event (event)")
          }
        }
      }
    }
    
    

Please signup or login to give your own answer.
Back To Top
Search