マイネット Advent Calendar 2016二日目の記事です。
プレイしているデバイスとは別の端末で、マップなんか表示できたら面白そうだと思い、
Unityのネットワーク機能を利用して実装してみました。
#発端
######(読み飛ばして結構です)
メタルギアソリッド5にiDROIDという仮想の端末が登場します。
ゲーム内で主人公はこの端末を操作し、マップをみたり、物資や砲撃の支援を要請できます。
このiDROIDですが、なんと専用アプリをインストールすることで、AndroidやiOSを搭載した実世界のデバイスをiDROIDとして使用できるのです!!!
とてもおもしろそうです。
しかし、ページには無情な一文が
※Xbox 360® および PC(Steam®)は、サポートしていません。
OMG!! 神よ、Steamerが何をしたというのですか!!
少し話がそれました。
時代を少し遡り ゼルダの伝説 風のタクトでもチンクルシーバーというものがありました。
こちらはゲームキューブにゲームボーイアドバンスを接続することによって、アドバンス側でマップの表示やリンクのサポートが行えるというものでした。
これらのような機能をUnityで実装してみたいとおもいました。
#実装
今回はキャラクターが自由に歩き回ることができるシーンに、別の端末でアクセスした際、マップ(というかかなり引き気味の俯瞰カメラ)として機能するようにします。
メインとなる端末と、Mapを表示する端末はUnityのネットワーク機能を用いて通信させます。
Unityのネットワーク機能に関する知識が皆無だったので、テラシュールブログやUnityの公式マニュアルを参考にしました。
Unityのシーンの組み方や、Unityのネットワーク機能等の基本の説明は省きますので上記のサイトを参照してください。
とても参考になります。
メインのキャラクターを操作する側をホストとする前提で組んでいきます。
まずはUnityのネットワーク機能を利用するために、Network ManagerとNetworkManagerHUDをシーンに追加します。
次に別端末用のカメラをシーンに追加します。マップっぽくするためにこのカメラはシーンを高い位置から見下ろします。
次に、二つの端末で位地を同期すべきオブジェクトにNetworkIdentityとNetworkTransformを追加します。
今回はメインのキャラクターと、マップとなるカメラにも一応追加します。
このままでは両方の端末でプレイヤーが操作を受け付けてしまいます、テラシュールブログさんの記事のコードを参考に、メインのキャラクター用のカメラと、操作を処理するスクリプトをホスト側でのみ有効になるようにします。
using UnityEngine;
using UnityEngine.Networking;
public class DisableNetworkUnlocalplayerBehaviour: NetworkBehaviour {
[SerializeField]
Behaviour[] behaviours;
void Start() {
if(!isServer) {
foreach(var behaviour in behaviours) {
behaviour.enabled = false;
}
}
}
}
上記のスクリプトに、インスペクターからキャラクターを操作するスクリプトと、カメラを追加します。
Mapとなる端末側には、Map用カメラとその操作がクライアント側でのみ有効になるように、先ほどと逆の動作をするスクリプトを追加します。
using UnityEngine;
using UnityEngine.Networking;
public class DisableOnServer : NetworkBehaviour {
[SerializeField]
Behaviour[] behaviours;
void Start() {
if(isServer) {
foreach(var behaviour in behaviours) {
behaviour.enabled = false;
}
}
}
}
こちらも、操作するスクリプトとMap用のカメラをアタッチします。
あとはプロジェクトをビルドし、メインとなる側はホストとして起動し、Map側はクライアントとして接続してます。
動きを見せられないのがアレですが、ネットワークを利用し別の端末でMap(というか引いた俯瞰カメラ)を表示することができました。
これでもう一つの端末をマップとして使用したり、キャラクターを操作するプレイヤーをもう一つの端末を利用するプレイヤーがナビゲーターとしてサポートしたり等の遊び方を実現できそうです。