はじめに
ようやくUdonSharpのSendCustomNetworkEvent
に引数の受け渡し機能が追加されましたね!!
このアップデートによってSendCustomNetworkEvent
の使い方が少し変わったので、新しくまとめてみました
-
新しいSDKにするには
-
新しいSDKでできるようになったこと
-
SendCustomEventとSendCustomNetworkEventの違い
-
SendCustomNetworkEventの簡単な使い方
-
新しいSDKで追加された便利なもの
新しいSendCustomNetworkEventを使うにはVRChatSDK 3.8.1以上が必要です
まだアップデートしていない人はVCCからアップデートしておきましょう!
(VRChatSDK – Worldsと- Baseの2種類がありますが、両方ともアップデートしておけば良いと思います)
新しいSDKでは
-
SendCustomNetworkEvent
に引数の受け渡し機能の追加 -
NetworkEventTarget.Others
、NetworkEventTarget.Self
の追加 -
NetworkEventを呼び出したプレイヤーの取得
-
VRC.Udon.Common.Interfaces.NetworkEventTarget.~~~
を短く記述
ができるようになりました!
これ以外にも追加されたものはありますが、ここでは紹介しません…(難しく私にはわかりませんでした)
詳しくは公式サイトの説明をごらんください
今回ここで主に取り扱うSendCustomNetworkEvent
と似たものとしてSendCustomEvent
というものがあります
両者の違いはネットワーク同期するかどうかですSendCustomNetworkEvent
はネットワーク同期しますが、SendCustomEvent
はネットワーク同期しません
SendCustomNetworkEvent
を使うと自分以外のプレイヤーにもその動作を行わせることができますが、SendCustomEvent
だと自分にしかその動作を行わせることができません
(その代わりにSendCustomEventにはSendCustomEventDelayedSeconds
というn秒後にその動作を行わせることができる、というメソッドがあったりします)
また、新しいSDKではSendCustomNetworkEventで引数が使えるようになりましたが、SendCustomEventでは引数は使えません!!!
そのSendCustomEventで引数が使えないという制限の回避策として今回のアップデートでNetworkEventTarget.Self
が追加されたようです。そのことについては5で解説します
C#での呼び出しとの比較↓
C#での呼び出しとの比較
SendCustomEvent
は同期の機能がないもの、と説明しましたが同期が必要でない部分であればわざわざこれを使わなくても良かったりします
じゃあどうやるのといえば大したことではないのですが、C#のメソッドの呼び出しと同じように記述することでUdonSharpでも同じようにメソッドを呼び出すことができます
SendCustomEventを使用した例
public class WhiteCube : UdonSharpBehaviour
{
void Start()
{
SendCustomEvent("Greet");
}
public void Greet()
{
Debug.Log("こんにちは!");
}
}
上記の例はSendCustomEvent
を使った例ですが、これは以下のように書くこともできます
SendCustomEventを使用しない例
public class WhiteCube : UdonSharpBehaviour
{
void Start()
{
Greet();
}
public void Greet()
{
Debug.Log("こんにちは!");
}
}
このようにどちらで書いても出力結果は変わりません
しかし両者には明確な差があります。
SendCustomEvent
を使用した場合、そのメソッドの返り値を受け取ることができません!!
2つ目の例のやり方ではそのメソッドの返り値を受け取ることが可能です
なのでぶっちゃけあんまりSendCustomEvent
を使う場所はない気がするのですが、SendCustomEventDelayedSeconds
にはしっかりと使う場面があります
その場面とは、
n秒後に指定の動作をさせたいというときです。
今まででUnityを触ったことのある人はコルーチン使えばいいやん、と思ったかもしれませんがUdonSharpではコルーチンは使用不可能です
具体的なコードについてはハツェさんの一定間隔で処理をするやつの正攻法と裏技 – ハツェの真時代傾向璋をごらんください
新しくなった機能を利用するにはVRC.SDK3をインポートするのが(おそらく)必須です!!
引数について
SendCustomNetworkEventの引数は
第1引数 :メッセージを送る対象
第2引数 :実際に実行させるメソッドの名前(String)
第3引数~:メソッドに渡す引数(任意)
となっています。
-
第1引数
メッセージを送る対象をここで指定します
選ぶことのできるものは以下のとおりです指定できる種類 意味 NetworkEventTarget.All そのワールドにログインしている全員に送信する NetworkEventTarget.Owner そのオブジェクトのオーナにのみ送信する NetworkEventTarget.Others 自分以外の全員に送信する NetworkEventTarget.Self 自分のみに送信する アップデートでは
Others
とSelf
が追加されたようです
また、従来のやり方ではVRC.Udon.Common.Interfaces.NetworkEventTarget.~~~
と、呪文レベルで長かった文章がNetworkEventTarget.~~~
で良くなっています(短縮した書き方を使用する場合には
using VRC.Udon.Common.Interfaces;
を追加しておきましょう)
-
第2引数
実行するメソッドの名前を指定します
名前はStringで与える必要があります。直接"hogehoge"
と指定しても良いですし、nameof(hogehoge)
として与えても良いです(公式的にはnameofを使用する方法を推奨している気がしますが、UdonSharpの記事では前者の直接文字列で指定する方法をよく見る気もします。まあどっちでもいいと思います)
-
第3引数以降
メソッドに渡す引数を設定することができます
ここで設定できる引数の上限数は8個までで、同期変数として使用できる型ならおそらく全て利用可能ですよく使いそうな型としては
bool、int、long、float、Vector2、Vector3、char、String、VRCUrl
などがサポートされています現在サポートされているすべての型を見るには公式サイトをごらんください
例を用いた使い方の説明
まず簡単な例をここで紹介します
WhiteCube.cs
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.SDK3;
using VRC.Udon;
using VRC.Udon.Common.Interfaces;
using VRC.SDK3.UdonNetworkCalling;
[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class WhiteCube : UdonSharpBehaviour
{
void Start()
{
SendCustomNetworkEvent(NetworkEventTarget.All, "Greet", "hogehoge");
}
[NetworkCallable]
public void Greet(string name)
{
Debug.Log(name + "さん、こんにちは!");
}
}
出力
hogehogeさん、こんにちは!
まず、使い始めるときにはusing VRC.SDK3;
とusingの部分に追加するようにしましょう!
これを追加することによって新しく追加されたものを簡単に利用できるようになります
そして呼び出したいメソッドは、必ずpublicで宣言するようにして、[NetworkCallable]
属性を付与するようにしましょう!
(引数を付けた呼び出しをする際にはこれが必須になります。引数を必要としないものの呼び出しではこの属性付与はおそらく必要ありませんが、公式ではつけるようにおすすめされているので引数が必要でない場合でもつけるようにしておきましょう)
[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]について
この部分では共有変数の同期方法について設定していますBehaviourSyncMode.Manual
を任意のものに変更することで同期方法を変更することができます
設定可能な値は以下のとおりです
モード | 意味 |
---|---|
None | 同期を行わない |
NoVariableSync | 動作に共有変数が強制されない…らしいです(よくわかりません) |
Continuous | 一定周期ごとに自動的に変数の同期を行う |
Manual | 手動で変数の同期を行う |
Continuousは自動的に変数の同期を行うが、Manualだと手動で設定したタイミングでしか同期が行われないので、ネットワーク的にManualを使うことがおすすめ、とされています(多分)
しかし、Manualモードの弊害として、VRC ObjectSync
コンポーネントが使用できなくなります。
ちなみにNoneにすると全く同期が行われないらしく、この状態ではSendCustomNetworkEvent
は使用できなくなります。
NoVariableSyncについては同期を行わないという点ではNoneと共通していますが、唯一違う点として、SendCustomNetworkEvent
が使用可能です
同期をオフにしたいけれどSendCustomNetworkEvent
を使いたい!というときにはNoVariableSyncを使いましょう
ちなみに[UdonBehaviourSyncMode(BehaviourSyncMode.~~~)]
のようなものを書かない場合、このようにインスペクターから同期方法を設定することができます
しかし、[UdonBehaviourSyncMode(BehaviourSyncMode.~~~)]
を書くと
このように設定項目がグレースケールになり、インスペクター上から変更ができなくなります
(ちなみに下の例はManualモードで固定しています)
コード側から指定したほうが安全性も増すと思うのでできるだけ[UdonBehaviourSyncMode(BehaviourSyncMode.~~~)]
という書き方を使ったほうが良いと思います
もっと詳しくこの同期方法について知りたい方はシン・U# 入門 ② – ハツェの真時代傾向璋を見ることをおすすめします!
新しいSDKではSendCustomNetworkEvent
を呼び出したプレイヤーのVRCPlayerApiを取得できるようになりました!
具体的にはNetworkCalling.CallingPlayer
プロパティを使用します
このプロパティの値としてはネットワーク呼び出しが行われた場合には、その呼び出しを行ったプレイヤーのApiを、ネットワーク呼び出し出ない場合にはNoneを取得できます
以下はCallingPlayer
プロパティを使用してSendCustomNetworkEvent
を呼び出したプレイヤーのプレイヤーIDを取得する例です
WhiteCube.cs
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.SDK3;
using VRC.Udon;
using VRC.Udon.Common.Interfaces;
using VRC.SDK3.UdonNetworkCalling;
[UdonBehaviourSyncMode(BehaviourSyncMode.Manual)]
public class WhiteCube : UdonSharpBehaviour
{
void Start()
{
SendCustomNetworkEvent(NetworkEventTarget.All, "Greet", "hogehoge");
}
[NetworkCallable]
public void Greet(string name)
{
VRCPlayerApi caller = NetworkCalling.CallingPlayer;
Debug.Log(name + "さん、こんにちは!" + "プレイヤーIDは " + caller.playerId + " です。");
}
}
出力
hogehogeさん、こんにちは!プレイヤーIDは1です。
Views: 0