ネットワーク

変化を教えてくれる同期値と、誰でも送れる型付きメッセージ。シーンに用意するものはありません。

更新日 2026-09-10

ワールドの中の 2 台のクライアントが同じ内容を共有する方法は 2 つあり、選び方を間違えると静かに壊れます。

同期変数は「全員が持っている事実」です。 スコア、扉の開閉、次に誰の番か。あとから入ってきた人にも、誰も送り直さずに現在の値が届きます。

メッセージは「一度だけ起きたこと」です。 攻撃が当たった、ラウンドが始まった、ボタンが押された。これを変数で送ると、何も起きていないように見える形で壊れます。同じ値を 2 回入れても変化は 1 回なので、同じ攻撃 2 回は 1 回になります。遅れて入った人には、見ていない戦闘の最後の一撃が今起きたかのように届きます。書けるのはオーナーだけなので、2 人が同じ対象を攻撃すると変数を奪い合い、片方の攻撃は何も言われずに消えます。

このパッケージはその両方で、うまくいかない部分は引き受けます。

public class Door : UdoniteBehaviour
{
    private Synced<bool> open = new Synced<bool>();

    public override void Start()
    {
        open.Subscribe(OnOpenChanged);
        Room.Subscribe<Knocked>(OnKnocked);
    }

    public override void Interact()
    {
        open.Value = !open.Value;      // 複製され、各クライアントのハンドラーが動く
        Room.Send(new Knocked());      // 送信者も含め、全員が一度だけ受け取る
    }

    private void OnOpenChanged(bool value) => panel.SetActive(value);

    private void OnKnocked(Knocked message) => sound.Play();
}

Room.Send の行き先はルーム全体で、誰でも送れます。特定のオブジェクトについてのメッセージはそのオブジェクトの上を流れ、オブジェクトそのものであるビヘイビアに this.Send と書きます。そちらはそのオブジェクトの所有が要ります。どちらもメッセージにあります。

open.Value = ... は変数を書いて複製を依頼します。忘れがちな RequestSerialization はありません。Subscribe は値が届いたときに各クライアントでハンドラーを呼びます。更新の途中ではなく、全部が届いてからです。

何を誰が所有している必要があるか

所有権はこのパッケージのものではなく VRChat のものです。replicate されるのは所有者の書き込みだけで、違うのは所有者でないときに何が起きるかです。

すること 所有が要るもの 所有していないと
Synced<T> に書く そのフィールドを持つオブジェクト 書き込みは自分のクライアントに留まり、次に届いた値で上書きされます
このオブジェクトのチャンネルへの this.Send このオブジェクト 何も積まれず何も配られません。コンソールに一度だけ出ます
NetworkBus への channel.Send そのバスのオブジェクト 同じです
Room.Send 不要 各クライアントが自分のプレイヤーオブジェクトのバスに書くので、取り合うものがありません
NetworkTransform を動かす そのオブジェクト 所有者が送り、ほかは全員そこへ補間します

所有者が要らないのはルームのメッセージだけで、どのクライアントも動いてよいときにこれを選ぶ主な理由です。オブジェクトのチャンネルも同期フィールドも、結局は書き手が 1 人です。誰でも動いてよいワールドは先に所有を取ります。

if (!Ownership.IsMine(gameObject))
    Ownership.Claim(gameObject);

ピックアップや Interact なら、たいていすでに取れています。MasterOwned は逆で、これを継承すると調停役のクライアントしか所有できません。ほかの誰にも書かせたくない状態のためのものです。

ここにあるもの

Synced<T> 全クライアントが持つ変数。変化を教えてくれます
Room 型付きメッセージの送信と購読。誰がいるか、誰が調停役か
NetworkEvent バイト列ではなく、フィールドを持つメッセージ
NetworkBus オブジェクト自身のチャンネル。そのオブジェクトについての話に
NetworkTransform 位置・回転・スケール。補間とテレポート検出つき
Ownership 誰が持っているか、取る、渡す
MasterOwned 調停役だけが持てるオブジェクトの基底クラス

用意しなくてよいもの

ルームのメッセージは、シーンの中の 1 つのオブジェクトに書かれます。書き込み先はクライアントが所有している必要があり、ワールド実行中に作ることはできないからです。このパッケージが自動で追加し、その理由をコンソールに一度だけ出します。送信しないワールドには何も追加されません。

自分で置きたい場合は、VRCPlayerObject を持つオブジェクトに NetworkBus を付けてください。名前ではなくコンポーネントで探すので、そちらが使われます。

Udonite → Open Window → Settings → Net にこれを切るトグルがあります。オフにすると、ワールドが何を送っていようとパッケージはシーンに一切触れません。バスを置くのは完全にあなた次第になります。デフォルトはオンです。この設定は ProjectSettings/ にあり、除外リストと同じくコミットされます。これは開発者一人の好みではなく、シーンを誰が持つかという、プロジェクト自体の話だからです。

問題が発生しました 再読み込み