Unity Multiplayer Networking (MLAPI) 0.1.0 Experimental Release Note (日本語版)

MLAPI 改め Unity Multiplayer Networking v0.1.0 が Experimentalリリースされています.
こっそりリリースノートが公開されていたので,日本語版を書きました.

mp-docs.dl.it.unity3d.com

f:id:xrdnk:20210323210452p:plain

旧MLAPIのLast Release (v12.1.7) との相違点などをまとめました.
昨年12月で発表されたMLAPIの改善予定の部分がいくつか反映されています.

blogs.unity3d.com

New MLAPI v 0.1.0

先日 Unity Multiplayer Networking (MLAPI) の新ドキュメントが公開されました.

xrdnk.hateblo.jp

本日 3/23 にてこっそりと 0.1.0 のリリースノートが公開されています.
v0.1.0 は develop ブランチ または release/0.1.0 ブランチが対応しています.

新 MLAPI から UPM が対応しており,Add Package from git URL もできます.

(2021.04.01 追記)
以下は Unity 2020.3.2f1 以上, Unity 2021.1.0f1 以上でエラーが出るようです
https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi?path=/com.unity.multiplayer.mlapi

こちらを利用してください.
https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi.git?path=/com.unity.multiplayer.mlapi#release/0.1.0

New MLAPI は誤解が持たれていますが,GameObjectベースのMultiplayerソリューションになります.
公式の方もそうTweetしていたり.

New Features (新機能)

リファクタリング

MLAPI の RPC 新規格のリファクタリング,パフォーマンス向上,定型的なコードの大幅な削減,拡張性の実現

Convenience / Performance RPC が統一

今までは MLAPI は Convenience RPC (利便性の高いRPC) と Performance RPC (パフォーマンス重視のRPC) がありましたが,
これが統一されました.これは昨年12月に発表された「RPCの改善」を反映しています.

以下,これまでのConvenience RPC と Performance RPC の例を記しておきます.

Convenience RPC

public class Example : NetworkedBehaviour
{
  private void OnGUI()
  {
      if (GUILayout.Button("SendRandomInt"))
      {
          if (IsServer)
          {
              InvokeClientRpcOnEveryone(MyClientRPC, Random.Range(-50, 50));
          }
          else
          {
              InvokeServerRpc(MyServerRPC, Random.Range(-50, 50));
          }
      }
  }

  [ServerRPC(RequireOwnership = false)]
  private void MyServerRPC(int number)
  {
      Debug.Log("The number received was: " + number);
      Debug.Log("This method ran on the server upon the request of a client");
  }

  [ClientRPC]
  private void MyClientRPC(int number)
  {
      Debug.Log("The number received was: " + number);
      Debug.Log("This method ran on the client upon the request of the server");
  }
}

Performance RPC

void (ulong clientId, Stream readStream) というシグネチャが必要で,
逐一 PooledBitStream,PooledBitWriter,PooledBitReader を using する必要があって正直冗長でした.

private void OnGUI()
{
    if (GUILayout.Button("SendRandomInt"))
    {
        if (IsServer)
        {
            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteInt32Packed(Random.Range(-50, 50));

                    InvokeClientRpcOnEveryonePerformance(MyClientRPC, stream);
                }
            }
        }
        else
        {
            using (PooledBitStream stream = PooledBitStream.Get())
            {
                using (PooledBitWriter writer = PooledBitWriter.Get(stream))
                {
                    writer.WriteInt32Packed(Random.Range(-50, 50));

                    InvokeServerRpcPerformance(MyServerRPC, stream);
                }
            }
        }
    }
}

[ServerRPC]
private void MyServerRPC(ulong clientId, Stream stream)
{
    using (PooledBitReader reader = PooledBitReader.Get(stream))
    {
        int number = reader.ReadInt32Packed();
        Debug.Log("The number received was: " + number);
        Debug.Log("This method ran on the server upon the request of a client");
    }
}

