2018年07月29日

VRChatパスワード入力式インスタンス移動システム(VRC Password Jumper)

*はじめに
この記事は、以下の記事を前提としています。

VRChat固定インスタンス間移動システム(VRC World Jumper)の設置方法 http://gpsnmeajp.sblo.jp/article/184041906.html

*概要
パスワード認証を実装してみました。

お試し用ワールド
https://vrchat.net/launch?worldId=wrld_30da4670-55de-4633-a2e3-b6d34ab1b5b1

jmpD.png



twitterに載せたところ割と評判が良かったので、差し替え用HTMLを配布します。
(このままページを開くとデモを試すことができます。パスワード=1234)
https://sabowl.sakura.ne.jp/gpsnmeajp/tool/vrcpass.htm

Quadの大きさや、WebPanelの描画の大きさは適時調整してください。
Scale X=1,Y=1と、W=800,H=800で動作確認しています。

*解説
WebPanel上で動作するjavascriptでパスワード認証を行い、照合に成功すると特定のインスタンスにジャンプします。
このインスタンスは、Ownerの居ないInviteOnlyになるため、誰もInviteできません。
つまり、正しいパスワードを入れた人しか入れません。

謎解きワールドなどに使えるかもしれません。
桁数の制限はありません。
他者の入力しているパスワードを見ることはできません。

ところで、パスワードによって飛ぶ先を変えたり、パスワード入れたらQRコード表示されたり、いろいろできます。やってみたいことありましたらコメント等にdiscordかtwitterのIDを添えてでお問い合わせください。

*注意
1. パスワード認証はかなり簡易的なものです。おもちゃとして取り扱ってください。
注意喚起のためあえて突破方法を案内します。
以下の方法で突破することができます。
・ワールド情報のぶっこ抜き→HTML内の閲覧
・ワールドIDを何らかの方法で引っこ抜いてからの直接GotoRoom
・総当たり攻撃
これらに対する対策は可能ですが、外部サーバーが必要になります。

2. この方法はVRChat公式の方法からは外れた方法です。
公式から提供されている機能を利用していますが、未保証な機能です。(理由はページ末へ)
将来的に使用できなくなる可能性があります。

3. この手法を用いたことによる損害等の責任は一切持ちません。

4. WebPanelが何らかの理由で動作不良になっている人は飛べません

5. 一度ワールドから蹴り出されると、戻るためには再びパスワードを入れるしかありません。

*苦労した点
まさかPC上でチャタリング対策を実装するとは思わなかったよね

