【Unity/VRChat】変数の同期方法

Unity

サンプルワールドの概要

ワールド内オブジェクト

  • ディスプレイ

したい事

変数の同期を利用して、ワールド内の全てのプレイヤーが同じテキストをディスプレイで見れるようにする。

処理内容

「自分が入室した時のプレイヤー数」を各プレイヤーが記録し、その値を各々がディスプレイに表示する。

この際、取得した値を同期するため、最初にワールドに参加したプレイヤーは2人目が参加するまでディスプレイに「1」と表示され、2人目が参加してからは1人目も2人目もディスプレイに「2」と表示される。

テスト

同期できない場合

スクリプト

using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
using VRC.SDKBase;

public class DisplayController : UdonSharpBehaviour
{
    [SerializeField]
    private Text txtDisplay;

    /// <summary>
    /// ワールドへの参加直後に呼び出される
    /// </summary>
    void Start()
    {
        //ワールド参加時のプレイヤー数を取得する
        int playerCount = VRCPlayerApi.GetPlayerCount();

        //取得した値をディスプレイに表示する
        txtDisplay.text = playerCount.ToString();
    }
}

実行結果

下画像にて1人目が左で2人目が右だが、変数の同期が出来ておらず、各々がワールドに参加した時のプレイヤー数を表示してしまっている。

同期できる場合

スクリプト

using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
using VRC.SDKBase;

//同期モードを「手動」に設定する
[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class DisplayController : UdonSharpBehaviour
{
    [SerializeField]
    private Text txtDisplay;

    [UdonSynced]//同期変数として登録する
    private int playerCount;

    /// <summary>
    /// ワールドへの参加直後に呼び出される
    /// </summary>
    void Start()
    {
        //ディスプレイの所有者が自分ではないなら
        if (!Networking.IsOwner(gameObject))
        {
            //ディスプレイの所有者を自分に設定する
            Networking.SetOwner(Networking.LocalPlayer, gameObject);
        }

        //ディスプレイの所有者が自分なら(念のため)
        if (Networking.IsOwner(gameObject))
        {
            //ワールド参加時のプレイヤー数を取得する
            playerCount = VRCPlayerApi.GetPlayerCount();

            //同期する
            RequestSerialization();

            //ディスプレイのテキストを設定する
            SetDisplayText();
        }
    }

    /// <summary>
    /// 同期変数の値が更新された際に呼び出される
    /// </summary>
    public override void OnDeserialization()
    {
        //ディスプレイのテキストを設定する
        SetDisplayText();
    }

    /// <summary>
    /// ディスプレイのテキストを設定する
    /// </summary>
    private void SetDisplayText()
    {
        //プレイヤー数をディスプレイのテキストに設定する
        txtDisplay.text = playerCount.ToString();
    }
}

実行結果

下画像にて1人目が左で2人目が右で、変数の同期が上手く出来ており、2人共同じ「2」という数字が表示されている。

ポイント

変数を同期するために必要な事

  • クラス名の上に「[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]」と記述して同期モードを「手動」に設定しなければならない
  • UdonSynced 属性を用いて同期したい変数を「同期変数」に登録する必要がある
  • 同期変数の値を変更し、変更後の値を同期できるのはそのオブジェクト(同期変数)の所有者のみであるため、「自分がそのオブジェクト(同期変数)の所有者かどうか」を確認し、自分が所有者ではなければ「Networking.SetOwner()」を用いてそのオブジェクト(同期変数)の所有者を自分に設定する必要がある
  • 同期変数の値を変更する場合は必ず変更後に「RequestSerialization()」と「同期変数の値を利用する処理(「同期変数の値をワールドに反映させる」等)をまとめたメソッド」の2つを呼び出さなければならない
  • 同期変数の値を利用する処理(「同期変数の値をワールドに反映させる」等)は1つのメソッドにまとめ、必ず「OnDeserialization()」内でそのメソッドを呼び出さなければならない

その他

参考記事

お問い合わせ

    タイトルとURLをコピーしました