🍎

【GameMaker】iOS拡張機能からAsyncイベントを飛ばす方法

に公開

拡張機能で実装したカメラ・ギャラリー・テキスト入力などのiOSネイティブの機能から
非同期で値を受け取るための方法です。

今回はObjective-Cで実装したUITextField(1行の入力可能なテキストボックス)で、
ユーザーが入力後エンターキーを押したことをGameMakerに伝えるために
Objective-CでAsyncイベント用のDSMapを作成し、GameMakerへ飛ばします。

GameMaker向けiOS拡張機能を作れることが前提です。
noteですみませんが過去に書いた記事があるので参考にしてください。
https://note.com/rokkindonesia/n/n19c266c6101a

また、Objective-Cに関しては特に経験もなく、chatGPTにほとんど丸投げの
最低限動くだけのコードしか書けませんのでご了承ください。

やり方

.mmファイルに下記を追加すると
Asyncイベント用のDSMapを作成するメソッドと
作成したDSMapをAsyncイベントとして飛ばすメソッドが使えるようになります。
(EVENT_OTHER_SOCIALはのちに引数として使う定数なのであってもなくても可)

const int EVENT_OTHER_SOCIAL = 70;
extern int CreateDsMap( int _num, ... );
extern void CreateAsynEventWithDSMap(int dsmapindex, int event_index);

GameMakerがiOS拡張機能用に用意しているメソッドらしく
externで使えるようになります。

CreateDsMap

Asyncイベント用のDSMapを作成するメソッドです。

使用例

int dsmap = CreateDsMap(1,"type",0.0,"UITextField_ShouldReturn");

引数の意味

  • 1 → 作成するDSMapにキーと値のペアがいくつあるか
  • "type" → 1つ目のキー
  • 0.0 → 1つ目の値の型
  • "UITextField... → 1つ目の値

以下、複数のペアを作成する場合は第二引数〜第四引数を繰り返します。

こちらの例では、「ペアが1つで、"type"というキーに"UITextField..."という値が入ったDSMapを作成」することができます。

こちらのDSMapをGameMakerのasync_loadで参照するとしたら,

async_load[? "type"]

"UITextField_ShoudReturn"

を受け取ることができます。

第三引数の値の型は

  • 0.0 string
  • 1.0 real
  • 2.0 不明
  • 3.0 bool

を示しているのだと思いますが、いかんせんどこにも資料がなくchatGPTに聞いたり
公式拡張機能のコードを読み解いた結果なので、合っているかどうかわかりません。

CreateAsynEventWithDSMap

Asyn"c"が抜けているのは仕様なのかyoyogamesの人のお茶目なミスなのかはわかりません

また、こちらはDSMapですが先ほどのメソッドはDsMapと、大文字小文字が
混在しているため注意してください。

こちらのメソッドでAsyncイベントをGameMakerに飛ばせます。

使用例

CreateAsynEventWithDSMap(dsMap,EVENT_OTHER_SOCIAL);

引数の意味

  • dsMap → createDsMapで作成したDSMap
  • EVENT_OTHER_SOCIAL 最初にconstで設定した定数(70)

Asyncイベントの定数に関しては公式マニュアルに載っていますが、
イベントの種類によって動作が異なるっぽいので
基本的にSOCIALの70を使うのがおすすめです。
(公式のMobileUtils拡張機能も大体70です)

https://manual.gamemaker.io/lts/en/The_Asset_Editors/Object_Properties/Async_Events.htm

実装(Xcode)

今回、UITextFieldでユーザーがリターンを押したことをGameMakerに伝えたいのですが
その場合textFieldShouldRetrunというメソッドに追記することで実装できます。

//リターンキー押下のデリゲートメソッド
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    NSLog(@"textFieldShouldReturnを実行");
    int dsMap = CreateDsMap(1,"type",0.0,"UITextField_ShouldReturn");
    CreateAsynEventWithDSMap(dsMap,EVENT_OTHER_SOCIAL);
    
    return YES;
}

リターンが押されると

  1. NSLogでtextFieldShouldReturnが呼び出されたことを出力(デバッグ用)
  2. dsMapを作成
  3. dsMapをAsyncイベント - Socialに送信

という処理が行われますので、このdsMapをGameMakerで受け取っていきます。

実装(GameMaker)

Asyncイベントを実行したいオブジェクトで
Async - ソーシャル(Async - Social)イベントを作成します。

下記のコードを入力します。

if async_load[? "type"] == "UITextField_ShouldReturn"{
    show_debug_message("リターン押下");
}

実行するとリターンキーをタップするとGameMakerにAsyncイベントが送信され、
デバッグログにメッセージが出力されます。


(GMLiveという拡張機能を使用している都合でGameMakerのIDEにデバッグログが出ないのでXcodeで見ています)

以上になります。
ご覧いただきありがとうございました。

Discussion