-
Notifications
You must be signed in to change notification settings - Fork 43
Creating a Software based Controller (Peripheral)
See the project named "Peripheral_iOS" for a reference implementation of a Peripheral. Most all possible functionality is represented in that project, particularly the ViewController. It can be used to drive the other sample projects that execute as Centrals, but especially with the Central reference implementation called "Central_iOS".
Note that in the following example, no custom elements or custom mappings are being set. See elsewhere in this document for a discussion of how those are handled (or see the sample projects).
VgcManager.startAs(.Peripheral, appIdentifier: "MyAppID", customElements: CustomElements(), customMappings: CustomMappings(), includesPeerToPeer: false, enableLocalController: false)
The parameter appIdentifier
is for use with Bonjour and should be a short, unique identifier for your app.
A simplified form is available if custom mapping and custom elements are not used:
VgcManager.startAs(.Peripheral, appIdentifier: "MyAppID", includesPeerToPeer: false)
Documentation of the custom mapping and custom elements functionality is coming soon, although the combination of the sample projects and class files are probably enough for you to get going.
The includesPeerToPeer
parameter is passed through to NSNetServices. It provides the functionality for connectivity to fallback to Bluetooth or WiFi peer-to-peer. It should be noted that if you plan to only support WiFi, it should be set to false because it has a negative performance impact even when running on WiFi. See the NSNetServices documentation for more information.
The enableLocalController
parameter supports utilizing the VGC interface as a common interface to triggering game activity in response to controller input on both the local implementation of a game and a remote implementation of the same game (on a Central). It is used as a part of a multiplayer implementation. The functionality allows you to define local handlers in the same way as you define them on the Central. This functionality will still be active even when not connected to a Central. See Multiplayer Implementation below for more information.
After calling the startAs
method, the Peripheral may be defined by setting it's deviceInfo
property. Doing so is not required as the defaults (shown here) should suffice for most purposes.
VgcManager.peripheral.deviceInfo = DeviceInfo(deviceUID: "", vendorName: "", attachedToDevice: false, profileType: .ExtendedGamepad, controllerType: .Software, supportsMotion: true)
Pass an empty string to deviceUID
to have it be created by the system using NSUUID()
and stored to user defaults.
Pass an empty string to vendorName
and the device network name will be used to identify the Peripheral.
Begin the search for Bridges and Centrals:
VgcManager.peripheral.browseForServices()
Access the current set of available services:
VgcManager.peripheral.availableServices
Related notifications - both notifications carry a reference to a VgcService as their payload:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "foundService:", name: VgcPeripheralFoundService, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "lostService:", name: VgcPeripheralLostService, object: nil)
In the simplest implementation, you'll be connecting to the first Central service you find, whereas if you always use a Bridge, you'll be connecting to the first Bridge you find. In those cases, you'll want to start the search and use the VgcPeripheralFoundService
notification to call the connectToService
method.
If you choose to implement a more complex scenario, where you have multiple Peripherals that connect to either a Bridge or Central, the combination of the above methods and notifications should have you covered. The sample projects implement this type of flexible scenario.
Once a reference to a service (either a Central or Bridge) is obtained, it is passed to the following method:
VgcManager.peripheral.connectToService(service)
To disconnect from a service:
VgcManager.peripheral.disconnectFromService()
Related notifications:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "peripheralDidConnect:", name: VgcPeripheralDidConnectNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "peripheralDidDisconnect:", name: VgcPeripheralDidDisconnectNotification, object: nil)
An Element class is provided, each instance of which represents a hardware or software controller element. Sets of elements are made available for each supported profile (Micro Gamepad, Gamepad, Extended Gamepad and Motion). To send a value to the Central, the value property of the appropriate Element object is set, and the element is passed to the sendElementState
method.
let leftShoulder = VgcManager.elements.leftShoulder
leftShoulder.value = 1.0
VgcManager.peripheral.sendElementState(leftShoulder)
When a Central assigns a player index, it triggers the following notification which carries the new player index value as a payload:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "receivedPlayerIndex:", name: VgcNewPlayerIndexNotification, object: nil)
Support for motion updates is contingent on Core Motion support for a given platform (for example, it is not supported on OS X). The framework should detect it if an attempt is made to start motion updates on an unsupported platform.
Key methods that should be self-explanatory:
VgcManager.peripheral.motion.start()
VgcManager.peripheral.motion.stop()
VgcManager.peripheral.motion.enableUserAcceleration = true
VgcManager.peripheral.motion.enableGravity = true
VgcManager.peripheral.motion.enableRotationRate = true
VgcManager.peripheral.motion.enableAttitude = true
VgcManager.peripheral.motion.updateInterval = 1/60
VgcManager.peripheral.motion.enableAdaptiveFilter = true
VgcManager.peripheral.motion.enableLowPassFilter = true
It is important for performance reasons to reduce updateInterval as much as you can, and to disable motion inputs that are not used in your game.