[ClientRPC]
private void MyClientRPC(ulong clientId, Stream stream)
{
    using (PooledBitReader reader = PooledBitReader.Get(stream))
    {
        int number = reader.ReadInt32Packed();
        Debug.Log("The number received was: " + number);
        Debug.Log("This method ran on the client upon the request of the server");
    }
}

IBitWritable の置換

IBitWritableINetworkSerializable に置き換えられます.

NetworkSerializer の追加

NetworkSerializer が追加されます.これまで NetworkVar は Serialization が未対応で,SyncVar の方が対応されてました.
後述しますが,新MLAPI では SyncVar が廃止されるので,NetworkVariable (NetworkVar の後継) が Serialization に対応するようにした感じでしょうか.

Network Update Loop インフラの実装|MonoBehaviourライフサイクルの前後に処理を走らせることが可能に

標準的なMonoBehaviourイベントサイクルの外で,Netcode システムのアップデート(RPCキューや Transport など)を支援する Network Update Loopインフラが追加されました.

言葉だとわかりにくいので,以下の図を見てください.
Network Update Loop を利用すれば,MonoBehaviourライフサイクルの前後に処理を走らせることが出来るようになります.

https://camo.githubusercontent.com/043459dcadb043db09d205f9ba85031923bc33a752045197c00df92ff1f838ba/68747470733a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f7376672f744c66314c2d43733442787041746f346d5f41776c42734b52566a55493039444974506630696c557a576278346b6a3562626e39316a6e567476376939374f4971445a714b5a5750494a43515a4d512d6354373468425a43634d5050444255625743584f704d44525045423852364f6f394c4d5351664c3150374b315a50613435676d477a623939452d565f47464a6e717a36484c314f597a4757776b5836693137736a4c377555744b626b6f2d5a696675795f6474774168635f645a4d4c566d3375666c526842347351584d5a716866454b504a393238437536536c7966686e5038667335476248746934714f5656336437506158796351536674314e504f51307449526153464b46746f754b46717765413039436e6f394b7964716532736e5f4e327a6b47396355634f514c354d307069533670447154665679365041337831657054374f743657756f7375704a4d48746171714555515f706439506373536e724f41634456766a63514630625275316d7763547649676f425643516f5a32462d735174507467427568626856654e653762387775586a6168464d504f42326937306233412d6f6d4c776762697a35706e557371733053657734323330494e4e4b59797938512d6c67763352465f46636a756e383672586e376565376a7777637736596e386b385668727135713948766c7a51435f7936365a44495a5f5f7563514a726b59794431516f795f52494c6e57754b7068346d5045304a37504c7644526c534a626f326f6968563573784248444b47624a5f33764d4b51357534677a4c676d474c654c414573626e587247646a53764f4b70467346485261434d41766165424f5f444b36626c494f507132585f43786b35583164794e6b302d39506c6d43534d35586f6859794a4a4d6d76305f724f4339375a79364f674965432d694b7a6275627732663043314a307a6148507131576237694d50754a513131366d68584450534735576543586961424d415772623053655061584774506e4e794d3231716a4c53476568737833736b70353162336f6e554a506234547a38616d686235484d54534268694774534170424e475f4d5a6f4c47702d61326767616b664b6c6f6c393545503646744630373049473054705362597470387558494934524543393965706c326b795763795364635265553249593850454670425a626a766639577055553151364d7661352d61535477636476684c76583166636777685a592d3272427a47376f4e497574575a55375f32746d3738636f69554d7648556f446d65756237746f425675675f4674704c56665a5049596e526635436b3532715a50387255354658717969484b53647449592d4968376167347854324a70436a4f713854467861796b6d342d3350454c4f6534734c6d723368683770795951384b4779665239664941766d4f5952644461757a4d705f4167303071574f74514d616d513762537a4c5956417647466165734a4f6c42394477377250564c58714c45706766746d2d45477170464a7576374638553742443452516a4f366c366a4547306a446b376f4857735752616374454f515a4d42616c7566654e2d3339386d67547a4a65727a584a715f4258386b37667a61725348523955713775426a536761486833377970583169306e3278397756594965436b5932756a6f6f3350715a4b694d4c70777a474639437279326130595f702d5952723676457279305851365a66754e4346316445553551393137504a745246473659537a3652765250692d57697a4c3065635f4f34617067464c364f6a495353757850647541337268752d52444179647767775a4a396b6f37454d715544553969316a7937746a4a7472546b7867344f7775716b55464159615a42504863623135686e74673352784b4d5341704b495350586f6434416f6f5f425a633876414b536c71616d634c78544a55507556707672496159767170684f717a77626142556c6c616369316e43494b725637546f59496c6c34344c4345482d74646e6372727574745f565478424738717957665759786133716739536a756c304e6a526b497470416d4343534a695054456a62732d5955526c574c3064485154544453644331496f7639494c36745645593578535278356c38327547574d65424e3334494f416d656b554a4175716f7244344956554d76762d72416874476f5843625a544d43497a6b6648693849627955595457366c6f6c6779476c493878336b4e74706b77785f3350486c5a6a6e3769355966735a4b79355949755130714e33384c6a6b387a317865576a4a77544c4c5a6d4b7771546c386b527949684566364f6878594b61465a536b3636736631334f7647366f7355496764592d337a4e5f6a4741757733777079546c637a58765545725f372d69385f4943384c794e564e483273444c4c5a7170726f5f5148334b38474d71505a414c6d5457776f526a547434307a746747725932594f354f59466137587679486551565933703171615a5839535a626256436871704e587767497041614d5a6b4c736274346336316f3150795a5a5a6a68425a417230504d3572737a78544242686239494967656262512d78494b447a70386b74306c634c324d7a43366b657445435066493266714d563858445768636c526470697a4e77346a563574774a4f434b49417048574d47312d65424e5739766e3766516a3265646c3678514e494d727754572d6d2d65465543696c6b43726336734456432d756b6d516d374656597569725733496669684a5566385644614d51715063644d694c45774f79372d6851503344744336486563324b30787843644c53786e396745513150657a4c6c7054497657636b4e5857773331524a4e3067643064515343445647786175633069544f6767416777634f3364363370704f446c346a794b586b517577673244754139524b746d5171566d794973636141635441627276446859733834537071374d5746567a4c323775357572673266553278637649684953566d3430

