VRChatでイベント用ワールド制作をしていると、イベントスタッフのみに使用許可したいUIメニューやお客さんに入って欲しくないエリアを作りたい時があります。荒らし対策は必須ですが、一方でUdonでセキュリティシステムを構築するのは少し知識が必要になります。また、それぞれのオブジェクトで許可するプレイヤーを選択するスクリプトを組んでいては管理が大変です。
そこで今回はUdonSharpでイベントスタッフを一元管理するコードを書いてみました。基本構造のみで一応実用上は問題ないですが、バグ取りをしていないので適当にブラッシュアップしてください。 (そして僕に教えてください)
public class StaffList : UdonSharpBehaviour
{
[Tooltip("スタッフリスト")]
public string[] StaffNameList;
[System.NonSerialized] public bool _isStaff;
void Start()
{
foreach (string list in StaffNameList)
{
if (list == (string)Networking.LocalPlayer.displayName)
{
_isStaff = true;
return;
}
}
_isStaff = false;
}
}
このUdonを付けたGameObjectを適当な階層に置き、Inspector上でStaffNameListにVRChatのユーザー名(表示名)を登録します。
表示名は VRChat.com からブラウザ上で変更できますが、一度変更すると数か月間は変更できません。なので捨て垢とかでスタッフと全く同じユーザー名にされてしまうと対処法がありません。
Start内で自分の表示名を取得し、StaffNameListと照合をかけます。私のイベントでは現在スタッフ4名を登録しているのでそこまで重くなっていませんが、100名とか登録するとワールドに入った瞬間が重いかも?
照合結果をlocalのbool変数_isStaffに持ちます。あとは実行側のスクリプトで_isStaffを参照して登録されたスタッフかそうでないかを判断するだけです。
public class StaffOnly : UdonSharpBehaviour
{
[SerializeField] UdonBehaviour StaffList;
[SerializeField] GameObject TargetObject;
void Start()
{
LocalOff(TargetObject);
}
private void LocalOff(GameObject obj)
{
if ((bool)StaffList.GetProgramVariable("_isStaff") == false) return;
obj.SetActive(false);
}
}
スタッフ以外立ち入り禁止エリアを作るコードです。
StaffListは上のリストのオブジェクト、TargetObjectは立ち入り禁止エリアのコライダーを指定します。
Start関数でLocalOff関数が呼ばれ、StaffList内の_isStaff変数がFalseだったらreturnで処理終了。そうでなければ(=スタッフ登録されていれば)TargetObjectを無効化するのでエリアに侵入することができます。
if ((bool)StaffList.GetProgramVariable("_isStaff") == false) return;
スタッフのみに実行させたい関数の頭に1行足すだけなのでお手軽です。
メンバー登録はStaffListで行うので複数のシステムで再利用することができますし、複数のStaffListを作ることも可能です。
名前を変えられると無意味な点、バグ取りをしていない点など適当ですが、基本構造としてはシンプルでよいかなと思います。