Network Update Loop で MonoBehaviour ライフサイクル前後に処理を差し込む【MLAPI】
MLAPI v0.1.0 から Network Update Loop という MonoBehaviour のライフサイクルの前後に処理を差し込める機能が追加されました.
Network Update Loop
RPC queue,Transport の IO 関連の処理を MonoBehaviour のライフサイクル外で処理を走らせたい場合があり, それを解決するための MLAPI 独自のライフサイクルイベントを構築するインフラシステムです.
Player Loop System
こう言ったシステムを作る時に Player Loop System を利用しているようです.
ちなみに Player Loop System は VContainer でも利用されていますね.
つまり,Player Loop System を理解していれば,MLAPI の NetworkUpdateLoop の実装方法は, VContainer に似通った形になるのは予想がつきます.
Update Stage
以下の画像の通りに呼ばれます.
もう少しシーケンスの中身を深く追いたい場合はこちらのサイトをご覧ください.
基本的に Network Update Loop は MonoBehaviour ライフサイクルより前に呼ばれるようです. e.g. NetworkUpdateLoop.FixedUpdate → MonoBehaviour.FixedUpdate,NetworkUpdateLoop.Update → MonoBehaviour.Update
椿さんのこちらの記事を参考に各 Update Stage に盛り込む処理をば.
Update Stage | 内容 |
---|---|
Initialization | 「時間」のアップデートやステートの同期など |
EarlyUpdate | 「入力」の更新 |
FixedUpdate | 物理演算系 |
PreUpdate | 物理演算の反映・マウス入力云々 |
Update | アップデート処理 |
PreLateUpdate | アニメーションの更新 |
PostLateUpdate | 布の更新とかレンダリング |
How To Use
サンプルスクリプトを載せます.
using MLAPI; using UnityEngine; namespace MLAPIPractice { // Network Update Loop を利用する場合は INetworkUpdateSystem を実装する public class NetworkUpdateSystemTest : NetworkBehaviour, INetworkUpdateSystem { private void OnEnable() { // Update Stages の順番は以下の通り. // 追加したい Stage を指定する時は this.RegisterNetworkUpdate() を最初に指定する this.RegisterNetworkUpdate(NetworkUpdateStage.Initialization); // ちなみに上のコードはこちらと同じ // NetworkUpdateLoop.RegisterNetworkUpdate(this, NetworkUpdateStage.Initialization); this.RegisterNetworkUpdate(NetworkUpdateStage.EarlyUpdate); this.RegisterNetworkUpdate(NetworkUpdateStage.FixedUpdate); this.RegisterNetworkUpdate(NetworkUpdateStage.PreUpdate); this.RegisterNetworkUpdate(NetworkUpdateStage.Update); // 引数なしでも同様 this.RegisterNetworkUpdate(NetworkUpdateStage.PreLateUpdate); this.RegisterNetworkUpdate(NetworkUpdateStage.PostLateUpdate); // 全ての Update States を指定したい場合は以下で宣言してもよい // this.RegisterAllNetworkUpdates(); // こちらでもよい // NetworkUpdateLoop.RegisterAllNetworkUpdates(this); } /// <summary> /// RegisterNetworkUpdate に指定した Stages が Resolve される /// </summary> /// <param name="updateStage">updateStage</param> public void NetworkUpdate(NetworkUpdateStage updateStage) { Debug.Log($"{nameof(NetworkUpdateSystemTest)}.{nameof(NetworkUpdate)}({updateStage})"); } private void Update() { Debug.Log($"{nameof(NetworkUpdateSystemTest)}.{nameof(Update)}()"); } private void FixedUpdate() { Debug.Log($"{nameof(NetworkUpdateSystemTest)}.{nameof(FixedUpdate)}()"); } private void LateUpdate() { Debug.Log($"{nameof(NetworkUpdateSystemTest)}.{nameof(LateUpdate)}()"); } private void OnDisable() { // Dispose する時は以下のように宣言する this.UnregisterAllNetworkUpdates(); // こちらでもよい // NetworkUpdateLoop.UnregisterAllNetworkUpdates(this); } } }
INetworkUpdateSystem を実装し,MonoBehaviour の前後に差し込みたい処理を NetworkUpdate の中に書きます. どのタイミングで差し込みたいかは,初期化処理段階で Register し,使わなくなったら Unregister する流れになります. NetworkUpdateStage を Register することで NetworkUpdate メソッドに Inject されます.
Register の書き方は二通りあり,以下のようになります.下の方だとRiderちゃんに上の方がイイヨ~って下線がつくけど.
// 追加したい Stage を指定する時は this.RegisterNetworkUpdate() を最初に指定する this.RegisterNetworkUpdate(NetworkUpdateStage.Initialization); // ちなみに上のコードはこちらと同じ // NetworkUpdateLoop.RegisterNetworkUpdate(this, NetworkUpdateStage.Initialization);
引数なしの場合は,Updateが登録されるようです. Unregister する時は Register を Unregister に変えるだけでOK.
まあ少し軽く動作確認しますか.
使いどころはしっかり考えて実装する感じになりそうです.