Avatar Series ― 自作の VRChat アバターを「シリーズ」にまとめて、VR の中から着替える
VRChat にアバターをアップロードしていると、同じ子の改変版やテスト版がどんどん増えていきます。
気づいたら自分のアバターが 199 体。名前もそのときの気分で付けているので ミルティナ、みるてぃな2、旧_ミルティナ、default-ミルティナ改 …… とバラバラで、VRChat の一覧から目当ての 1 体を探すのが大変でした。
そこで、自作アバターを 「シリーズ」 ごとにまとめて、シリーズから選んで着替えられるツール 「Avatar Series」 を作りました。 整理は Windows でじっくり、着替えは VRChat をプレイしたまま SteamVR のダッシュボード から。この記事では、どんな見た目で、どう動いて、中身はどうなっているのかをまとめます。
個人が趣味で作った非公式のツールです。VRChat とは関係ありません。 VRChat の公式に公開されていない API を使っているので、VRChat 側の変更で突然動かなくなることがあります。 パスワードは VRChat に送るだけで保存しません。
できること
- シリーズにまとめる:自分がアップロードしたアバターを、
ミルティナ・ショコラのようなシリーズに分ける。分け方は自分で決める - シリーズから着替える:シリーズを開いて、アバターを押すだけで着替え。いま着ているアバターには「使用中」の透かし
- 名前から自動でまとめる:ボタン 1 つで、名前の似ているアバターをまとめてシリーズにする(押したときだけ)
- 整理のおすすめ:表記ゆれのまとめ・改変版の切り分け・テスト用の非表示などを、1 件ずつ提案
- 表紙:シリーズの表紙を、自分の好きな画像か、好きなアバターのサムネイルにできる
- SteamVR のダッシュボード:VR の中で下のバーにアイコンが出て、そこから見て着替えられる
- irushia ランチャーに入っている:ランチャーのホームからそのまま開ける
シリーズの考え方

シリーズは「同じ子のバージョン違い」をまとめる箱です。たとえば ミルティナ シリーズと ミルティナ改変2 シリーズを分けておけば、元の子と大きく改変した子を別々に扱えます。
1 体のアバターは 1 つのシリーズにだけ入ります。お気に入りやタグのように「いくつにも入る」仕組みにはしていません。自分の作ったアバターを並べるだけなら、これがいちばん迷わないので。
画面は 2 つのモードに分けました。
| モード | できること |
|---|---|
| 着替え | シリーズを開いて、アバターを押すと着替える。ふだんはこっち |
| 整理 | アバターを選んでシリーズへ移す、シリーズを作る・名前を変える・まとめる・解散する |
着替えモードではアバターを押しても何も壊れないので、うっかり整理してしまうことがありません。

右上には自分の VRChat のアイコンと名前、「○○を着用中」が出ます。押すとメニューが開いて、ここからログアウトもできます。
アバターのカードの PC Quest iOS は、そのアバターがどの機種向けにアップロードされているかです。
名前から自動でまとめる
最初は 199 体が全部「未分類」です。1 体ずつシリーズに入れていくのは大変なので、「名前から自動でまとめる」 ボタンを付けました。
名前をそのまま比べると表記ゆれで全然まとまらないので、比べる前に名前を「同じ子なら同じになる形」に直しています。
- 全角・半角や大文字・小文字をそろえて、カタカナはひらがなに(
ミルティナ→みるてぃな) - 先頭の
旧_、default-のような飾りを外す -_:や空白で区切って、最初のかたまりを取る- 最後のバージョン番号(
2、v3など)を外す
こうすると ミルティナ2・みるてぃな-改・旧_ミルティナ が全部 みるてぃな になって、1 つのシリーズにまとまります。
ただ、自動でまとめた結果が自分の思う分け方と違うことも多いです。最初は同期のたびに自動でまとめていたんですが、自分で整理した分け方を崩されるのがいやだったので、ボタンを押したときだけ にしました。 一度シリーズにした名前は覚えておいて、あとから同じ名前のアバターをアップロードしたときは、同期のときにそのシリーズへ自動で入ります。
整理のおすすめ
自動でまとめきれないところは、「整理のおすすめ」 が 1 件ずつ提案します。
| 提案 | 例 |
|---|---|
| シリーズをまとめる | みるてぃな と Miltina が別のシリーズになっている → まとめる? |
| シリーズへ入れる | 未分類の みるてぃなv4 → みるてぃな シリーズへ? |
| 新しいシリーズにする | 未分類で名前の似たアバターが 3 体 → シリーズにする? |
| 改変版を切り分ける | シリーズの中に ミルティナ2-… のような番号付きの名前がまとまっている → 別のシリーズにする? |
| テスト用を隠す | test の入った名前や、a・aaa のような名前 → 非表示にする? |
ひらがなとローマ字の表記ゆれ(みるてぃな と Miltina のような)は、読みをローマ字にしてから比べています。みるてぃな は mirutina、Miltina は l を r にそろえて mirtina。母音を落とした子音の並びはどちらも mrtn で、ローマ字の違いも 1 文字なので「同じ読み」とみなします。
提案は右のボタンを押せばその場で反映、違っていれば「無視」で消せます(あとから戻すこともできます)。
整理モード

