やや濃厚なソース

プログラミングやゲームについて。

Unity と Android, iPhone のネイティブ連携

Unity でゲームを作る際、
単体で作れるならばそれが一番好ましいんですが、
様々な要因によりネイティブとのハイブリッドで動かさないと
いけないことも起こることもあるかと思います。
これはその記録です。
玄人向けの説明です。Unity, Android, iPhone 初心者はやらない方がいいと思います。
あと、非推奨の動かし方ですのでサポートももちろん受けられません。

Android
Activity 単位で連携させるのが一番容易。
MyActivity が俺ソース、UnityActivity が Unity が書き出したソース。
MyActivity から UnityActivity へのデータの送信は intent を使い、UnityActivity から Unity のコアへのデータ送信は UnitySendMessage を使った。UnitySendMessage の第3引数を null にしてると動かないことがあったので、送るデータが無くても空文字を送りましょう。
Unity コアから MyActivity へは intent を使ってデータを飛ばした。

注意としては、UnityActivity の OnDestory 関数 が呼ばれると、Unity コア内部で Application.Exit が呼ばれるのか、MyActivity まで死んでしまうことが起こった。
そこで、UnityActivity は一回作られると、アプリ起動中はずっと、単一 Activity が必ず存在するようにし Activity が死なないように設定を行った(Launch mode = Single Task)。

iPhone
ViewControllerを取り替える方法で連携させた、というかこれ以外方法が思いつかなかった。
MyAppController が俺ソース、UnityAppController が Unity が書き出したソース。
MyAppController も UnityAppController もそれぞれ、Window, ViewController, View を新しく作成するが、
アプリ内に複数の Window があるとうまく動作しないため、単一の Window しか作成されないようにした。
具体的には、ApplicationDelegate を MyAppController も、UnityAppController も継承しているが、
まず ApplicationDelegate を MyAppController に継承させ、次に MyAppController を UnityAppController で継承させた。
もちろん、application:didFinishLaunchingWithOptions: などの関数は、親を呼び出し処理するようにすること!
そして、Window を作る際、もう作成されてるならば作らない、という処理にすることで、単一の Window を確保した。
ViewController, View はそれぞれの AppController が作成し、必要に応じて、これらを切り替えるようにした。

MyAppController から Unity コアへのデータ送信は UnitySendMesssage を使った。
逆に Unity コアから MyAppController へのデータ送信は Unity のプラグイン機能(確かプロライセンスでしか使えない)で
iPhone のネイティブ関数を呼び出す機能を使った。

AndroidiPhone もクセのある処理になってしまいましたが、
動作は確認しております。
が、できるなら使いたくない所。