A Game Controller For visionOS RealityView

Im searching for a simple swiftUI code that can move a cube in immersive space when I click the X button on Sony Playstation Game Controller, I did load a USD entity and connect the game controller but when it comes to get a simple click into the reality view to change position or rotate the entity it always not even accepted in codes. although I can control it with a finger or hand gestures, and yes I have closed the "Send Game Controller to device" in the simulator to make sure the controller would not effect the system but only effect in the game,

here is a sample

import SwiftUI
import RealityKit
import GameController

struct ImmersiveView: View {
    @State var entity = ModelEntity()
    @State var z: Float = -4.0

    var body: some View {
        RealityView { content in
            if let cube = try? await ModelEntity(named: "am.usdz") {
                entity = cube
                entity.generateCollisionShapes(recursive: true)
                entity.name = "Cube"
                entity.position = [0, 0, -4]
                entity.components.set(InputTargetComponent(allowedInputTypes: .indirect))
                entity.components.set(HoverEffectComponent())

                content.add(entity)
            }
        }
        .gesture(
            SpatialTapGesture()
                .targetedToEntity(entity)
                .onEnded { value in
                    print(value)
                    z -= 1.0
                    entity.position = [0, 0, z]
                }
            )
        // What to do here to make game controller button X act as the gesture do 
    }
}

Accepted Reply

I figure it out myself

import SwiftUI
import RealityKit
import GameController
struct ImmersiveView: View {
    @State var entity = ModelEntity()
    @State var z: Float = -4.0

    @State var connected = false
    @State var controller = GCController()

    var body: some View {
        RealityView { content in
            if let cube = try? await ModelEntity(named: "am.usdz") {
                entity = cube
                entity.generateCollisionShapes(recursive: true)
                entity.name = "Cube"
                entity.position = [0, 0, -4]
                entity.components.set(InputTargetComponent(allowedInputTypes: .indirect))
                entity.components.set(HoverEffectComponent())

                content.add(entity)
            }
        }
        .gesture(
            SpatialTapGesture()
                .targetedToEntity(entity)
                .onEnded { value in
                    print(value)
                    z -= 1.0
                    entity.position = [0, 0, z]
                }
            )
        
        .onAppear(perform: {
            // Start Using The Game Controller
            NotificationCenter.default.addObserver(forName: NSNotification.Name.GCControllerDidConnect, object: nil, queue: nil, using: didConnectController)
            NotificationCenter.default.addObserver(forName: NSNotification.Name.GCControllerDidDisconnect, object: nil, queue: nil, using: didDisconnectController)
            GCController.startWirelessControllerDiscovery{}
        })
    }
    
    func didConnectController(_ notification: Notification) {
        connected = true
        controller = notification.object as! GCController
        print("◦ connected \(controller.productCategory)")
        
        controller.extendedGamepad?.buttonA.pressedChangedHandler = { (button, value, pressed) in self.button("X", pressed)}
    }
    
    func didDisconnectController(_ notification: Notification) {
        connected = false
        controller = notification.object as! GCController
        print("◦ disConnected \(controller.productCategory)")
    }
    
    func button(_ button: String, _ pressed: Bool){
        
        if button == "X" && pressed
        {
            z -= 1.0
            entity.position = [0, 0, z]
        }
    }
}

Replies

I figure it out myself

import SwiftUI
import RealityKit
import GameController
struct ImmersiveView: View {
    @State var entity = ModelEntity()
    @State var z: Float = -4.0

    @State var connected = false
    @State var controller = GCController()

    var body: some View {
        RealityView { content in
            if let cube = try? await ModelEntity(named: "am.usdz") {
                entity = cube
                entity.generateCollisionShapes(recursive: true)
                entity.name = "Cube"
                entity.position = [0, 0, -4]
                entity.components.set(InputTargetComponent(allowedInputTypes: .indirect))
                entity.components.set(HoverEffectComponent())

                content.add(entity)
            }
        }
        .gesture(
            SpatialTapGesture()
                .targetedToEntity(entity)
                .onEnded { value in
                    print(value)
                    z -= 1.0
                    entity.position = [0, 0, z]
                }
            )
        
        .onAppear(perform: {
            // Start Using The Game Controller
            NotificationCenter.default.addObserver(forName: NSNotification.Name.GCControllerDidConnect, object: nil, queue: nil, using: didConnectController)
            NotificationCenter.default.addObserver(forName: NSNotification.Name.GCControllerDidDisconnect, object: nil, queue: nil, using: didDisconnectController)
            GCController.startWirelessControllerDiscovery{}
        })
    }
    
    func didConnectController(_ notification: Notification) {
        connected = true
        controller = notification.object as! GCController
        print("◦ connected \(controller.productCategory)")
        
        controller.extendedGamepad?.buttonA.pressedChangedHandler = { (button, value, pressed) in self.button("X", pressed)}
    }
    
    func didDisconnectController(_ notification: Notification) {
        connected = false
        controller = notification.object as! GCController
        print("◦ disConnected \(controller.productCategory)")
    }
    
    func button(_ button: String, _ pressed: Bool){
        
        if button == "X" && pressed
        {
            z -= 1.0
            entity.position = [0, 0, z]
        }
    }
}