Google

2012年8月31日金曜日

Unityでコインゲー開発;ネイティブ拡張の実際

今回はiOS版で拡張した際の話とその詳細。

あちこちで書かれているので今更感はありますが、外部連携時の細かい話をば。
このときの要求はこんなでした。

 「公式にHTML置くんで、Unityからシームレスに表示して欲しい」

となれば、iOSならUIWebViewを使うことになります。
Safariが起動して、本体がバックタスクに回るのはNGって事ですな。
その際に行ったのは以下のような処理でした。

 ・プラグインは自前で全て実装
 ・UnityFWのUIVewの上にUIWebViewを被せる形
 ・後はURLにアクセスするだけ

そういえばUnity拡張時の基本の概念がなかったので改めて書いてみます。
Unity自身は、プロジェクト内部に包含されたソースやリソースについて、どれがどのプラットフォームで使うのか、という区別が付きません。
ファイルひとつひとつにそういった属性の情報を細かく持っている訳ではないという事です。
では何でやっているかというと、これで区別しているのです。

 「Project以下のディレクトリに付けられた名称」

単純過ぎて管理ミスがでそうな仕組みですが、昔からこうです。
で、外部連携プラグインを設置していい場所も決まっています。
iOSやAndroidの場合はここ。


Pluginsの下にiOSとAndroidがありますが、この下に各々ネイティブコードのソースを設置します。
ここまで適当にプラグイン、プラグインと言ってますが、明確に書くとUnityのプラグインとは以下のような構成になります。

 [Unity Plugin構成]
  /Assets/Plugins/
    C#/JSで書かれたstatic関数だけの集まりクラス
  /Assets/Plugins/(ネイティブOS名)
    ネイティブコードで書かれた実装処理

最低でもこの2組の構成が1つのプラグインとして動作します。
ネイティブの方は自由に書けますが、UnityFWを含んだ塊がアプリの本体で、そこに対して処理を行うとか、上にViewを被せるとかの概念を気にしなければなりません。
Unity側の方はむしろAdapterパターンとなり、Unity側との橋渡しがメインです。
そしてこのUnity側のクラスは全てコンパイル前にアドレスが決定しなくてはならず、その関係で全てstatic関数で構成する必要があります。
例えばこんな感じに書きます。


public static class iOSPlugin
{
// Safariを起動。被せるURLは決まっているので引数なし
[DllImport ("__Internal")]
public static extern void startSafari();
}


これはiOS版ですがAndroidでも原理だけは同じで全てstatic関数必須です。
初期化、実行、メモリ解放等の考慮して順序良く呼ばれることを想定した関数群にし、呼び出しもそれを守る必要があります。
あーめんどくさいですな。

ちなみにわざわざプラグインを書いてにアクセスする理由ですが、現場ではこんな裏事情がありました。
 
 ・ランキング情報を送信してユーザに見せたい
 ・コレクション実績をサーバに送信したい
 ・コイン残数を同期して不正防止したい、、、、等々

中身の処理の詳細は長くなるので今回は割愛。
しかし、サーバ連携の基本GET/POSTの仕組みはネイティブ側で行うので、Unityからは引数で渡すだけの話です。

次回はちょっとずれて、XCodeでまれに発生するプラグイン実装時エラーの回避方法を書きます。

0 件のコメント:

コメントを投稿