How to use GCVirtualController directly with SKScene?

GCVirtualController isn't displaying when used with SKScene class. The Virtual controllers appear but then it seems that they are obscured by the SKScene itself!? The documentation says that calling connect() will display the virtual controllers but I seem to be missing how to add the controllers to the SKScene?

class GameScene: SKScene {
    private var _virtualController: Any?
@available(iOS 15.0, *)
    public var virtualController: GCVirtualController? {
        get { return self._virtualController as? GCVirtualController }
        set { self._virtualController = newValue }
    }
    override func didMove(to view: SKView) {
    let background = SKSpriteNode(imageNamed: ".jpg")
        background.zPosition = -1
        addChild(background)

        let virtualConfig = GCVirtualController.Configuration()
        virtualConfig.elements = [GCInputLeftThumbstick, GCInputRightThumbstick, GCInputButtonA, GCInputButtonB]
        virtualController = GCVirtualController(configuration: virtualConfig)
        virtualController?.connect()
    }
}

I've also tried adding the virtual controllers in the UIViewController but this doesn't work either.

It appears the issue only occurs when pushing from one ViewController to the GameViewController. When the GameViewController (with GameScene) is the entry point on the Storyboard the virtual controllers display as expected but if a different ViewController is the entry point and then the GameViewController is shown from that ViewController the issue occurs. 

covaticMyth, I hope you've already found your answer but I wanted to post the code that worked for me so anyone one else might come across it. Also, thank you for posting your question, it helped me.

In the Game Scene, I declared it similar to you:

private var _virtualController: Any?
@available(iOS 15.0, *)
        public var virtualController: GCVirtualController? {
            get {return self._virtualController as? GCVirtualController}
            set {self._virtualController = newValue}
        }

In the Game Scene I also created the following function, which I called in the didMove function:

func configVirtualController(){
        if #available(iOS 15.0, *) {
            let virtualConfig = GCVirtualController.Configuration()
            virtualConfig.elements = [GCInputLeftThumbstick, GCInputButtonA, GCInputButtonB]
            virtualController = GCVirtualController(configuration: virtualConfig)
            virtualController?.connect()
        } else {
            // Fallback on earlier versions
        }

To add my two cents, if you're using the AppDelegate to register the physical MFi controller, aka a physical game controller, you need to write exception logic to make sure that the Virtual Controller isn't included. Otherwise it will create bugs and send the button event twice.

A virtual controller has a vendorName of "Apple Touch Controller".

// MARK: - Controller -

@objc private func controllerWasConnected(_ notification: Notification) {
    
    let controller: GCController = notification.object as! GCController

    let status = "MFi Controller: \(String(describing: controller.vendorName)) is connected"

    print(status)
    
    // make sure it's not virtual

    if controller.vendorName != "Apple Touch Controller" {
     
        gcSharedInstance.reactToInput(controller: controller)
        
    }

}

@objc private func controllerWasDisconnected(_ notification: Notification) {
    
    let controller : GCController = notification.object as! GCController
    
    let status = "MFi Controller: \(String(describing: controller.vendorName)) is disconnected"

    print(status)
    
    // make sure it's not virtual

    if controller.vendorName != "Apple Touch Controller" {
        
        gcSharedInstance.deallocController(controller: controller)
        
    }
    
}

I know this is an old thread, but I just now tackled this issue myself. Reading this thread several times. But I was finally able to see the virtual controller on the second VC. If presenting the second VC, it covers the virtual controller. You can see it briefly when dismissed. But using the navigation controller and self.navigationController?.pushViewController(secondVCName, animated: true). it is no longer hidden. I'm not exactly sure why I can't get it to display above a modal presentation of a VC but it does work when using UINavigationController.

How to use GCVirtualController directly with SKScene?
 
 
Q