エンジニア

MFi Game Controllersに対応してみよう!

投稿日:2014年5月28日 更新日:

今回のエンジニアブログを担当する村田です。

本日はiOS7で追加された「MFi Game Controllers」について紹介します。
「MFi Game Controllers」はiOS7で追加された機能にも関わらず、
これについて書かれた記事を目にする事はあまりありません。何だか残念です。

MFi Game Controllersとは?

簡単に言いますと、AppleにはMFi Programというものがあり、このMFiライセンスに対応したGame ControllersのことをMFi Game Controllersと呼びます。

国内ではLogicool社から「G550 Powershell controller + battery」という製品が発売されております。
まだ少ないのが現状です。

MFi Game Controllers対応アプリ

Logicool社のホームページ情報によると、G550に対応したアプリは170以上はあるようです。
※ Logicool社による G550に対応したアプリ一覧

最近では「MONSTER HUNTER PORTABLE 2nd G for iOS」が、MFi Game Controllersに対応されております。
スクウェア・エニックスの「ファイナルファンタジー」シリーズが随時対応していくニュースも話題になったかと思います。

徐々にではありますが、MFi Game Controllers対応アプリが増えてきております。

MFi Game Controllers対応アプリの作り方

ここからは、MFi Game Controllers対応アプリの作成手順を説明します。

1. 必要なフレームワークの追加
MFi Game Controllersからの入力をプログラムで受け取るには、
「GameController.framework」が必要です。
Xcodeのプロジェクト設定 - [General] から追加します。

あとは 「GameController.framework」内のGameController.hファイルをimportすれば、関連するクラスは全て扱えます。
【使用例】

#import <UIKit/UIKit.h>
#import <GameController/GameController.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

2. MFi Game Controllersの接続/切断の通知
MFi Game Controllersが接続/切断されたイベントを受け取りたい場合は、
NSNotificationCenterクラスに通知を登録します。

NSNotificationCenter* center = [NSNotificationCenter defaultCenter];

// 接続されたときの通知を登録  
[ center addObserver:self
            selector:@selector(setupControllers:)
                name:GCControllerDidConnectNotification
              object:nil];

// 切断されたときの通知を登録  
[ center addObserver:self
            selector:@selector(setupControllers:)
                name:GCControllerDidDisconnectNotification
              object:nil];

Appleのドキュメントでは、
 -application:didFinishLaunchingWithOptions:

で、通知の登録を行いましょうと記載されております。

3. MFi Game Controllersのエントリポイントの取得
現在接続されているMFi Game Controllersを取得する場合は、
GCControllerクラスに定義されたcontrollersというstaticなメソッドを呼び出します。

@interface GCController : NSObject
+ (NSArray *)controllers
...

戻り値のNSArrayには現在接続されているゲームコントローラーが、GCControllerクラスのインスタンスとして格納されます。

【使用例】

- (void)setupControllers:(NSNotification *)notification
{
  // Controllersを取得  
  self.controllerArray = [GCController controllers];

  if ([self.controllerArray count] > 0) {
    // 接続されたControllersがある場合  
  } else {
    // 接続されたControllerが無い場合  
  }
}

4. MFi Game Controllersからの入力
まず、MFi Game Controllersには、2つのProfileが存在します。
1つは「Standard Gamepad Profile」、もう1つは「Extended Gamepad Profile」です。
「G550 Powershell controller + battery」は「Standard Gamepad Profile」になります。

今回は「Standard Gamepad Profile」を紹介します。「Standard Gamepad Profile」には、大きく3つの入力方法が存在します。
実際に「G550 Powershell controller + battery」の写真で確認してみましょう。
IMG_13132

  • LRボタンの『Shoulder buttons』
  • 十字キーの『D-pad』
  • ABCDボタンの『Face buttons』

ごく一般的なゲームコントローラーと同じ入力ですね。

では、これら入力方法の入力値の取得方法について、まずサンプルソースを見てみましょう。

// self.myControllerは、GCControllerのインスタンスです。  
// Shoulder buttons  
self.myController.gamepad.leftShoulder.pressed; // Lボタンが押されているか  
self.myController.gamepad.leftShoulder.value;   // Lボタンがどこくらい押されているか  

// D-pad  
self.myController.gamepad.dpad.up.pressed;   // 十字キーの上方向が押されているか  
self.myController.gamepad.dpad.up.value;     // 十字キーの上方向がどのくらい押されているか  
self.myController.gamepad.dpad.xAxis.value;  // 十字キーのX座標方向(左右の方向)にどう押されているか  

// Face buttons  
self.myController.gamepad.buttonY.pressed; // Yボタンが押されているか  
self.myController.gamepad.buttonY.value;   // Yボタンがどのくらい押されているか  

GCControllerにはgamepadプロパティがあり、GCGamepadクラスのインスタンスを取得できます。
GCGamepadから各入力方法へアクセスします。表にまとめると、このようになります。

入力方法 プロパティ名 タイプ
Shoulder buttons leftShoulder Button Input
rightShoulder
D-pad dpad DirectionPad
Face buttons buttonA Button Input
buttonB
buttonX
buttonY

プロパティ名が分かりやすいので、あまり迷う事はないかと思います。
タイプについて説明します。

タイプ:「Button Input」
「Button Input」では、2パターンの値を返します。

  • BOOL pressed;
    ボタンが押されたかを、BOOL値で取得。
  • float value;
    ボタンがどのくらい押されているか。値の範囲は、0.0〜1.0。

大抵、pressedのみで足りるかと思います。

タイプ:「DirectionPad」
「DirectionPad」では、まず入力の方向を取得し、その方向に対しての押し込み具合を返します。

  • GCControllerButtonInput *up, *down, *left, *right;
    上下左右を取得。
    • BOOL pressed;
      ボタンが押されたかを、BOOL値で取得。
    • float value;
      ボタンがどのくらい押されているか。値の範囲は、0.0〜1.0。
  • GCControllerAxisInput *xAxis, *yAxis;
    X軸、Y軸を取得。
    • float value;
      ボタンがどのくらい押されているか。値の範囲は、-1.0〜1.0。
      図で表すとこのようになります。
      Axis
      ニュートラルな状態が、0.0になります。
  • 5. プログラムへの実装
    MFi game controllersからの入力方法が分かれば、あとはプログラムに実装するだけです。
    iOS、Objective-Cでゲームと言えば、SpriteKitです。
    SpriteKitについては、こちらのブログをご覧下さい。

    SpriteKitを使っている場合は
     - (void)update:(CFTimeInterval)currentTime
    で使用します。

    まとめ

    調べる前は一見大変そうだなと思いましたが、調べてみると思いのほかMFi Game Controllers対応は簡単でした。
    Apple DeveloperのWWDC 2013 Session Videosの中に「Integrating with Game Controllers」というセッションのドキュメントがありましたので、こちらが分かりやすく一番参考になりました。今回は説明しなかった、PauseボタンやLEDといったものの制御方法まで記載されております。

    MFi Game Controllers製品は、まだまだ少ないですが、発売予定はあるので楽しみです。
    特にWirelessタイプは、iPhoneとの接続が簡単で、サイズを問わないので楽しみです。

採用情報

ワンダープラネットでは、一緒に働く仲間を幅広い職種で募集しております。

-エンジニア
-,

© WonderPlanet Inc.