SyncedVar を用いた変数同期【MLAPI】

SyncedVar を用いて変数の同期を行います。

前回記事

xrdnk.hateblo.jp

こちらの続きになります。

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 を利用して確認します。

gyazo.com

左側の方で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の表示・非表示制御を行い、それが右側でも同期されているのか試してみます。

gyazo.com

無事に同期されているのを確認できました。
最終的なコードは以下のようになります。

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;
    }
}