https://camo.githubusercontent.com/97f447377490cbbaec4404bfc301e831c369795de0824936a18e188de6b99fb4/68747470733a2f2f7777772e706c616e74756d6c2e636f6d2f706c616e74756d6c2f7376672f784c50544a79386d353774644c5f4848376e576e794f6365324b4f6d39414236584d544973484b516b64526645644a2d556c533551786a6b6931364459563871556b797a667874647841785858683030322d6d5a4c794f4b4b3257354d5368386678726d375f347675796b72753375574149394738587779754f5a41324d564939502d304259767846534f6238427535574d526e43794d346b4b6a31305a623471706949315a7034686e4751615876316c64456e63475355626b3336654748566f787837466b6f4950796436526336446a754837655a52423268614946306671536356415932494f3957566665554964314c375f3163617533766d37475f47324176425732497271446951326e6c64706b474e67676a2d6c4f6672384549345675467169504c69734f44776b7851666b7058435269796d4b454c30667451617a4c763251706a2d487144426e786f4c696f4c4d73457634633166346b4561674e43666d6f4c42554c59314d68506361626b475158554571614e57367748594f414a476c7a5852417936306331756f6e4f4973434333497364654a396a6235507759344b54382d72386f69656944484e337737557a477448486f647a33443157576e7437697159662d52326b6a4d5466444d584562613550505f596c4973624c684a69654834717473577a376966737273635a624c336c73616a646e703845614c6f6b4f6a316b785533516b376b7a64745045544d4a56695f5965424d565a725772484f6b5f4d4b36445179686f4a7373704e726270614a6e46487a4867694e337a6a7a6f7648426a76385f374e724f46522d4965497a6d4e