*応用例
こんなふうに使えるかもしれません。
1. ワールドを作る。
2. ワールドに、このパスワードシステムを設置する。
 そして、このワールドのURLをSNSとか個人サイトに適当に貼る。
 (https://vrchat.net/launch?worldId=wrld_48cf80e6-15dd-4c17-8667-c5dc01baa5cb のように)
3. パスワード知ってる人は、公開されたワールドを経由して、
 「パスワード知ってる人用インスタンス」にいつでも入ることができる。
posted by gpsnmeajp at 20:01| Comment(0) | TrackBack(0) | 雑感

【未検証】人数増えると重くなるVRChatのワールドをお手軽に軽くできそうな方法(カメラのカリング距離)

※根本的に複数インスタンス間を移動できるようにしてしまうという手もあります。こちらもどうぞ。
VRChat固定インスタンス間移動システム(VRC World Jumper)の設置方法
http://gpsnmeajp.sblo.jp/article/184041906.html

*はじめに
VRChatって、人数集まるとかなり重くなりますよね。
それって多分、遠くにプレーヤーが居ても消えないからんじゃないかな、と勝手に思っていました。

たまたまVRChat技術メモ帳を見に行ったら気になる項目が更新されていました。
https://vrcworld.wiki.fc2.com/wiki/VRC_SceneDescriptor

「カリングの範囲はこのカメラの設定が適用される。Nearを最小にすれば、普段より近づいてもカリングされなくなる。
https://twitter.com/gatosyocora/status/1023400101933248512
カリング(余計なものを描画しない処理)の距離が変更できるらしいです。

Near、つまり近づきすぎたときに消える処理をいじると、ガチ恋距離ができるという。
では、Farはどうなってるのかなと思ったら「1000m」でした。そりゃ離れても消えませんわ。
(天空高くや、地下深くなど、別の部屋を遠くに作ると軽くなると言われる原因はこれかと思います。)
なお、声は350m離れると聞こえなくなります。

というわけで、カメラのカリング距離を変更して、遠くにいるプレーヤーが見えないようになれば、人数増えてもあまり重くならないんじゃないかなと思いました。
代償として、遠くの壁や物品も見えなくなりますが...

また、同期周期もデフォでは最小値の33msを大きく下回る10msになっているらしいので、これも大きくすると重さが改善されそうです。
※最新のSDK(VRCSDK-2018.06.21.13.02_Public.unitypackage)ではこの問題は修正されており、デフォルトで33msに設定されています。
https://docs.vrchat.com/docs/vrchat-201822

*設定方法
クリックで拡大
light0.png

*カリング距離の適用結果
light1.png
posted by gpsnmeajp at 14:34| Comment(0) | TrackBack(0) | 雑感

VRChat固定インスタンス間移動システム(VRC World Jumper)の設置方法

VRC World Jumper


jmpA.png

この記事を試す前に、下記の対策も試してみてください。(併せると効果高くなります)

ワールドのカメラのカリング距離調整と、同期頻度調整
http://gpsnmeajp.sblo.jp/article/184044375.html

*概要
VRChatはまだ未発展のサービスということもあり、1つのワールドに20人以上集まると段々と重くなってきます。
しかし、ワールドの部屋単位たるインスタンスは、基本個人に紐付いて生成されるため、
publicではないインスタンスでは、フレンド同士でないと移動が難しくなります。

ワールドに設置したポータルは、インスタンスを指定できないため、
時に違うインスタンスに移動してしまったりします。

ここでは、WebpanelのGoToRoomを使った「固定のインスタンス間の移動」を
行う仕組みをワールドに実装する方法をご説明します。

お試し用ワールド
https://vrchat.net/launch?worldId=wrld_30da4670-55de-4633-a2e3-b6d34ab1b5b1

*注意
この方法はVRChat公式の方法からは外れた方法です。
公式から提供されている機能を利用していますが、未保証な機能です。(理由はページ末へ)
将来的に使用できなくなる可能性があります。

この手法を用いたことによる損害等の責任は一切持ちません。
vrcjmp.zip内のコードに関してはCC0とします。

*よりシンプルな作例のご紹介
がとーしょこら(@gatosyocora)様がunitypackageでよりシンプルな形態のものを配布されています。
こちらもご検討ください。
https://twitter.com/gatosyocora/status/1022125633671843840

*作り方
1. 以下のファイルをダウンロードし、展開します。
https://sabowl.sakura.ne.jp/gpsnmeajp/tool/vrcjmp.zip
v1.0 2018-07-29 公開
v1.1 2018-07-29 構造の改良と色付け
v1.2 2018-07-29 nonceの修正

2. vrcjmp.htmの中身を書き換えます。
「wrld_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx」を、自分のワールドのIDに置き換えてください。
別の部分を巻き添えで消さないように注意してください。1文字でも欠けると動きません。
jmp1.png
ワールドのIDは、Unityの「VRChat SDK」の「Manage Uploaded Content」からコピーできます。
(まだ一度もpublishしていないワールドはコピーできません。一度publishしてください)
jmp2.png

3. webフォルダを作り、その中にvrcjmp.htmを配置します。
jmp3_1.png

jmp3_2.png

jmp3_3.png

4. ワールドにWebpanelを設置します。
まずそのためのQuadを設置します。位置は自由です。
Scale はX : Y が 2 : 1 になるように設定してください
(例ではX=1, Y=0.5にしています)
jmp4.png

jmp5.png

QuadにVRC_Web Panelをセットします。
jmp6.png

設定はまず以下のようにします。特に赤枠に注意してください。
(赤枠以外も変更していますので、なるべく同じ状態にしてください)
jmp7.png

次に、vrcjmp.htmを読み込むように設定します。
jmp8.png

最終的に以下のようになればOKです。
jmp9.png

*ワールド内での使い方
ワールドに入ると以下のように表示されます。クリックすると、指定されたFriend+のインスタンスに飛びます。
これは固定化されており、誰がクリックしても同じROOMは同じインスタンスに飛びます。
(なお、このルームの数や種類はvrcjmp.htmを編集することで変更できます。)
jmpA.png
最初にワールドを開いた人は、そこは固定されたインスタンスではないため、
まずどれかのROOMをクリックして移動しておくことをおすすめします。

*ちなみに
HTMLをカスタマイズするとこういう画像を使ったものや、ボタンを増やしたものもできます。また、違うワールド同士を固定のインスタンスで接続したりもできます。

パスワード入力して正しいときだけ特定のワールドに飛んだり、オリジナルのポータルを通ってワールド間を往来したり、時刻によって飛び先が変わったり、そんなことも多分できます。

やってみたいけどやり方わからない、という方は、簡単なものであればお作りできますので、お気軽にページ下部のコメントでお問い合わせください。
問い合わせの際にはdiscordかtwitterのIDを添えてください。

例えば、城ワールドと飛空艇ワールドと迷宮ワールドを行き来できるようになったり
jmpB.png
パスワード認証したり(http://gpsnmeajp.sblo.jp/article/184045837.html )
jmpD.png

なお、設置の仕方がわからないという問い合わせは受け付けかねます。

設置してみたけどうまく動作しない場合は、上記の手順をしっかり読み直して、
可能であればまっさらなワールドに設置してみて、それでもダメ場合は
配布HTMLの不具合等の可能性がありますので、お問い合わせください。

*メモ
・セキュリティを向上させたい場合はnonceを書き換えてください。
・他のワールドのWorldIDを指定すると、他のワールドの固定インスタンスに飛ぶことができます。
 (相互に設置し合うと、行って帰ってくることができるようになります)
・スクリプトや外部サーバーを組み合わせるとかなりいろいろなことができます。
・負荷の都合上おすすめしませんが... その場にいる全員を違うワールドにふっとばすこともできなくはないようです。
・VRC_Triggerから発動もできるはずなので、斬られると天国に飛ばされるとかも、できなくはない
 →Triggerからの発動についてはがとーしょこらさんの仕組みのほうが単純で良いと思われる。

*書式
ユーザーIDあり
Public
wrld_xxxx:0000~public(usr_yyyy)
Friends+
wrld_xxxx:0000~hidden(usr_yyyy)~nonce(zzzz)
Friends
wrld_xxxx:0000~friends(usr_yyyy)~nonce(zzzz)
Invite+
wrld_xxxx:0000~private(usr_yyyy)~canRequestInvite()~nonce(zzzz)
Invite Only
wrld_xxxx:0000~private(usr_yyyy)~nonce(zzzz)
wrld_xxxx:0000~private(inviteurl_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)というパターンも?

ユーザーIDなし
Public
wrld_xxxx:0000~public
Friends+
wrld_xxxx:0000~hidden~nonce(zzzz)
Friends(実質Closed?)
wrld_xxxx:0000~friends~nonce(zzzz)
Invite+
wrld_xxxx:0000~private~canRequestInvite()~nonce(zzzz)
Invite Only(実質Closed?)
wrld_xxxx:0000~private~nonce(zzzz)

VRChat ワールド一覧 - beta のURL生成機能を参考にさせていただきました。
http://teruaki-tsubokura.com/vrchat/

なおこのインスタンスに関する法則性は起動時のワールド指定でも有効です。
(ワールドIDのみだとInvite Onlyで起動しますが、Publicに飛んだりできる)
Launch URL - Programming in VRChat
http://vrcprog.hatenablog.jp/entry/tips-Launch_URL

*「公式から提供されている機能を利用していますが、未保証な機能です」について
この機能は、VRChatのWebPanelに搭載されているJavascript API bindingsのGotoRoom機能を利用しています。この機能含め、Javascript API bindingsはマニュアルには乗っておらず、実際殆どが機能しません。GotoRoom機能は数少ない動作している機能の一つです。

UnityでVRC_Web Panelを設置して、ローカルのファイルを指定すると以下のような表示が現れます。

jmpC.png

以下意訳
「Javascript API bindingsを呼び出すには、engine.call('メソッド名',...)を使ってね。これはPromiseライクなオブジェクトを返すよ」
「ListBindings()を呼び出すと、利用可能なAPIを確認することができるよ」
「ページが読み込み完了してAPIが使えるようになったらonBindingsReadyイベントが発生するからlistenしてね」
(注: GotoRoomは単純な機能なのでonBindingsReadyイベントをチェックする必要はほぼ無いです)

というわけで、どうやらワールド製作者が利用することを最初から意図しているようです。
が、未完成なのでマニュアルに乗ってないものと推測されます。
posted by gpsnmeajp at 04:04| Comment(0) | TrackBack(0) | トラブル解決

2018年07月11日

VRChat向け小ネタシェーダー(FPS表示・テクスチャ切り替え)

VRChatやってると、ちょっと変なシェーダーが欲しくなることありますよね。
スクリプト使えないのでAnimatorでなんとかしなきゃいけなかったりして。

ちなみにすべてUnlitです。

FPS表示


現在のFPS(フレーム/秒)を表示します。
ちなみにシェーダーが動作している人のfpsが表示されるので、アバターに仕込むと見る人によって数値が違います。
showfps.png

ダウンロード↓
https://sabowl.sakura.ne.jp/gpsnmeajp/blog/FPSMonitorShader.unitypackage

・使い方
1.読み込みます。
fps1.png
2. Shaderフォルダができます
fps2.png
3.Materialを適当なオブジェクトに突っ込みます
fps3.png
fps4.png
4. fpsが表示できました
showfps.png
5.ちなみに、alpha値を設定すると半透明になります。

テクスチャ切り替え


モデルのテクスチャを切り替えます。
・2つをきっちり切り替えるやつ
(0か1かしかない)
switch2.png

・2つをスムーズに切り替えるやつ
(例えば0.5で2つのテクスチャが均等に混ざる)
switch2smooth.png

・8つをきっちり切り替えるやつ
switch8.png
の3種類あります。

ダウンロード↓
https://sabowl.sakura.ne.jp/gpsnmeajp/blog/TextureSwitcherShader.unitypackage

・使い方
1.読み込みます。
tex1.png
2. TexSwフォルダができます
tex2.png
tex3.png
3. 試しにこんなふうに設定してみると
tex4.png
0にするとこう
tex5.png
1にするとこうなります。
tex6.png
4.Animationでは、_Switch変数を操作すると同じことができます。
tex7.png
値を直でセットしてください。
tex8.png

シェーダーを始めるにあたって参考にした文献
https://docs.unity3d.com/jp/460/Manual/SL-BuiltinValues.html
https://qiita.com/sune2/items/fa5d50d9ea9bd48761b2
http://izmiz.hateblo.jp/entry/2014/02/23/223405
http://baba-s.hatenablog.com/entry/2018/01/09/090000
http://marupeke296.com/UNI_S_No2_ShaderLab.html
http://marupeke296.com/UNI_S_No3_SurfaceShader.html
http://www.suitechlog.net/entry/2017/12/11/190937
http://light11.hatenadiary.com/entry/2018/05/06/230414
https://qiita.com/moca_uni/items/4e71e423c84f830687f1
http://www.jonki.net/entry/20140209/1391944797
https://qiita.com/edo_m18/items/591925d7fc960d843afa
https://docs.unity3d.com/ja/current/Manual/SL-BuiltinFunctions.html
https://answers.unity.com/questions/192553/camera-forward-vector-in-shader.html
https://www.slideshare.net/kurisaka_konabe/20121208-unityhack-billboard
http://wordpress.notargs.com/blog/blog/2015/11/10/unity%E5%BA%8A%E5%B1%8B%E3%81%AE%E3%81%82%E3%82%8C%EF%BC%88%E3%82%B5%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%AB%EF%BC%89%E3%82%B7%E3%82%A7%E3%83%BC%E3%83%80%E3%83%BC%E3%82%92%E4%BD%9C%E3%81%A3/
https://qiita.com/edo_m18/items/d6a5a39e9b42da723663
http://ch.nicovideo.jp/tenoji/blomaga/ar1527951


ライセンス表記が必要な用途で使用する場合
MITライセンスとします。

MIT License

Copyright (c) 2018-2021 gpsnmeajp

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

posted by gpsnmeajp at 21:10| Comment(0) | TrackBack(0) | プログラム

2018年07月01日

#VRChat のログをHMDでも見たい時用PowerShellスクリプト

ワールドのデバッグ等々の際ログを見たくなりますが、HMDをかぶっているとうまく表示されないものです。
そこでWindows Power Shellを使って、VRChatのログを表示しましょう。
vvvlog.png

*注意
※製作者はWindows Power Shellは初心者です。
 これを実行したことによる損害等の保障は一切しません。
 スクリプトをざっと読んで何をするのか理解した上で実行してください。


*仕組み
VRChatのデバッグログファイル(%appdata%\..\LocalLow\VRChat\vrchat;output_log.txt)を
リアルタイムに読んでいるだけです。ので、チートとかには該当しないと思います。

VRChatのメニューキー+3とほぼ同じ情報が出ていると思います。

VRChatを長時間立ち上げ続けていると、ファイルが分割されて表示できなくなることがあります。
その際はVRChatを起動し直すか、コマンドのファイル名を修正してください。

*最も基本的な手順
1. Windows Power Shellを起動する(スタートメニューにあるはず)

2. 以下のコマンドを入力してEnter(長いが1行。コピペでどうぞ)

cat "$env:APPDATA\..\LocalLow\VRChat\vrchat;output_log.txt" -wait -Encoding UTF8 | ? {$_.trim() -ne "" } | % {$_ -replace "</?color.*?>",""}


コードの内容
・VRChatのログファイルの最新情報をUTF-8で常に読み込みながら
・空行を削除しながら
・Unity用のcolorタグを削除しながら
・画面に表示する

3. 出てきた画面をOVRDropなどを利用してVR空間に表示する

フォントサイズを大きくすると見やすくなります。
設定はPowerShellのタイトルバーを右クリックして出てきた設定から。

ログを止めたいときはScroll Lock
終了したいときはCtrl+Cか、PowerShellを閉じる。

*特定の文字を含むログを出したい場合
例えばIKを含むものの場合

cat "$env:APPDATA\..\LocalLow\VRChat\vrchat;output_log.txt" -wait -Encoding UTF8 | ? {$_.trim() -like "*IK*" } | % {$_ -replace "</?color.*?>",""}


例えばExecuting event(ワールドでのトリガなどの始動)を含むものの場合

cat "$env:APPDATA\..\LocalLow\VRChat\vrchat;output_log.txt" -wait -Encoding UTF8 | ? {$_.trim() -like "*Executing event*" } | % {$_ -replace "</?color.*?>",""}


例えばSwitching (プレーヤー名) to avatarを含むものの場合

cat "$env:APPDATA\..\LocalLow\VRChat\vrchat;output_log.txt" -wait -Encoding UTF8 | ? {$_.trim() -like "*Switching * to avatar*" } | % {$_ -replace "</?color.*?>",""}


*色をつける・音を鳴らす
長くて改行も含んでますが、コピペで入力してください
いろいろとワールド制作に便利そうなのを強調したりしてみています

cat "$env:APPDATA\..\LocalLow\VRChat\vrchat;output_log.txt" -wait -Encoding -last 5 UTF8 | ? {$_.trim() -ne "" } | % {$_ -replace "</?color.*?>",""} | % {
$msg = $_ -replace "</?color.*?>",""
if($_ -match "uSpeak"){
#uSpeakを含むとき表示しない
}elseif($_ -match "APIUser"){
#APIUserを含むとき表示しない
}elseif($_ -match "The referenced script on this Behaviour"){
#The referenced script on this Behaviourを含むとき表示しない
}elseif($_ -match "Can not play a disabled audio source"){
#Can not play a disabled audio sourceを含むとき表示しない
}elseif($_ -match "IK\[VRCPlayer"){
#IK[VRCPlayerを強調
Write-Host $msg -backgroundcolor DarkRed
}elseif($_ -match "Photon"){
#Photonを強調
Write-Host $msg -backgroundcolor DarkRed
}elseif($_ -match "OnPlayerJoined"){
#OnPlayerJoinedを強調
Write-Host $msg -backgroundcolor DarkCyan
[Console]::Beep(800, 100)
[Console]::Beep(4070, 100)
}elseif($_ -match "I am MASTER"){
#I am MASTERを強調
Write-Host $msg -backgroundcolor DarkCyan
[Console]::Beep(2000, 100)
}elseif($_ -match "Room"){
#Roomを強調
Write-Host $msg -backgroundcolor DarkCyan
}elseif($_ -match "OnPlayerLeft"){
#OnPlayerLeftを強調
Write-Host $msg -backgroundcolor DarkCyan
[Console]::Beep(300, 100)
[Console]::Beep(150, 100)
}elseif($_ -match "triggered"){
#triggeredを強調
Write-Host $msg -backgroundcolor DarkCyan
[Console]::Beep(500, 10)
}elseif($_ -match "OnOwnershipTransfered"){
#OnOwnershipTransferedを強調
Write-Host $msg -backgroundcolor Black
[Console]::Beep(400, 10)
}elseif($_ -match "Executing event"){
#Executing eventを強調
Write-Host $msg -backgroundcolor DarkGreen
[Console]::Beep(700, 10)
}elseif($_ -match "Preparation has taken"){
#Preparation has takenを強調
Write-Host $msg -backgroundcolor DarkGreen
[Console]::Beep(700, 10)
}elseif($_ -match "to avatar"){
#Switching * to avatarを強調
Write-Host $msg -backgroundcolor DarkCyan
[Console]::Beep(300, 10)
}elseif($_ -match "Warning"){
#Warningのとき
Write-Host $msg -foregroundcolor red
}elseif($_ -match "Exception"){
#Exceptionのとき
Write-Host $msg -foregroundcolor yellow
}elseif($_ -match "Error"){
#Errorのとき
Write-Host $msg -foregroundcolor Cyan
}else{
#Logのとき
Write-Output $msg
}
}


*入退室情報だけ表示する
長くて改行も含んでますが、コピペで入力してください

cat "$env:APPDATA\..\LocalLow\VRChat\vrchat;output_log.txt" -wait -Encoding -last 5 UTF8 | ? {$_.trim() -ne "" } | % {$_ -replace "</?color.*?>",""} | % {
$msg = $_ -replace "</?color.*?>",""
if($_ -match "OnPlayerJoined"){
#OnPlayerJoinedを強調
Write-Host $msg -backgroundcolor DarkCyan
[Console]::Beep(800, 100)
[Console]::Beep(4070, 100)
}elseif($_ -match "OnPlayerLeft"){
#OnPlayerLeftを強調
Write-Host $msg -backgroundcolor DarkCyan
[Console]::Beep(300, 100)
[Console]::Beep(150, 100)
}else{
#その他は表示しない
}
}

posted by gpsnmeajp at 04:22| Comment(0) | TrackBack(0) | プログラム