How do I connect to a external game controller in swift - apple tv

1.8k Views Asked by At

I have followed this tutorial here: https://cartoonsmart.com/how-to-support-external-game-controllers-with-swift-2-and-sprite-kit-for-the-new-apple-tv/ to connect a external game controller to the apple tv in sprite kit, but I was unable to do it with the tutorials code. I was getting no error message, but it simply was not working. Here is my code:

func setUpControllerObservers() {
    NotificationCenter.default.addObserver(self, selector: #selector(connectControllers), name: NSNotification.Name.GCControllerDidConnect, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(disconnectController), name: NSNotification.Name.GCControllerDidDisconnect, object: nil)
}

func connectControllers() {
    var count = 0
    for controller in GCController.controllers() {
        count = count + 1
        print(count)
        print(controller.extendedGamepad != nil)
        print(controller.microGamepad != nil)
        print(controller.gamepad != nil)
        if (controller.extendedGamepad != nil && controller.playerIndex == .indexUnset) {
            if (count == 1) {
                controller.playerIndex = .index1
            }
            else if (count == 2) {
                controller.playerIndex = .index2
            }
            else if (count == 3) {
                controller.playerIndex = .index3
            }
            else if (count == 4) {
                controller.playerIndex = .index4
            }
            controller.extendedGamepad?.valueChangedHandler = nil
            setupExtendedController(controller: controller)
        }
    }
}

func disconnectController() {

}

func setupExtendedController(controller: GCController) {
    controller.extendedGamepad?.valueChangedHandler = { (gamepad: GCExtendedGamepad, element: GCControllerElement) in
        // not calling
    }
}

When debugging, I found the GCController.controllers() array to be empty, even though it was connected to the apple tv. To be extra sure, I even tested the controller on a app from the app store which worked fine. Can anyone help please?

Edit: here is my didMove function:

didMove(to view: SKView) {
    setUpControllerObservers()
    connectControllers()
}
1

There are 1 best solutions below

3
On BEST ANSWER

When and from which class is your setUpControllerObservers function called? We need some more context to help you out.

Anyway, make sure you manually call your connectControllers function at least once yourself. You can't solely rely on the incoming notification to call that function for you. They mention this in the tutorial you have linked:

Notice too, we are calling connectControllers ourselves right after setUpControllerObservers. The first time the app runs, setUpControllerObservers will cause our NSNotification to also call connectControllers, but if we were to go back and forth between our GameScene and other class, we can’t rely on connectControllers getting called again from the notification. Which is why we call it ourselves.

You should also make sure you don't call these functions before your app has finished launching (e.g. early in the AppDelegate):

Call the controllers class method to retrieve an array of GCController objects for all connected controllers. [...] If there are no connected controllers or you call this method while your app is launching, the array will be empty.


Edit:

For debugging purposes, could you try 'discovering' the controller using the startWirelessControllerDiscovery(completionHandler:) function? (described in Game Controller Programming Guide: Discovering Wireless Controllers)