-
Tap into virtual and physical game controllers
It's time to up your input game: Learn about the latest improvements to virtual and physical game controllers for iPhone, iPad, Mac, and Apple TV. Meet the virtual on-screen controller, which turns touch input into game controller input, and find out how to add controller sharing features to your app. We'll also show you how to support adaptive trigger technology found in DualSense controllers, provide best practices for controller support, and take you through some common pre-flight checks around accessible and customizable input before submitting to the App Store.
For more information on saving highlight clips from a game controller, check out “Discover rolling clips in ReplayKit” from WWDC21.Ressources
Vidéos connexes
WWDC23
WWDC22
WWDC21
WWDC20
-
Rechercher dans cette vidéo…
-
-
2:06 - GameController Basics
func setupGameController() { // Add handler for when controller connects. NotificationCenter.default.addObserver( forName: NSNotification.Name.GCControllerDidConnect, object: nil, queue: nil) { (note) in guard let _controller = note.object? as GCController else { return } // Add controller input change handlers. _controller.physicalInputProfile[GCInputButtonA]?.valueChangedHandler = { ... } _controller.physicalInputProfile[GCInputButtonB]?.valueChangedHandler = { ... } } // Add handler for when controller disconnects. NotificationCenter.default.addObserver( forName: NSNotification.Name.GCControllerDidDisconnect, object: nil, queue: nil) { (note) in ... } } // Polling for controller input. func checkInput() { if controller.physicalInputProfile[GCInputButtonA]?.pressed { ... } if controller.physicalInputProfile[GCInputButtonB]?.pressed { ... } } -
8:42 - Virtual Controller Initial
// Creating an on-screen controller let virtualConfiguration = GCVirtualControllerConfiguration() virtualConfiguration.elements = [GCInputLeftThumbstick, GCInputRightThumbstick, GCInputButtonA, GCInputButtonB] let virtualController = GCVirtualController(configuration: virtualConfiguration) virtualController.connect() -
9:17 - Customizing Buttons
// Creating customized buttons vc.changeElement(GCInputButtonA) { config in let spinningPath = UIBezierPath() // load or draw the spinning attack path config.path = spinningPath return config } vc.changeElement(GCInputButtonB) { config in let jumpPath = UIBezierPath() // load or draw the jump path config.path = jumpPath return config } -
12:06 - DualSense Adaptive Triggers
func updateControllerAdaptiveTriggers() { guard let dualSense = GCController.current?.physicalInputProfile as? GCDualSenseGamepad else { return } let adaptiveTrigger = dualSense.rightTrigger if playerIsPullingSlingshot { let resistiveStrength = min(1, 0.4 + adaptiveTrigger.value) if adaptiveTrigger.value < 0.9 { adaptiveTrigger.setModeFeedbackWithStartPosition( 0, resistiveStrength: resistiveStrength) } else { adaptiveTrigger.setModeVibrationWithStartPosition( 0, amplitude: resistiveStrength, frequency: 0.03) } } else if adaptiveTrigger.mode != .off { adaptiveTrigger.setModeOff() } }
-