
[Unity]サンプルプロジェクトをMLAPIの新バージョンへの移行
半年ほど前に「Unityでマルチプレイヤーゲームを作ろう!」と題してMLAPIでゲームを作っていくという放送をしました。
この時にサンプルプロジェクトも用意していたのですが、UnityがMLAPIを正式採用したことによって変更が加えられました。
PackageManagerへの対応や、各種クラス名の変更、RPC周りの変更等々、諸々が入りました。
新しいMLAPIのマニュアルについてはコチラをご覧ください。
という事で…。
サンプルプロジェクトを新しいMLAPIに対応してみました。
変更箇所について
変更対応したのが下記になっています
・クラス名の変更対応
・及びそれに伴い、コンポーネントを手動で差し替え…
・RPC周りの変更
クラス名の変更について
各種クラスの名前が結構変わっていて対応を迫られました。
名前変更があったのはこんな感じでした。
NetworkedBehaviour -> NetworkBehaviour
ServerRPC -> ServerRpc
ClientRPC -> ClientRpc
NetworkedVar -> NetworkVariable
NetworkedVarSettings -> NetworkVariableSettings
NetworkedVarPermission -> NetworkVariablePermission
NetworkingManager -> NetworkManager
NetworkedPrefabs -> NetworkPrefabs
NetworkedObject -> NetworkObject
UnetTransport -> UNetTransport
またそれに伴って、Componentも手で付けなおしました…。
RPC周りの変更
Remote Procedual Callというサーバーやクライアントにある関数を呼び出す機能があるのですが、この仕様が大きく変わりました。
以前のMLAPIでは 下記のような形でInvokeServerRpcという関数を経由してクライアントからサーバーの関数呼び出しを行っていました
void RequestPlayAudio(int idx){
// サーバーにAudioを鳴らしてほしいと伝えます
InvokeServerRpc(PlayAudioRequestOnServer, i);
}
// Clientからサーバーに呼び出されるRPCです。
[ServerRPC(RequireOwnership = true)]
private void PlayAudioRequestOnServer(int idx)
{
// 何か処理する
}
新しいMLAPIではこの呼び出しが変わりまして、普通のメソッドを呼び出すかのような形になっていますが、これでサーバー側に呼び出しリクエストをしています。
void RequestPlayAudio(int idx){
// サーバーにAudioを鳴らしてほしいと伝えます
PlayAudioRequestOnServerRpc(i);
}
// Clientからサーバーに呼び出されるRPCです。
[ServerRpc(RequireOwnership = true)]
private void PlayAudioRequestOnServerRpc(int idx)
{
// 何か処理する
}
一つ制約としてServerRpcと言う末尾で終わるメソッドにしないといけません。これは単純に名前でわかりやすくするためだと思います。
余談(RPCの周りについて)
普通にメソッド呼び出しをしているようにしかしていないのに、何故サーバー側にリクエストされるのでしょうか…?
これはC#のコンパイルされた結果であるIL(中間言語)をポストプロセスで弄って、実行コードを変更しているから何です。
MLAPIのこの辺のコードでは、ILを弄ってRPC指定されたメソッドのテーブルなんかを作成しています。
そして、メソッドをハッシュ値で一致させて、そのハッシュ値を送る事でどのメソッドを呼び出すべきかを決定しています。
最終的には、ここで受け取ったRPCを呼び出ししています。
このようにILポストプロセスで多くの処理を行うようになったのでパフォーマンスも向上したし、普通に呼び出しをするような感じで使えるようになったっという感じみたいですね。