SyncedVar を用いて変数の同期を行います。
前回記事
こちらの続きになります。
SyncedVar
同期された変数という名の通りではありますが、 NetworkBehaviour継承クラスのフィールドを同期させる方法です。
MirrorやUNETのSyncVarとネーミングが似通っていますし、機能も同じです。
準備
Cボタンを押下したらプレイヤーの目の前にキューブを表示させるようにしてみます。
適当に目の前にSphereを置きます。
利用
所々確認しつつ、順を追って説明していきます。
MLAPI_InvetorBridge.cs のスクリプトを以下のように改変します。
using UnityEngine; using Invector.vCharacterController; using MLAPI; public class MLAPI_InvectorBridge : NetworkedBehaviour { [SerializeField] private GameObject _playerCamera; [SerializeField] private GameObject _sphere; private GameObject playerCam; private vThirdPersonInput vTPI; private bool isCubeVisible = false; void Start() { if (!IsLocalPlayer) { GetComponent<vThirdPersonInput>().enabled = false; } else { playerCam = Instantiate(_playerCamera); playerCam.name = this.gameObject.name + "camera"; vTPI = GetComponent<vThirdPersonInput>(); InitializeTpCamera(); } } private void Update() { isCubeVisible = Input.GetKey(KeyCode.C); _sphere.SetActive(isCubeVisible); } public virtual void InitializeTpCamera() { var tpCamera = playerCam.GetComponent<vThirdPersonCamera>(); if (tpCamera) { tpCamera.SetMainTarget(this.transform); tpCamera.Init(); } vTPI.tpCamera = tpCamera; } }
_sphere には準備の際に作成したSphereをあてはめてください。 この状態で ParrelSync を利用して確認します。
左側の方でCボタンを押下しましたが、Cubeが2つ出た上、右側の方では同期されていません。 操作権限を定めていないこと、isCubeVisible の変数が同期されていないことが理由です。
前回の記事では説明していませんでしたが、MLAPI_InvetorBridge.cs の Start メソッドの方で、 isLocalPlayer という NetworkedBehaviour のプロパティがあります。 isLocalPlayer を利用すれば、自分のクライアントかどうか判定できます。
Update メソッドを以下のように変えます。
private void Update() { if (IsLocalPlayer) { isCubeVisible = Input.GetKey(KeyCode.C); } _sphere.SetActive(isCubeVisible); }
操作権限を加えたいのは同期変数の変更処理部分なので、この部分のみ isLocalPlayer 判定にします。 (_sphere.SetActive(isCubeVisible) まで入れてしまうと相手側に表示されなくなってしまいます。)
次に、isCubeVisibleにSyncedVar属性を加えます。この時、MLAPI.NetworkedVar の名前空間を宣言する必要があります。
using MLAPI.NetworkedVar; .... [SyncedVar] private bool isCubeVisible = false;
以上で前準備を終えました。 左側でSphereの表示・非表示制御を行い、それが右側でも同期されているのか試してみます。
無事に同期されているのを確認できました。 最終的なコードは以下のようになります。
using UnityEngine; using Invector.vCharacterController; using MLAPI; using MLAPI.NetworkedVar; public class MLAPI_InvectorBridge : NetworkedBehaviour { [SerializeField] private GameObject _playerCamera; [SerializeField] private GameObject _sphere; private GameObject playerCam; private vThirdPersonInput vTPI; [SyncedVar] private bool isCubeVisible = false; void Start() { if (!IsLocalPlayer) { GetComponent<vThirdPersonInput>().enabled = false; } else { playerCam = Instantiate(_playerCamera); playerCam.name = this.gameObject.name + "camera"; vTPI = GetComponent<vThirdPersonInput>(); InitializeTpCamera(); } } private void Update() { if (IsLocalPlayer) { isCubeVisible = Input.GetKey(KeyCode.C); } _sphere.SetActive(isCubeVisible); } public virtual void InitializeTpCamera() { var tpCamera = playerCam.GetComponent<vThirdPersonCamera>(); if (tpCamera) { tpCamera.SetMainTarget(this.transform); tpCamera.Init(); } vTPI.tpCamera = tpCamera; } }