VRCStationに対して、「座っている」「座っていない」という状態を保持できる状態を作る話
概要
VRCSDK3のVRCStation に対して、今誰かが座っている、今誰かが座っていない、といった状態が欲しかったので、それらの仕組みをU#で作る上で、行ったアプローチの数々と最終的にどうしたか といったものが記述しています。正解かわかりませんが、こうすれば、一応作る事ができるといったものをまとめました。
対象
VRCStationを使用しているという状態が欲しくて渇望している人
開発環境
U#とSDKいずれも2020年5月くらいのタイミングで、実装されているものを使用。 なので、最新の場合だと変化している場合があるかもしれませんが、ちらっと見た感じはいけると思います。
事前知識
UdonGraphなどを、見てぼんやりこうかながわかる U#もしくはUnityでプログラムを書いた事がある SeiralizeFieldを使い方がわかる
作ろうと思ったきっかけ
きっかけは、座った状態の時に、OOが出来るといった。座っていないとできないものの制御を行うために VRCStationを調べてみたが、それっぽいのが、見つからなかったため。
作るもの
作るものとしては、「座っている」「座っていない」という状態を外部から判断が出来るもの。
目次
誤解回避のための事前共有
ここででてくる「VRCStation」は基本的には、VRC.SDKBaseの所にあるVRCStationです。 それらを継承したVRC.SDK3.ComponentsにあるVRCStationではありません。 以降VRCStationは、VRC.SDKBaseにあるVRCStationの事を指します。
また、VRCStationは、PrefabのVRCChair3というPrefabを使っています。 このPrefabについているVRCStationは、VRC.SDK3.Componentsの方ですが、VRCStationを継承されているため外部から取得する際は、VRCStationを取得しています。
成功したアプローチ
以下が最終的におちついた構成とそれぞれの処理。
まず、Hierachyの構成
緑の部分がU#で作ったものをUdonBehaviorで使用したものです。
数字に書いているUdonSharpスクリプトのそれぞれのソースコードとしてはざっくり以下 (必要な処理だけ)
その1 VRCStationの状態を知りたいところ
[Serializefield] private その3のクラス名; public override Intaract() { if(その3 のクラス名.IsSetting) { //座っていたらできるIntaract処理 } }
その2 VRCStationを降りるを行うもの
[SerializeField] private その3のクラス名; void Start() { } public override void Interact() { if(null == sorting) { return; } その3のクラス名.OutExit(); }
その3 VRCStationの状態を保持しているところ
[SerializeField] private VRCStation station; public bool stationUsed; public override void Interact() { if(stationUsed) { return; } stationUsed = true; VRCPlayerApi api= Networking.LocalPlayer; station.UseStation(api); } /// <summary> /// 降りるためのもの /// </summary> public void OutExit() { stationUsed = false; VRCPlayerApi api = Networking.LocalPlayer; station.ExitStation(api); }
さらにVRCStationの設定で、Stationから外れる時は、かならず、その2のスクリプトが通るように以下の設定を行います。 DisableStationExit をtrue CanUseStationFromStation をfalse
で一応行えました。
失敗したアプローチ その1
VRCStationで提供されているstatic 関数の useStationDelegate 及び exitStationDelegateに対して、U#のUdonBehavior継承したクラスが欲しい処理を呼び出してもらうようにする。
結果:そもそもU#がdelegateを使用できないようで、うまくいかなかった。あとstaticなので、全体のVRCStationに絡んでくる可能性もあるので、早めに切り上げ。 UdonGraphでなら出来るかもしれないが、少なくともやりたくなかったので、今回は割愛。
失敗したアプローチ その2
VRCStationが提供されているboolで実装されている内容を見る。 提供されているboolは全部で3種類 - canUseStationFromStation (StationからStationへの移動が可能か) - disableStationExit (Stationを移動で降りる事が可能か?) - seated (座る状態に最適化するか?) の3種類があるが、いずれも、Stationを使用した時に対しての設定みたいなものだったため、今回の目的である、「座った」「座ってない」が外部からとれるものではなかった。
参考としては以下のURL
VRC_Station - VRChat Document 日本語訳 Wiki*
失敗したアプローチその3
アプローチとしては、VRC.SDKBase.VRCStationがabstractで継承されているので、それを継承して、オレオレVRCStationを作成して、それを欲しいところで使用する。
オレオレVRCStationはU#側がそもそも認識されないという状態(恐らくあくまでも、U#自体は、UdonBehaviorを継承していないクラスは、基本的には、VRCSDKクラスのみをサポートしているであろうため。) (もしかしたら、Githubに書いているかもしれない。)のため、U#上で使用できなかったため。
失敗したアプローチその4
Intaractを実装したUdonBehaviorを継承したクラスにSerializeFieldでVRCStationの参照だけ持ってきてあげてUseStationなどを使用して、行う。
ほぼほぼ正解に近かったものではあるのだが、単純に、Intaractを実装したゲームオブジェクトに対して、Coliderが存在しなかったため。(これは単純なミス)