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