VRChatのワールドでuGUIを使う

# はじめに
VRChatのワールドでuGUIを使う際の注意事項や必要事項などを
具体例をあげて紹介していきます

本記事ではUnity本来のuGUI寄りの使い方を紹介しています
また, ワールド作成をしたことある人向けの内容になってると思います

VRChatでの黒魔術的な使い方（AnimationからPressでuGUIのButtonを叩いて～）はこの記事では解説しません
[butadiene121さんのこちらの動画](https://www.youtube.com/watch?v=VnlFv9mPUg0)を参考にどうぞ

また、uGUI自体の一般的な使い方についてはここでは紹介しないので各自調べてみてください

# uGUIとは
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/ff3cede8-44df-d1d8-f8a6-194b4a0672d2.png)
**Unityで提供されているGUI構築を簡単にする機能**
例) Button, InputFiled, Slider

VRChatでは単にuGUIだけだと**基本的にはローカルでしか動作しません**
(操作内容は他人と同期しません)
VRCSDKのVRC_Triggerをうまく絡ませたりすることで同期するuGUIを作ることができます

(2019/10/19更新) 海外の方が同期するuGUIスライダーを公開されました
https://twitter.com/Phasedragoon/status/1185207396202774528
これを使う方法は@hatuxesさんがこちらの記事で紹介されています
https://qiita.com/hatuxes/items/7be6e1ef4c5fb446512b

# 操作できるuGUIを設定する
VRChatのワールドで操作可能なuGUIにするためには以下が必ず必要です

1. Create>UI>Canvasで作成し, Canvasに**VRC_UiShapeコンポーネント**をつける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/ad500508-7cfd-8c76-bfeb-9cfccfc8a1fc.png)

2. ワールドに設置する場合, Canvasの**RenderModeをWorldSpace**にしてScaleやサイズを調整する<br>
(Scaleそれぞれ0.005, Width:300, Height:200とか)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/1c05f715-73b4-be11-3100-3f267b1559b7.png)

3. Canvasのレイヤーを**Default**にする<br>
(UIもしくはUiMenuの場合はクイックメニューを開いている際にレイキャストが出て操作できる)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/293282c8-0c1a-2e4c-5870-d5133bbf61d2.png)

4. 作成したCanvasの子にCreate>UIでButtonやSliderなどを追加していく（子にしていく）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/ada1a3bb-e3b7-b93c-fe3b-3258b4ecba3e.png)


SliderのNavigationはNoneにするように
(Noneにしないとアバター移動時にSliderを動かしてしまう)
Button以外はすべてNoneにしてもいいと思います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/30716f55-9efb-9077-7a3d-aa48004aa9f5.png)

操作しているとEventSystemというのが作成されますが, これは必要なので削除せずに残しておいてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/25292971-4990-6bf7-10a0-e2c93ecba019.png)


# 同期するuGUIのButtonを作る
1. VRC_TriggerをButtonにつけてOnClick()でVRC_TriggerのInteractを設定する
(VRC_Triggerは必ずしもButtonにつけないといけないわけではないです)
2. VRC_TriggerのOnInteractが実行されるため、ここにAlwaysUnBufferedなどを設定し、<br>
Buttonを押したときのActionを設定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/6ae2249e-963f-521e-f979-80b27497c6d5.png)


VRC_TriggerでCustomで設定してButtonからExecuteCustomTriggerで発火させても良い

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/ad6b016e-3ff7-641a-fc44-194a4f4b812c.png)


# InputFiledで動画URLをSyncVideoPlayerなどに入力する
Youtubeなどの動画URLをSyncVideoPlayer(またはSyncVideoStream(以下省略))に動的に追加する方法です
入力内容は同期しませんが, SyncVideoPlayerの本来の仕様で再生される動画内容は同期します
SyncVideoPlayerのOwnerのユーザーが入力することで入力内容が反映されます
(特に意図的にOwnerを切り替えることをしていなければ, おそらくインスタンスのMasterがOwnerになっている)

1. InputFiledのOnEndEditの右下の+を押す
2. RuntimeOnlyの下の選択部分でSyncVideoPlayerがついたオブジェクトを選択する（またはドラッグ&ドロップする）
3. RuntimeOnlyの右側にあるところでSyncVideoPlayerのAddURLを選択する（この時, Dynamic(上のほう)のAddURLを選択）
4. これで入力後にEnterを押すと, SyncVideoPlayerに新しい動画URLとして追加される。<br>
その後追加されたURLの動画を再生するように組めばよい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/fc0b3b65-163e-bca7-c517-0edb78dfb1d1.png)

追加前にSyncVideoPlayerに対してStop->Clearをして, 動画URL追加後にPlayすると追加した動画が再生できます（あくまで1例）
その際に動画URL追加後に反映に時間がかかるため5秒ぐらい開けてPlayする必要があります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/35ef8d4e-8783-6b56-32e3-d1f1324ac125.png)


# SliderでAudioSourceの音量を変更する
ワールドのBGMやSyncVideoPlayerの音量などを調整する方法です

1. OnValueChanged(Single)に対象のAudioSourceを設定する
2. Dynamic float（上のほう）のfloat volumeを選択する
（SliderのValueの値がAudioSource.volumeに入るようになる）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/d6d5b820-062e-938a-ecde-d52317938179.png)

3. SliderのMin ValueとMaxValue, Valueを設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/86f8e105-2c81-fc0b-cca2-678bd096edf8.png)

ちなみにButton等でAudioSource.muteをtrueにするようにするとミュートボタンを作れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/1e4f84b2-ecfb-e087-609d-1e1b76cf3602.png)
また, SilderAでSliderBのmaxValueを設定するとSliderAを操作することでSliderBの最大値を変更するみたいな使い方もできる

ここらへんは同期せず、ローカルで動作する
(同期するSliderはTPCスライダーを使わないといけない。もしくはAnimator周りを絡ませる(結構複雑な機構))

# 別のSliderも同時に操作する
Sliderを操作すると別のSliderも一緒に動くみたいなこともできます

1. SliderAのOnValueChangedにSliderBのDynamic floatのvalueを設定する
2. 逆も同じように設定する。SliderAを動かすとSliderBも動くようになる


# 参考
[VRChat技術メモ帳 uGUI](https://vrcworld.wiki.fc2.com/wiki/uGUI) : 下のほうに実装サンプルもあります
[JetDogs-Prefabs](https://github.com/jetdog8808/JetDogs-Prefabs) : Jetdogさんのワールド制作向けPrefab集で一部uGUIのものが含まれています

uGUIについての解説
[【Unity入門】Canvasって何が出来るの?UIの基礎を学ぼう!](https://www.sejuku.net/blog/56615)
[uGUI (UnityのUI機能) の使い方まとめ](http://mikan-daisuki.hatenablog.com/entry/2016/01/11/175010)

# 関連記事
[【VRChat】uGUIを使ったワールドメニューのサンプル公開+解説](https://www.pixiv.net/fanbox/creator/4868515/post/436158)