Discovering and Connecting to Controllers
A physical controller is represented in your game by a
GCController object. The Game Controller framework creates these objects for you when a controller is connected to the device, and you work through these objects to configure the controller and read the controller’s inputs. However, before you add input support to your game, you first need to learn how to find and configure controllers.
You will learn about:
Determining which controllers are connected to a device.
Discovering wireless controllers for the first time.
Configuring a connected controller and reading information about the controller.
Finding Connected Controllers
Whether the controllers are connected by a wireless connection or directly attached to an iOS device or Mac, they appear the same in your game. At any time, you can call the
controllers class method to retrieve an array of
GCController objects, one for each connected controller. Then, you use these objects to configure the controllers or read the controller’s inputs.
The Game Controller framework posts notifications when a controller is connected (
GCControllerDidConnectNotification) or disconnected (
object property on the notification object points to the
GCController for the controller whose status has just changed.
Wireless Controllers Must Be Discovered First
A wireless controller must be discovered before it can be connected to an iOS device or Mac. The discover process is triggered on both devices, which then attempt to search for a compatible device. Once discovery is complete, the devices are paired and the controller is connected. The discovery process only happens once. After that, when both devices are turned on, they automatically connect to each other.
Normally, the discovery process happens outside of your game. The player leaves your game, connects the controller, then launches your game again. However, you have the option of adding discovery support directly in your game; when you do, keep the following guidelines in mind:
There is no built-in user interface for discovery. The framework only manages the discovery process. You are responsible for designing and displaying an appropriate interface to the user.
The discovery process may take a long time to complete and the user is busy during the process. Pause active gameplay and other similar behaviors that require user intervention until the discovery process completes.
The discovery process follows these steps:
To start discovering new controllers, call the
startWirelessControllerDiscoveryWithCompletionHandler:class method, passing in a completion handler. Once the discovery process is running, new controllers are automatically discovered and connected to the device. When a new controller is connected, the normal notification is posted.
The discovery process eventually times out. However, you can also call the
stopWirelessControllerDiscoveryclass method to end the process early. (You do this by implementing a cancel button in the game’s user interface and cancel discovery when the user selects it).
After the discovery process ends, your completion handler is called.
The primary reason to hold a
GCController object is to read its input data, but that isn’t the only thing you do with the controller object. You can also:
Set its player index so that you can identify this specific controller later.
Register a handler to be called when the user hits the controller’s pause button.
Player Indices Identify a Controller Persistently
playerIndex property holds an integer value that determines which player is associated with the controller. When the controller later connects, it keeps the same index, giving you the option to implement persistent behavior in the game. For example, you might set the
0, to assign that controller to the “first player” in your game.
Here are some guidelines for player indices:
A player index is persistent for the controller, across all games. Always check player index values to ensure they make sense for your game, and change them if they do not.
An index value can be
0or any positive integer value, but you should almost always use numbers between
3. When you choose a number in this range, a matching LED on the controller lights up.
If you do not want to identify a controller, assign it the value
GCControllerPlayerIndexUnset. This guarantees that the LEDs on the controller are not lit.
Pausing and Resuming
Every game controller includes a pause button. If your game supports controllers, it must also support pausing and resuming from the controller. When pressed, your game should toggle between being active and paused. Even if your game was paused for another reason, pressing the pause button should resume gameplay. For example, if the game pauses when it moves into the background, then you should typically leave the game paused when it returns to the foreground. Gameplay should resume, however, when the user presses the game controller’s pause button.
To implement the pause behavior in your game, you assign a block to a controller object’s
The Game Controller framework does not show a user interface to indicate that the pause button has been pressed. Essentially, it is up to you to implement a handler to toggle your game from active to paused and from paused to active. When the game is paused, you should provide onscreen information that states that the game is paused and how to resume gameplay.
Reading Information About a Controller
You can read a
GCController object’s properties to learn more about the controller. For example, you may want to know whether a user can touch the screen at the same time as he or she works the controls. For more information about what is available from the controller object, see GCController Class Reference.