Skip to content

Bidirectional Communication

Rob Reuss edited this page Dec 14, 2015 · 4 revisions

What Is It?

Bidirectional communication refers to the ability of Virtual Game Controller to support transmitting values from the Central (your game) to a software-based Peripheral. Some example scenarios:

  • A quiz game where a set of possible answers is sent to each player or the question/answer is sent to a rotating player who plays master of ceremonies.
  • Sending a screen flash or vibration to an iOS device. This is demonstrated in the iOS Peripheral sample project. (There is now a method on a VgcController instance vibrateDevice()to simplify vibrating the device, without using custom elements.)
  • Dynamically changing the controller input design.
  • Sending images from the Central to the Peripheral. There is an Element data type "Data" that sends NSData between Centrals and Peripherals (and the reverse) that is a separate stream, thereby minimizing the impact on core performance.

Obviously, bi-directional functionality will not work with hardware-based controllers, so if you plan to support both software and hardware controllers, you'll need to work around this limitation. One way to work around it is to use bridging, where the bridge itself serves the role of recieving messages from the Central.

Standard and Custom Elements Supported

Since bidirectional communication goes beyond the standard capabilities of Apple's Game Controller framework, it makes sense to define custom elements when you need to communicate from a Central to a Peripheral. However, Central-to-Peripheral transmission of standard elements is also supported.

Defining Custom Elements

See the wiki article that explains how to define custom elements.

Sending From the Central to a Peripheral

Sending an element value from a Central to a Peripheral is done using this syntax:

element.value = yourElementValue
controller.sendElementStateToPeripheral(element)

To receive the element on the Peripheral side, simply set up a handler in the viewDidLoad method similar to setting a handler on the Central side:

if let element: Element = VgcManager.elements.elementFromIdentifier(CustomElementType.SendImage.rawValue) {
    
    element.valueChangedHandlerForPeripheral = { (element: Element) in
        
        print("Custom element handler fired for Send Image")
        self.peripheralControlPadView.imageView.image = UIImage(data: element.value as! NSData)
        
    }
}