サンプルワールドの概要
ワールド内オブジェクト
- ディスプレイ
- 床

したい事
変数の同期を利用して、
ワールド内の全てのプレイヤーが同じテキストをディスプレイで見れるようにする
処理内容
「自分が入室した時のプレイヤー数」を各プレイヤーが記録し、
その値を各々がディスプレイに表示する。
この際、取得した値を同期するため
最初にワールドに参加したプレイヤーは
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()」内でそのメソッドを呼び出さなければならない
コメント