整理モードでは、アバターのカードを押すと選択になります。何体か選んで、下のバーから
- シリーズへ移動:ほかのシリーズへ
- 新しいシリーズに:選んだアバターで新しいシリーズを作る
- 非表示:使わないアバターを一覧から隠す(VRChat からは消えません)
シリーズの上のボタンで、名前の変更・ほかのシリーズを取り込む(2 つのシリーズを 1 つに)・表紙の変更・解散ができます。
表紙

シリーズのカードの表紙は、ふだんは いちばん新しいアバターのサムネイル です。 でも、新しいアバターがテスト中の変なアングルだったりすると表紙がいまいちになるので、自分で決められるようにしました。
- 画像ファイルを選ぶ:好きな画像(PNG・JPEG・WebP・GIF)を表紙にする
- アバターから選ぶ:そのシリーズのアバターのほか、「すべてのアバター」に切り替えればほかのシリーズのアバターも選べる
- 自動に戻す:いちばん新しいアバターに戻す
デザイン

見た目は 黒い光沢と、後ろを流れる光の波。PS3 の XMB や Xbox 360 のころのゲーム機のメニューのイメージです。
じつは最初、「昔の Windows Vista みたいなモダンに」と思って Aero 風のガラスで作ってみたんですが、できあがったものは「Windows の安っぽいまね」にしか見えませんでした。 欲しかったのは Windows の部品の再現ではなくて、あのころの 黒くてつやつやして、奥で光がゆっくり流れている 雰囲気。なので Windows の部品っぽさは全部やめて、
- 背景は濃い紺〜黒のグラデーションに、細い線でできた 光の波(canvas で描いて、ゆっくり揺らす)
- カードやパネルは、上がほんのり明るい黒の 光沢。ふちに細いハイライト
- 選んでいるカードは白く光る
- シリーズのカードは、後ろに 同じシリーズのほかのアバターが重なっている ように見せて「束」っぽく
にしました。ボタンも最初はつやの境目がくっきりした丸いボタンにしていたんですが、これも安っぽかったので、境目のない控えめな光沢に作り直しています。
「使用中」の透かしは、カードの真ん中に細い線と字間の広い文字で。サムネイルの上に乗っても顔を隠しすぎないように、文字は半透明にしています。
SteamVR のダッシュボード

