VRChat Udonの同期について、初心者向けにわかりやすく解説

Udon

Udonの同期について理解に苦しむ方が多いんじゃないでしょうか。

私もその一人でした。

しかし、同期について理解すると、Udonでのワールド作りがだいぶ楽になります。

今回は、難解のUdonの同期について、絵を使いながら丁寧に説明していきます。

意外と簡単なので、皆さんぜひ参考にしてみてくださいね!

 

①同期とは

同期とは、VRChatの同じワールド内のプレイヤ間で同じ処理をすることを言います。

例えば、ワールド内にあるミラーのスイッチを押してミラーを「ON」にしたら、
他のプレイヤから見てもミラーが「ON」になるような処理をすることを「同期する」と言います。

具体的に見てみますと、プレイヤAが、ミラーのスイッチを押したら、

青いCubeがミラーのスイッチ

 

プレイヤAから見るとミラーは「ON」になります。

両者とも鏡に映っている様子

 

同期ができていれば、プレイヤBからみてもミラーは自動的に「ON」になります。

両者とも鏡に映っている様子

 

②同期をしないとこうなる

同期を考えずにワールドを作った場合、誰かがミラーのスイッチを押しても、他のプレイヤから見たら、ミラーは「OFF」のままです。

具体的には、プレイヤAがミラーのスイッチを押したら、プレイヤAからみるとミラーは「ON」になります。

両者とも鏡に映っている様子

 

しかし、プレイヤBから見ると、ミラーは「OFF」のままです。

プレイヤBから見ると、鏡が「OFF」のままなので、
自分とプレイヤAが鏡に映る姿を見ることができない。

 

どうしてこうなるかと言いますと、ワールド内にいるプレイヤたちは、Udonで書かれたスクリプトをおのおの実行しているからです。

つまり、それぞれ「ローカル」で実行しているわけです。

だから、例えば、プレイヤAがミラーのスイッチを押しても、プレイヤBから見るとミラーは「OFF」のままという現象が起きます。

つまり、プレイヤAはミラーを見ることができますが、プレイヤBはミラーを見ることができません。

プレイヤBは、自分でミラーのスイッチを押すことで初めて、下のようにミラーを見ることができます。

プレイヤBが自分でスイッチを押すことで、
両者とも鏡に映すことができる。

 

ミラーであれば、別にそこまで問題ないかもしれませんが、敵を倒すゲームを作る場合、同期をちゃんと考えないと、
プレイヤAの世界では敵は倒れているのに、プレイヤBの世界ではまだ敵が生きているという感じになってしまいます。

これはちょっとまずいですよね?

そこで登場するのが「同期」です。

同期をすれば、プレイヤAの世界で敵が倒れていたら、プレイヤBの世界でも敵は倒れているという状況を作り出すことができます。

 

③同期の仕組み

例えば、プレイヤAとプレイヤBが同じワールドに居て、ワールド内にはミラーとミラーを起動させるスイッチがあるとします。

プレイヤAとプレイヤBはそれぞれスクリプトを実行しているので、同じ処理をしているとは限りません。

先程述べた通り、プレイヤAがミラーのスイッチを押しても、プレイヤBから見るとミラーは「OFF」のままとなるわけです。

プレイヤAがミラーのスイッチを押したら、プレイヤBから見てもミラーが「ON」になるようにするためには、
プレイヤAがスイッチを押したら(プレイヤA側のスクリプトでミラーを「ON」にする処理をしたら)、
プレイヤB側のスクリプトにもミラーを「ON」にする処理をさせる必要があります。

では具体的にはどうするか、スクリプトを見ながら解説していきます。

 

④同期させる方法

1.同期しないスクリプト

次のスクリプトを見てください。

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class MirrorButton : UdonSharpBehaviour
{
    public GameObject mirror;

    void Start()
    {

    }

    //スイッチを押すと実行される関数
    private void Interact() 
    {
        //「mirrorOn()」を実行
        mirrorOn();
    }

    public void mirrorOn()
    {
        //ミラーを「ON」にする命令
        mirror.SetActive(true); 
    }
}

このスクリプトはスイッチとなるオブジェクト(青いCube)に「Add Component」でくっつけます。

 

スクリプトの流れは、

まず、プレイヤーがスイッチを押すと「Interact()」が実行されます。

つづいて「Interact(){}内のmirrorOn()」が実行されます。

「mirrorOn(){}」内の「mirror.SetActive(true)」でミラーを「ON」にしています。

ただし、プレイヤはスクリプトをおのおの実行しているため、上のスクリプトだと、スイッチを押した人だけミラーが「ON」になります。

 

2.同期するスクリプト

今度はこちらのスクリプトを見てください。

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;

public class MirrorButton : UdonSharpBehaviour
{
    public GameObject mirror;

    void Start()
    {

    }

    private void Interact()
    {
        //スイッチを押した人を「オーナ」にする命令
        if (!Networking.IsOwner(Networking.LocalPlayer, this.gameObject)) Networking.SetOwner(Networking.LocalPlayer, this.gameObject);
        
        //すべてのプレイヤに「public void mirrorOn()」を実行させる(同期させる)命令
        SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.All, "mirrorOn");
    }

  //同期させる関数は「public」
    public void mirrorOn()
    {
        mirror.SetActive(true);
    }
}

先ほどと違って、

「if (!Networking.IsOwner(Networking.LocalPlayer, this.gameObject)) Networking.SetOwner(Networking.LocalPlayer, this.gameObject)」

「SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.All, “mirrorOn”)」

が追加されていますよね。

この部分が、まさに同期をさせるところになります。

 

1つ目の

「if (!Networking.IsOwner(Networking.LocalPlayer, this.gameObject)) Networking.SetOwner(Networking.LocalPlayer, this.gameObject)」は

スイッチを押した人に同期させる権限を与えるためのものです。

ここで注意なのですが、同期を実行するには権限が必要です。

この権限を持つ人とは、スクリプトがくっついているオブジェクトのオーナのことです。

「if (!Networking.IsOwner(Networking.LocalPlayer, this.gameObject)) Networking.SetOwner(Networking.LocalPlayer, this.gameObject)」

の意味は、「このスクリプトがくっついているオブジェクトのオーナでなかったらオーナにする」です。

 

同期の権限を与えたら、

「SendCustomNetworkEvent(VRC.Udon.Common.Interfaces.NetworkEventTarget.All, “mirrorOn”)」

で実際に同期をしています。

この意味は、
「このワールド内のすべてのプレイヤに「public void mirrorOn()」を実行させる」です。

こうすることで、すべてのプレイヤが一斉に「public void mirrorOn()」を実行します。

つまり、すべてのプレイヤが一斉にミラーを「ON」にするわけです。

 

これで無事、すべてのプレイヤで見ている世界が一緒ということになりました。

 

⑤同期の際の注意点

最後に、同期をするときの注意点をお伝えしたいと思います。

同期をさせたい関数は「public」にしないと動かないので注意です。

今回の場合も「public void mirrorOn()」と「public」が、頭についていますよね。

 

以上がUdonの同期の大まかな話です。

本当は変数も同期できたりと、もっといろいろできるのですが、長くなってしまい、皆さんに辛い思いをさせてしまうかもなので
今回はこの辺で。

最後まで読んでいただきありがとうございました!

また次の記事でお会いしましょう!!

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