RPCキューやTransportなどのNetcodeシステムを、標準的なMonoBehaviourのイベントサイクルの外でアップデートする必要があることがよくあったので,
Network Update Loop を利用すれば,それが実現できるわけです.後程利用方法例を記事にする予定です.

(2021.04.01 追記)

実装方法追記.

xrdnk.hateblo.jp

RpcBatcher|バッチ処理の追加

RpcBatcher が追加されます.同じクライアントに送られた連続したRPCリクエストを処理するためのメッセージのバッチ処理機能です. RpcBatcher は RpcQueueProcessing からのリクエストに基づいて,バッチサイズのしきい値で,または即時にバッチを送信します.

NetworkObject は 1オブジェクトに 1つ

NetworkObject に DisallowMultipleComponent 属性が追加されたため,1オブジェクトに1NetworkObjectが保証されるようになりました.

Unity 2020.2 以降の Profiler に統合

MLAPI が Unity 2020.2 以降の Profiler に統合されました.

MLAPI Community Contributions リポジトリの公開|MLAPI の拡張機能が利用可能

MLAPI Community Contributions リポジトリが公開されました.ここでは,MLAPI の様々な拡張機能が追加されています.

旧MLAPI にはなかった,NetworkManagerHud.cs (Mirror や UNET にはあった,すぐに Host,Client,Server ボタン押せる奴) があったり LagCompensation(後述),NetworkObjectPool などがあり,こちらも MLAPI ライブラリと一緒に使う方がよいと思います.

f:id:xrdnk:20210321180334p:plain

NetworkManagerHud は上の画像のことです.これですぐに MLAPI のサンプルを試したい時に View 側を作る必要が省くことができます.

Changes (変更点)

MLAPI が UPM でインストール可能に

最初の方でも説明しましたが Add Package from git URL ができるようになりました.最高.

(2021.04.01 追記)
以下は Unity 2020.3.2f1 以上, Unity 2021.1.0f1 以上でエラーが出るようです
https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi?path=/com.unity.multiplayer.mlapi

こちらを利用してください.
https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi.git?path=/com.unity.multiplayer.mlapi#release/0.1.0

NetworkVariable (旧 NetworkVariable) の機能追加と SyncVar の廃止

NetworkVariable(以前の名称はNetworkVar)に機能と使いやすさを追加しました.
このアップデートにより,オプションが強化されたため,SyncedVarsの必要性が完全になくなり,廃止されています.

NetworkAnimator の再実装

NetworkAnimator は実は少し欠陥部分があったのですが,それが修正されたようです.
こはちょっと要確認かな….

Refactored API names (API の名前変更)

旧MLAPI の命名が新MLAPIでは以下のように変更されました.
名前がNetwork~で始まるようになったので,個人的にはとっつきやすくなったと感じます.

旧MLAPI 新MLAPI (0.1.0)
NetworkingManager NetworkManager
NetworkedObject NetworkObject
NetworkedBehaviour NetworkBehaviour
NetworkedClient NetworkClient
NetworkedPrefab NetworkPrefab
NetworkedVar NetworkVariable
NetworkedTransform NetworkTransform
NetworkedAnimator NetworkAnimator
NetworkedAnimatorEditor NetworkAnimatorEditor
NetworkedNavMeshAgent NetworkNavMeshAgent
SpawnManager NetworkSpawnManager
BitStream NetworkBuffer
BitReader NetworkReader
BitWriter NetworkWriter
NetEventType NetworkEventType
ChannelType NetworkDelivery
Channel NetworkChannel
Transport NetworkTransport
NetworkedDictionary NetworkDictionary
NetworkedList NetworkList
NetworkedSet NetworkSet
MLAPIConstants NetworkConstants

NetworkChannel の string から byte 表現に

C# スクリプトリファクタリング

文字列補間,var や nameof の利用,明示的なアクセス修飾子の利用など.

Removed features (なくなった機能)

SyncVar の廃止

代わりに NetworkVariable を利用すること.

NetworkVariable に対応している型は以下の通り

  • C# プリミティブ型

