Unity の API とプロジェクト構造のほとんどは、サポートされているすべてのプラットフォームで同等であり、プロジェクトを再ビルドして異なるデバイスで実行できる場合もあります。しかし、ハードウェアやデプロイ方法の根本的な違いにより、プロジェクトの一部がプラットフォーム間でそのまま使用できない場合があります。このページでは、クロスプラットフォームに関する一般的な問題と、その解決策を紹介します。
プラットフォーム間での異なる動作のもっとも良い例は、ハードウェアによって提供される入力方法です。
Input.GetAxis 関数はデスクトッププラットフォームで便利で、キーボードとジョイパッドの入力を統合します。この関数は、タッチスクリーンでの入力に依存するモバイルプラットフォームには適していません。デスクトップ標準のキーボード入力は、入力したテキストをモバイルデバイスに使用するのにのみ適しています。将来、他のプラットフォームへの使用を検討している場合は、入力コードに抽象化のレイヤーを追加することができます。例えば、ドライブゲームを作っているのであれば、独自の入力クラスを作り、Unity の API コールを独自の関数でラップするとよいでしょう。
// -1.0 .. +1.0 (== left .. right) の範囲で値を返します
function Steering() {
return Input.GetAxis("Horizontal");
}
// -1.0 .. +1.0 (== accel .. brake) の範囲で値を返します
function Acceleration() {
return Input.GetAxis("Vertical");
}
var currentGear: int;
// 選択されたギアに一致する整数を返します
function Gears() {
if (Input.GetKeyDown("p"))
currentGear++;
else if (Input.GetKeyDown("l"))
currentGear--;
return currentGear;
}
API コールをクラスにまとめて、1 つのソースファイルに置き、呼び出しの検索や置き換えが容易になります。入力関数は、ゲームでの入力の論理的な意味に合わせて設計してください。これは、ゲームコードの残りの部分を、特定のプラットフォームで使用される特定の入力方法と分けるのに役立ちます。
例えば、上の Gears 関数を変更して、実際の入力がモバイルデバイスのスクリーン上のタッチで行うようにできます。整数を使用して、すべてのプラットフォームで選択されたギアの動きを表すことができます。しかし、プラットフォーム固有の API コールを他のコードに混ぜてしまうと、問題が発生する可能性があります。また、プラットフォーム依存のコンパイルを利用すれば、異なる実装の入力関数を同じソースファイルにまとめることができ、手作業による入れ替えを避けることができます。
Input.GetMouseButtonXXX 関数は、モバイルデバイスで明らかに解釈できるように設計されています。画面は、単純なタッチを左クリックとして報告し、 Input.mousePosition プロパティは、指が画面に触れている限り、タッチの位置を示します。シンプルなマウスインタラクションのゲームは、デスクトップとモバイルプラットフォームの間で、頻繁に透過的に動作します。
変換はしばしば、これよりずっと単純ではありません。例えば、デスクトップゲームでは複数のマウスボタンを使用できます。そして、モバイルゲームでは画面で一度に複数のタッチを検出できます。 このような場合には、入力を論理的な値で表し、それを他のゲームコードで利用しきます。
例えば、モバイルデバイスでズームするためのピンチジェスチャーを、デスクトップでは +/- のキーストロークに置き換えることができます。入力関数は、ズームファクターを指定する float 値を返します。同様に、モバイルでの 2 本指のタップを、デスクトップでの右ボタンクリックに置き換えることができるかもしれません。しかし、入力デバイスのプロパティがゲームに不可欠な要素である場合、別のプラットフォームでそれらを作り変えることはできない場合があります。つまり、ゲームの移植ができなかったり、入力やゲームの大幅な変更が必要になる場合があることを意味します。
これらの入力は、ハンドヘルドデバイスの機動性に由来するもので、デスクトップでは有効な同等のものがないかもしれません。しかし、ユースケースの中には、標準的なゲームコントロールを単純に反映し、簡単に移植できるものもあります。例えば、ドライブゲームでは、モバイルデバイスの傾き (加速度センサーで測定) からステアリング制御を実装することができます。このようなケースでは、入力 API の呼び出しを簡単に変更することができます。つまり、加速度センサーの入力をキーストロークに置き換えることができます。
ただし、異なる入力方法に合わせて入力を再調整したり、ゲームの難易度を変えたりする必要があるかもしれません。デバイスを傾ける動作は、キーを押す動作に比べてゆっくりとした動きになるため、ディスプレイに集中することが難しくなります。そのため、モバイルデバイスでゲームを習得するのが難しくなるかもしれません。そのため、ゲームの速度を遅くしたり、1 レベルあたりの時間を長くしたりすることが適切かもしれません。そのためには、これらの要素を調整するゲームコードの設計が必要になります。
モバイルデバイスは、デスクトップデバイスに比べて利用可能なストレージ、メモリ、CPU の能力が低いため、性能の低いハードウェアでは受け入れられないという理由で、ゲームの移植が難しい場合があります。デスクトップデバイスの限界に挑戦しているのであれば、そのゲームはモバイルプラットフォームへの移植には適していないでしょう。
ビデオ、オーディオ、テクスチャなどは多くのストレージスペースを使用します。ゲームを移植したい場合は、ストレージを効果的に管理する必要があります。ストレージの容量 (ダウンロード時間にも相当することが多い) は、デスクトップマシンでは通常問題になりませんが、モバイルデバイスでは制限されることがあります。モバイルアプリストアでは、提出する製品の最大サイズに制限を設けることがよくあります。これらの問題に対処するためには、ゲーム開発中にいくつかの計画を立てる必要があるかもしれません。
例えば、容量を節約するために、モバイル用に削減したバージョンのアセットを提供する必要があるかもしれません。また、大容量のアセットをアプリケーションの最初のダウンロードに含めるのではなく、必要に応じてダウンロードできるようにゲームを設計する必要があるかもしれません。
Unity は、使用していないオブジェクトから未使用のメモリを回収する処理を自動的に行うため、デスクトップマシンではそれに気づかないかもしれません。しかし、モバイルデバイスではメモリや CPU の能力が低いため、ガベージコレクションが頻繁に発生し、パフォーマンスに影響を与え、ゲーム中に不要な一時停止を発生させます。また、使用可能なメモリ内でゲームが動作したとしても、ガベージコレクションによる一時停止を避けるために、コードを最適化する必要があるかもしれません。
For more information, see the memory management page.
デスクトップマシンでは快適に動作するゲームでも、モバイルデバイスではフレームレートが低下することがあります。これは、ゲームの複雑さがモバイル CPU に負荷を与えているためです。プロジェクトをモバイルプラットフォームに移植する際には、コードの効率性に注意してください。