Android プラットフォーム上で動作するネイティブ アプリは Android インターフェイスを直接呼び出すため、早い者勝ちの利点を享受できますが、Unity を使用して開発された Android アプリは二級市民のようなものであり、使用するのがはるかに面倒です。 WiFi、Bluetooth などの Android のネイティブ機能、特にいくつかの高度な機能は Unity で完全にはカバーされておらず、Unity で直接開発するだけでは十分ではありません。さらに、クロスプラットフォーム開発のニーズに適応するためには、 Unity のエンジン アーキテクチャ設計は、より複雑かつ柔軟です。Unity エンジンに基づいた開発アプリ アプリケーションは、独立した VM (仮想マシン、仮想マシン) で実行されます ( IL2CPP バックエンドでコンパイルされたアプリケーションは、実行時に仮想マシンのサポートが必要です)。これは、アプリ アプリケーションと Android ネイティブ システム コード間の相互作用に困難をもたらします。実際のアプリケーション開発では、Unity ベースのアプリ アプリケーションとその基盤となる Android プラットフォームとの間でインタラクションが必要になることがよくありますが、このシリーズでは主に Unity エンジンと Android プラットフォームの間のインタラクティブな通信について研究します。
(1) AndroidとUnity間の通信原理
Unity エンジンの最大の利点と機能は、ワンタイムの制作とマルチエンド展開であり、マルチプラットフォーム ゲームの開発とメンテナンスのコストを大幅に削減します。Unity エンジンが強力なクロスプラットフォーム機能を実現するための基盤は、Mono/ IL2CPP: Mono/IL2CPP は、Unity エンジンのクロスプラットフォーム機能であり、プラットフォームのコアおよび基盤です。
2001年に電気通信標準化団体ECMAが、特定の言語に依存しないクロスアーキテクチャ実行環境CLI(Common Language Infrastructure)の標準仕様を策定し、この仕様で定義された高級言語を使用して開発する限り、アプリケーションは準拠することになります。つまり、異なるコンピュータ アーキテクチャ上でのクロスプラットフォーム動作を保証できます。これに基づいて、Microsoft は標準に従って .NET Framework Common Language Runtime (CLR) を実装しました。したがって、CLR は CLI の実装です。.NET Framework は CLR に基づいて実行されるフレームワークです。C#、VB.NET をサポートします。 、C++、Python などの言語に対応していますが、.NET Framework と Windows の間には深い関係があるため、.NET Framework 自体はクロスプラットフォームではありません。
Mono は、Xamarin が主導するもう 1 つの CLI 実装であり、組み込みの C# 言語コンパイラー、CLR ランタイム、およびさまざまな基本クラス ライブラリを使用して、Windows、Linux、FreeBSD、Android、iOS などのさまざまなプラットフォームでアプリケーションを実行できるようにします。 Android または iOS アプリケーションは、Mono を通じて C# 言語を使用して作成できます。CLI 仕様では、高級言語は直接マシン バイトコードにコンパイルされるのではなく、高級言語とマシン バイトコードの間の特定の基礎となる言語である中間言語 (Intermediate Language、IL) にコンパイルされます。ハードウェアに依存しない言語の場合、IL は、実際に実行する必要があるときに Mono VM にロードされます [Unity は、C#、Unity Script、Boo の 3 つのスクリプト開発言語をサポートしており、すべての高水準言語は次のようにコンパイルされます) IL中間言語。] を実行すると、VM はそれを動的にマシンコードにコンパイルして実行します (Just In Time、JIT コンパイル)。その実行プロセスを図 1(a) に示します。
IL2CPP は、最終的には AOT 方式を使用して各プラットフォームのネイティブ マシン コードに直接コンパイルされますが、IL 中間言語のメカニズムを継承しており、上位層の言語にはほとんど影響を与えません ( C++ は静的言語であり、 AOT 方式と JIT 動的言語の一部の機能は利用できなくなります) が、図 1(b) に示すように、メモリ管理やその他の作業のために VM の助けも必要になります。Android ネイティブ アプリケーションは Java 言語で書かれており、Java 言語はまずバイトコード IL 中間言語にコンパイルされ、次に Android 上の dalvik/art 仮想マシンに依存して解釈と実行が行われます。したがって、図 2 に示すように、Unity エンジンと Android ネイティブ コード間の対話型通信は、実際には 2 つの VM 間の通信になります。Unity コードと Android ネイティブ コードは異なる VM で実行されますが、両方とも同じプロセス内にあるため、データを共有できます。
実行レベルでは、UnityEngine は AndroidJavaObject、AndroidJavaClass、および AndroidJavaProxy クラスをカプセル化します。これらのクラスを通じて、Android 側の静的クラスまたは動的オブジェクトを取得できるため、対応するメソッドを実行できます。Android は mainActivity を通じて C# コードと通信します。 Unity アプリケーションの [このセクションで説明する Unity と Android 間の対話型通信は、基本的に C# コードと Java コード、JAR パッケージ、AAR パッケージ、および SO パッケージ間の相互呼び出しを指しますが、慣例的には Unity エンジン間の通信として説明されます。 Android オペレーティング システム ソフトウェア。]。
アクティビティは、Android アプリケーションの最も基本的かつ重要なコンポーネントの 1 つです。その機能は、Web のページや winform のフォームに似ています。したがって、アクティブなアクティビティのみが入力に応答できます。そのため、Android コードは最初に com を渡す必要があります。 unity3d. player.UnityPlayer パッケージの下の currentActivity はアクティブなアクティビティを取得し、それを使用して Unity コードと通信します。
(2) Unity が Java コードを直接呼び出す
Unity2018 以降のバージョンでは、Android 側でのコンパイル、ビルド、パッケージ化に一律に Gradle を使用し、Android Studio もコンパイル、ビルド、パッケージ化に Gradle を使用します。つまり、これらはすべて同じコンパイルおよびビルド ツール、つまり Java コードとC# コードは Unity で Android 側に正しくコンパイルされ、Unity で Java および C# 言語を直接使用するための基礎を築きます。
Java データ構造のマッピングを容易にするために、いくつかのカプセル化されたクラスが UnityEngine クラスに組み込まれています。最も重要なクラスは、AndroidJavaClass、AndroidJavaObject、および AndroidJavaProxy です。これらのクラスは、Java 側と C# 側の間の相互呼び出しの基礎です。 。AndroidJavaClass は Unity の java.lang.Class クラスの表現です。主にクラス構造の反映、クラスの静的属性の取得、またはクラスの静的メソッドの呼び出しに使用されます。そのパブリック メソッドを表 1 に示します。
パブリックメソッド | 呼び出し元のオブジェクト/プロパティ タイプ | 一般的なメソッド | 説明する |
---|---|---|---|
電話 | 非静的 | 電話 | オブジェクトの非静的メソッドを呼び出す |
コールスタティック | 静的 | コールスタティック | クラスの静的メソッドを呼び出す |
得る | 非静的 | 得る | オブジェクトの非静的プロパティを取得する |
GetStatic | 静的 | GetStatic | クラスの静的プロパティを取得する |
セット | 非静的 | セット | オブジェクトの非静的プロパティを設定する |
SetStatic | 静的 | SetStatic | クラスの静的プロパティを設定する |
GetRawClass | - | GetRawClass | JNI で使用するネイティブ Java 型へのポインタを取得します。 |
GetRawObject | - | GetRawObject | JNI で使用するネイティブ Java オブジェクトへのポインタを取得します。 |
廃棄 | - | - | IDisposable インターフェイス コールバック |
AndroidJavaObject は Unity の java.lang.Object クラスの式であり、java.lang.Object クラスは Java のすべてのクラスの基本クラスであるため、すべての Java オブジェクトを受け入れることができます。そのパブリック メソッドを表 2 に示します。
パブリックメソッド | 呼び出し元のオブジェクト/プロパティ タイプ | 一般的なメソッド | 説明する |
---|---|---|---|
電話 | 非静的 | 電話 | オブジェクトの非静的メソッドを呼び出す |
コールスタティック | 静的 | コールスタティック | クラスの静的メソッドを呼び出す |
非静的になる | 得る | オブジェクトの非静的プロパティを取得する | |
GetStatic | 静的 | GetStatic | クラスの静的プロパティを取得する |
セット | 非静的 | セット | オブジェクトの非静的プロパティを設定する |
SetStatic | 静的 | SetStatic | クラスの静的プロパティを設定する |
GetRawClass | - | GetRawClass | JNI で使用するネイティブ Java 型へのポインタを取得します。 |
GetRawObject | - | GetRawObject | JNI で使用するネイティブ Java オブジェクトへのポインタを取得します。 |
廃棄 | - | - | IDisposable インターフェイス コールバック |