いちばんやりたかったのがこれです。VRChat をプレイしながら、SteamVR のダッシュボード(コントローラーのシステムボタンで出る画面)の下のバーに Avatar Series のアイコンが出て、押すとシリーズの一覧が開きます。レーザーポインターでシリーズを開いて、アバターを押せばそのまま着替え。
VR の中では整理しないので、整理・検索・おすすめ・ログアウトは出しません。文字は少し大きめにして、後ろの光の波は止めています。
しくみはこうなっています。
| 役目 | |
|---|---|
| ランチャー(Electron) | 画面の外にもう 1 枚、VR 用の画面(1280 × 800)を描いて、その画像を 30 fps で送る。ダッシュボードが開いているときだけ |
VR ヘルパー(AvatarSeriesVR.exe) |
C# で書いた小さな exe。SteamVR(OpenVR)にダッシュボードを登録して、受け取った画像を表示する。レーザーのクリックやスクロールはランチャーへ送り返す |
ヘルパーは .NET の NativeAOT で 1 つの exe にしているので、.NET を入れていない PC でも動きます。 SteamVR を勝手に起動しない のもこだわったところです。ヘルパーはまず「SteamVR が動いているか見るだけ」のつなぎ方で確かめて、動いているときだけダッシュボードに出ます。SteamVR を閉じるとヘルパーも静かに止まって、次に SteamVR を起動したらまた出てきます。
ハマったところ:クリックした瞬間に消える
最初の版は、ダッシュボードには出るのに 押した瞬間に消える という状態でした。 原因は、画面の外で描いている VR 用の画面が、ダッシュボードを閉じたり開いたりするタイミングで一瞬 0 × 0 ピクセルの画像 を送っていたこと。ヘルパーがそれを「壊れたデータ」と思って終了していました。 テスト用のにせのヘルパーでは問題なく動いていたので、本物の SteamVR で試すまで気づけませんでした。いまは両側で空の画像を飛ばすようにしています。
ハマったところ:動かすとチカチカする
次は、スクロールしたりカーソルを動かしたりすると 画面が点滅 しました。
OpenVR には「画像のピクセルを直接渡す」いちばん簡単な関数(SetOverlayRaw)があるんですが、これは呼ぶたびに中で新しい画像を作り直していて、作り直しの途中が一瞬映っていました。
そこで、GPU(Direct3D 11)のテクスチャを 2 枚用意して、交互に書き換えて渡す ようにしました。片方を SteamVR が表示している間に、もう片方に次の画像を書く形です。これで点滅は出なくなりました(ヘッドセットで確認)。
しくみ:ランチャーへの組み込み
Avatar Series は最初、C# だけで作った単体のアプリでした。それを irushia ランチャー に入れるために、Windows 側の中身を全部 JavaScript(Node.js)に書き直しています。 ランチャーは Electron なので、同じ中で動かせばメモリも余計に食わず、ランチャーを起動していればいつでも開けます。VR に表示するところだけは C# のまま、上の「VR ヘルパー」として残しました。
| 中身 | |
|---|---|
| 画面 | HTML / CSS / JavaScript。ランチャーの中に avatarseries:// という専用のアドレスで表示 |
| データ | シリーズの分け方・表紙・非表示などは SQLite(Electron に入っている Node.js の node:sqlite)に保存 |
| ログイン | VRChat のログイン状態(Cookie)だけを、Windows の機能(DPAPI)で暗号化して保存。パスワードは保存しない |
| サムネイル | 一度取ってきたサムネイルは PC に保存して、2 回目からはすぐ出る |
| VRChat との通信 | 自分のアバターの一覧を取る・着替える、の 2 つだけ。同期は 1 分に 1 回まで |
C# 版で整理したデータがあれば、ランチャー版を最初に開いたときに 1 回だけ引き継ぎます。ログイン状態も引き継ぐので、ログインし直す必要はありません。 ランチャーの irushia アカウントからログアウトすると、VRChat のログインも一緒に消えるようにしています。共用の PC でも VRChat のログインが残らないように。
ハマったところ:数分でログアウトされる
ランチャー版にしてから「ログインしたのに数分で勝手にログアウトされる」ことがありました。 原因は、ログイン状態の確認が重なったときに「失敗した確認の結果」を使い回してしまう、という小さな順番の問題でした。 しかも「ログアウトした状態から始めたとき」だけ起きるので、開発中の PC(ずっとログインしたまま)では再現しなくて、見つけるのに時間がかかりました。
ほかにも、VRChat の API でユーザーのアイコンが入っているのは userIcon ではなく iconUrl のほうだったり(userIcon は空のことが多い)、細かいところでいくつかつまずいています。
使い方
- irushia ランチャーのホームにある Avatar Series を開く
- VRChat のアカウントでログイン(2 段階認証にも対応)
- 「同期」で自分のアバターを取ってくる
- 整理モードでシリーズに分ける(「名前から自動でまとめる」と「整理のおすすめ」を使うと早いです)
- あとは着替えモードか、SteamVR のダッシュボードから着替える
Avatar Series は irushia ランチャーの次の更新で入る予定です。