bool, char, sbyte, byte, short, ushort, int, uint, long, ulong, float, double, string

  • Unity プリミティブ型

Color, Color32, Vector2, Vector3, Vector4, Quaternion, Ray, Ray2D

独自の型を作りたい場合は,INetworkSerializable を実装すれば出来る模様ではあります.
今後試してみます.

Lag Compensation が MLAPI Commnuty Contributions リポジトリへ移行

ラグ補間システムを利用する場合は MLAPI Community Contributions リポジトリも利用すること.

MLAPI から暗号化機能が削除

これまで所々にあった暗号化機能がなくなりました.
暗号化機能は将来のリリースで開発される可能性はあるとのこと.

NetworkManager を見ると Cryptography の機能のところがなくなってますね.

f:id:xrdnk:20210321183350p:plain

MLAPI Profiler が Unity 2020.2 以降からは削除

Unity 2020.2 の Profiler と統合されています.

Convenience / Perfomance API の削除

新規格のRPC API に統一されています.

MLAPI Installer の削除

UPM対応になったので不要になった感じでしょう.私も正直使ってませんでした.

Fixes (修正点)

特定条件下で RPC の送受信が出来ない問題の修正

NetworkManager で loopback のフラグが設定されていない時に RPC の送受信ができない問題があったようです.

MLAPI Profiler の修正

プロファイラーのデータが正しく集計・描画されず,フレームごとにリセットされずに無限に増加してしまう問題の修正.

PlayModeでシーントランザクションに問題があったのを修正

Server モードで実行する際の NetworkList,NetworkDictionary のシリアル化の問題の修正

数値精度の問題修正

bool の修正

ShutDown() の修正

NetworkManager.Singleton = nullにする前にShutdown()を呼び出すと,NetworkManager.OnDestroy()でnullになってしまう問題を修正.

NetworkSceneManager の問題修正

NetworkSceneManagerで,HostまたはServerがNetworkSceneManager.SwitchSceneメソッドを呼び出したときに,
Client 側で "Soft sync" 例外の後にヌルポ例外が発生する問題が修正.

この修正により,シーンからシーンへの移行の安定性が向上します.

Known Issues (既知の問題)

NetworkNavMeshAgent の同期問題

以下の設定は同期されない.
Mesh Data,Agent Size,Steering,Obstacle Avoidance,Path Finding Settings.

また,destinationとvelocityの同期のみで目的地までの経路の同期は行いません.

RPC Suffix 問題

ClientRpc または ServerRpc の Suffix を持つメソッドで,[ClientRPC] または [ServerRPC] のマークを付けてない場合はコンパイルエラーになる.
こちらの方は正しい気がするような… Mirror もそうなっていた気がする.

NetworkAnimator の問題

Animator Override がサポートされていない.
Trigger は機能してない.(なので自分でRPCを作る必要があります)

NetworkVariable の問題

NetworkDictionary の List および Set は、reliableSequenced チャネルを使用する必要があります.

NetworkObjects の注意点

NetworkObjects はおそらく,NetworkObject の子孫を持つ NetworkObject のことだと解釈しています.

NetworkObjects はサポートされていますが,ネストされた子ネットワークオブジェクトを持つプレハブを生成する際には
それらに対して手動でスポーンを呼び出す必要があります.

NetworkTransform の問題

  • 複製されたオブジェクトには jitter が発生する可能性がある
  • Owner は常にオブジェクトの位置について権限を持つ
  • Scale は同期されない.

Connection Approval は ホストクライントでは呼ばれない

NamedMessages の問題

常に NetworkBuffer を利用する必要がある.

NetworkManager の機能の制限

接続管理には制限があり,IsServer,IsClient,IsConnectedClient を利用して適切にMLAPI接続が出来ているか確認してください.
NetworkManager がアタッチされているオブジェクトに NetworkObject を割り当てると soft sync エラー問題が発生するので避けること.

終わりに

4/7 あたりに出てくる予定の MLAPI 公式サンプルプロジェクトの「Boss Room」は New MLAPI v 0.1.0 の内容で公開する予定です.