tmytのらくがき

個人の日記レベルです

VRChatアバターのモーションを非破壊に差し替えるやつを作りました

VRChat楽しんでますか?僕はぼっちなのでBoothで衣装を買って、Unityで着せ替えを楽しんで、時々散歩に出かけるのと、ラジオ体操をするぐらいです。

2年ぶりの投稿がこれでいいのか一瞬悩まなかったわけでもないんですが、気にしたら負けな気がするので気にしないことにしました。

tl;dr

  • アバターのPlayable Layerに設定されているAnimatorに含まれるMotionを差し替えるNDMFプラグインを作ったよ
  • VCCから導入できるよ、URLはここ https://tmyt.github.io/vpm/
  • GameObjectを置いて、Avatar Motion Changer というComponentを設定してつかってね

前置き

さて、アバターのモーション*1を差し替えたいことが時たまあります。 具体的には、AFKを別なものに変えたり、ジャンプモーションを変えたり、ハンドサインに割当たっているモーションを変えたりでしょうか。

これらの変更をするにはアバターに付属しているAnimatorを複製して編集してアバターに設定という手順を踏まないといけないです*2。 ただ、Animatorを複製して編集みたいなのはできればやりたくないのでNDMFの力でPlayable LayerのAnimatorに設定されているMotionを差し替えるやつを作ってみました。

導入方法と使い方

VCCから簡単導入できるようにしてみました、手元のVCCと友人にやってもらった限りインストールできているので多分あってると思います。 次のページからAdd to VCC してVCCから、Avatar Motion Changer というのをインストールしてください。Non-Destructive Modular Framework が必要ですが、Modula Avatarがインストール済みであればすでに入っています。

tmyt.github.io

VCCからパッケージがインストールできたら、実際にアバターに組み込んでいきます。 今回は、ぽんでろさんのしなのちゃんに、フカさんのしなのちゃんの手でしょりしょりするやつを設定してみます。 アバターなどのUnity Packageはすでにインポートされている状態とします。

booth.pm

booth.pm

まずGameObjectをアバターの配下に追加し、そのGameObjectにAvatar Motion Changerというコンポーネントを追加します。*3

List is Empty と出ている近くの+ボタンを2回押します。すると項目が2個増えるので、ドロップダウンからいい感じに設定します。Animationのところは、設定したいMotion、ここではFUKA_Fist_Triggerをドロップします。

あとはプレイボタンを押すとか、アバターをアップロードするときなどのビルド時に自動でモーションが差し変わります。 もとのAnimatorも変更されないのでアバターのプレハブが更新されたときも基本的に気にしなくていいはず…です。

制約事項

  • Playable Layerに対するAnimatorが未設定の状態のものはこのコンポーネントから設定することはできません。将来的にできるようになるかもしれないですが、そもそも使うことがなさそうなので対応は未定です。
  • StateのMotion以外のパラメータの設定には現時点では対応していません。どうしても必要になったら対応するかもしれないですがこちらも使わなさそうなので対応は未定です。

その他

  • ひとつのGameObjectに複数つけても正しく動くように作っているはずですがテストしてないので本当に動くかはわかりません。
  • オリジナルのデータが変更されていないこと・Play時の一時ファイルでのみ変更されていること・アップロードしたアバターでは変更が反映されていることは十分に確認していますが、100%オリジナルデータが安全という保障はできないので各自バックアップは撮ってください。

おわりに

モーション入れ替えがとても簡単になるのでみんな使ってみてね!*4

それと、こういうの設定できたよ!これが設定うまくできないよ!みたいなのがあったらこそっと教えてください

*1:ここで指すモーションは、Playable Layerに設定されているAnimatorのStateMachine内に設定されているAnimation Clipを指します

*2:たぶんそう。本当にそうなのかはわからないけどみんなAnimator編集するって書いてるからたぶんそう

*3:アバター配下のどこかにComponentが設定されていれば動くので追加しなくても大丈夫ですが、後から見た時にわかりやすいのでとりあえず追加します

*4:そもそもこれを使うシーンが多分ほとんどない

Keychron Q65が届いた

Keychron Q65というキーボードがDHLで届いたのです。

5月ごろにGroupBuyやっていてそれがついに届いたという感じです。ちなみに昨日までは売り切れ表示だったんですが、今(2022年11月23日)みたところ在庫あり表示になっているので今すぐ買えますね!!!!

Keychron Q65 QMK Custom Mechanical Keyboardwww.keychron.com

組み立てるのも楽しいんですがキーキャップ選び出すと沼にはまるのでFully Assembled Knobにしました。

第一印象はめっちゃ重い(物理)なんか2.4kgあるらしいです。2リットルペットボトルより重たい…安定感抜群ですね…

そんでもってめっちゃ光る。USBケーブル接続した瞬間めっちゃ光る。虹色に波打っててゲーミングみたいでした。

このキーボードの気に入っているポイントは左側にノブとM2~M5キーがあることです。Knob Versionっていうぐらいなんだからそりゃそうかという感じですがノブがあります。

しかも、VIAでカスタムできるのも楽しいポイントでした。VIAってすごいんですね、リアルタイムで反映されるし自動で永続化されるし…

VIAで1個だけわからなかったのが、Altを押してESCを押したときはESCじゃなくてGrave*1を出力するようにしたいけどこれをどうしていいかわからなかった。

QMKにはGrave Escapeという機能があってこれを使うと似たようなことができる…けどこれはShiftかGUI*2とESCを押したときにESCじゃなくてGraveになる機能…らしい…*3

このためにレイヤ1枚使うのももったいないしなぁ…とおもってしばらく使ってたらふとQMK改造すればいい!!オープンソース最高!!となってGrave Escapeの機能を改造することにしました。

Grave Escape改造

Grave EscapeがShift or GUIでGraveになるESCから、AltでGraveになるESCに改造したメモ。

DockerでDebianを起動してやります。

# 環境設定
docker run -it --rm debian
apt update
apt install -y sudo zlibg1-dev libjpeg-dev git python3-pip vim
python3 -m pip install qmk
qmk setup Keychron/qmk_firmware

お好きなエディタでここを編集する

diff --git a/quantum/process_keycode/process_grave_esc.c b/quantum/process_keycode/process_grave_esc.c
index ddf02739..17c12a1a 100644
--- a/quantum/process_keycode/process_grave_esc.c
+++ b/quantum/process_keycode/process_grave_esc.c
@@ -23,7 +23,7 @@ static bool grave_esc_was_shifted = false;
 bool process_grave_esc(uint16_t keycode, keyrecord_t *record) {
     if (keycode == QK_GRAVE_ESCAPE) {
         const uint8_t mods    = get_mods();
-        uint8_t       shifted = mods & MOD_MASK_SG;
+        uint8_t       shifted = mods & MOD_MASK_ALT;
 
 #ifdef GRAVE_ESC_ALT_OVERRIDE
         // if ALT is pressed, ESC is always sent
# いい感じにビルドする
make keychron/q65/q65_ansi_stm32l432_ec11:via

ここまでやって、出来上がったbinを焼いたらOKでした。

焼き方はスペースバーを外すとスイッチの左側にDFUに入るスイッチがあるので、それをUSBケーブルを指すとDFUモードになってQMK Toolboxでファームが焼けるようになります。

焼き終わった後、Fn+J+Zを4秒くらい押してEEPROMをファクトリリセットしておくといいそうです。

*1:つまりバッククオート

*2:WindowsでいうところのWindowsキーMacでいうところのCommandキー

*3:ドキュメントを読むともちろんそう書いてある

Windows 開発キット 2023っていうの買いました

Windows 開発キット 2023 っていうやつを買いました。DevKit 2023のほうが呼びやすくていいですね。

BUILDでProject Volterraとして発表されたやつがようやく販売開始した感じなんですが、日本も対象でびっくりしました。*1 販売開始当初、Microsoft Storeで99万とか99円とかで一瞬話題になりましたね。

www.microsoft.com

10月26日に在庫が復活したので注文したところ、価格設定ミスってたこともあって発送がぐちゃぐちゃになっていたらしく配達予定は28日でしたが実際届いたのは11月1日でした。

スペックを引用しておくとこんな感じだそうです。

- 32GB LPDDR4x RAM and 512GB fast NVMe storage
- Snapdragon® 8cx Gen 3 compute platform
- Ports: 3x USB-A, 2x USB-C, Mini-Display (HBR2 support), Ethernet (RJ45)

あとから知ったんですが、実装RAMが32GBなことにびっくりしました。

感想

Arm64で動くWindowsなだけでなんも変わらないですね…  Snapdragon 8c以降はCPUが仮想化対応になったのでHyper-Vも動きます。Hyper-Vが動けばWSL2も動きます。

ソフトウェア面では、最近はVSCodeもArm64で動くし、Visual StudioもまだPreviewですがArm64で動作します。 2019年頃はまだx86エミュレーションで実行されていたOfficeやOneDriveも今ではArm64で動くようになりました。3年前よりArm64でコンパイルされたバイナリもかなり増えてきた印象です。

SlackやDiscordのようなサードパーティーのアプリケーションはArm64版Windowsバイナリを提供してくれないことが多くエミュレーションで実行されます。ただ、Arm64上のバイナリエミュレーションはそれなりにはがんばるので心配するほどは遅くないです。*2とはいえ、エミュレーションのChromiumとv8で動作するElectronよりはブラウザでアクセスしたほうが速いかもしれません…*3

x86エミュレーションでADBも使えるのでAndroidデバッグできます。*4

Seeeduino Xiaoを接続したところ、ちゃんとシリアルデバイスとして認識され、Arduino IDEコンパイルから書込みまで成功しました。

最近はデバイスドライバ周りもUniversal対応になっているものが増えてきたので、C630を買ったころよりはるかに環境が整備されました。

おもしろポイント1

おもしろポイント1は、Arm64でWindows動作しているのでWSAももちろんArm64で動作します。

[ro.product.cpu.abi]: [arm64-v8a]
[ro.product.cpu.abilist]: [arm64-v8a,armeabi-v7a,armeabi]
[ro.product.cpu.abilist32]: [armeabi-v7a,armeabi]
[ro.product.cpu.abilist64]: [arm64-v8a]

Arm64でWSAが動くメリットは、Unityのil2cppでコンパイルされたバイナリがx86_64版のWindowsより安定して動いている感がありました。あと心なしか動作が早い気もする、ただ計ったわけではないです。

ただ考えてみるとArm64で動いてるWSAって、それHyper-Vで仮想化されてるただのAndroidやん……という話なのでそりゃはやいじゃんという話ではあります。

おもしろポイント2

おもしろポイント2は、中身はほとんどSurfaceだそうです。たぶんSQ3のSurface Proから画面とモデムと電池をとっぱらった結果なんじゃないでしょうか。

UEFISurfaceのものが動いているようなのですが、USB-Cで接続するとUEFI画面が表示されないのでどんなのが出ているのでしょうか… miniDP to HDMIなアダプタが手に入ったら確認してみます。

そのほか

セットアップはさすがにリモートではできない…のだけど余っているディスプレイはないので数年前に流行ったHDMIをUVCで接続できる2000円ぐらいのアレ*5で画面をみてたんですがやっぱしまぁまぁ便利ですね。1個持っとくといい。

キーボードとかの接続もめんどくさかったのですが、LenovoThinkPad トラックポイント キーボード IIが2.4GHz無線とBluetoothのデュアルスタックなのでこういう時に1枚持っていると便利でした。*6

OOBEはネットワークが必須になったバージョンでした。ローカルアカウントを1回作りたい派なので、Shift+F10で OOBE\BYPASSNRO してI get kotonakiです。

このあとMSAログインに切り替えたのですが、その時にパスワードログインが無効になってしまうので有効にしたあと一度パスワードでログインしてあげないとリモートからログインできませんでした。地味にはまりポイントです。

あと結構謎な動きをしたのが、Final Fantasy XIV 暁月のフィナーレベンチマーク(x64バイナリ)を実行したところ、ベンチマークシーンの開始5秒付近でなぜかマシンがリセットしてしまいます。イベントログを見ると、予期しないシャットダウンでした。ということなので予期しないシャットダウンらしいのですがなんのこっちゃわかりません。エミュレーションの過程で変な命令とか叩いてうっかり死んでしまったのでしょうか。そもそも動作対象外の環境なのでこれ以上は詳しく調べることはしませんでした。

このPCはここまでの設定をしたのちに、電源ケーブルだけ接続された状態で部屋の隅に押し込まれたのでした…

*1:前のSnapdragon DevKitって言ってたやつは北米だけだったはず

*2:Ryzen 9 4950XみたいなハイエンドCPUと比較するともちろん遅いです。

*3:ちなみに、2022年11月現在ChromeもArm64版が提供されていません。EdgeはArm64ネイティブなのでChromeを使うよりはEdgeを使ったほうが速いですね

*4:もちろん、WSAで動作している自分自身にもadb接続できます。

*5:https://www.amazon.co.jp/dp/B0936Q2G5G/

*6:今思えば何も考えずに接続したけど普通に使えてました。ドライバ大丈夫かな…とか何も考えてなかった

スマホ同期 あらため、電話リンク

WindowsAndroidを接続して通知とかが見られるようになる、スマホ同期(英語だとYour Phone)がWindows 11になってもうちょっと便利になったよ。というのは見ていたけど一回も使ったことなかったので使ってみたら結構おもしろいし便利だったし、実装も面白い感じだったのでまとめておきます。

そもそも何

WindowsからAndroidに接続して通知がみれる、SMSの送受信ができる。一部の機種では画面の転送とか電話の発着信もできる。

一部の機種というのは、ここに書いてあって、 Surface Duoシリーズと、Galaxyシリーズだけ。GalaxyなのはSamsungとがんばって作ってますよ、ということだから。

さらに、最新の機能を使うにはGalaxyの最近の機種か、Surface Duo 2じゃないとだめ。そうSurface Duo 2を買ったから試そうと思ったのでした。

画面転送

画面転送がアプリ単位でできます。これがわりと便利でおもしろい。

例えば、Panasonicのシーリングを操作してみたり f:id:tmyt:20220406221535p:plain

プリコネグランドマスターズをプレイしたり f:id:tmyt:20220406221723p:plain

ToDoを書き込んでおいたり

f:id:tmyt:20220406221801p:plain

というのが、Windows上から同時に起動できます

f:id:tmyt:20220406222127p:plain

Google Chat入れてないなってPlayストアからインストール中の図 f:id:tmyt:20220406222344p:plain

アプリはWindows側から起動できて、電話リンクにアプリ一覧が出てきます。

f:id:tmyt:20220406222722p:plain

ここから選ぶと、アプリが立ち上がって専用のウィンドウとして表示される。さらにこのアプリはスタートメニューとタスクバーに登録ができる(!!)

f:id:tmyt:20220406222824p:plain

タスクバーにもちゃんとAndroid側のアイコンで表示される(!!)めっちゃすごい…すごいがんばって実装されている…

f:id:tmyt:20220406222851p:plain

使ってみた感想

たくさん開くとだめらしいです。Surface Duo 2では7個?が上限らしい。

f:id:tmyt:20220406223400p:plain

ゲームが快適に遊べるほどのフレームレートでは転送されてこないです。プリグラぐらいなら遊べた。

気になるのがどうやって実装されているのかな。というところ。わかる範囲で挙動をみてみたところ、アプリごとのセカンダリディスプレイが起動しているようです。

display?.displayId?.toString() // とかすると、20以上の値がGetできる

なので、サポートされてる機種じゃないとアプリ単位での転送ができないってことらしいです。

アプリごとのディスプレイを作ってるので、Windows側から比較的柔軟に制御できるのかーかしこいなー、なんて。

メールがみれたりしてちょっと便利なのと、Androidでしか動かないアプリを起動できてちょっと便利なぐらいでたいていはWindowsでもできるので劇的にこれが便利!!!ってことはないかもしれない。ただ知っておくとたぶんすごく便利。

あと、接続中はすごい速度で電池が減っていくのでいらないときは通知パネルからOffにしておくとなおよし。

f:id:tmyt:20220406232551p:plain

スマホ同期 あらため、電話リンク

WindowsAndroidを接続して通知とかが見られるようになる、スマホ同期(英語だとYour Phone)がWindows 11になってもうちょっと便利になったよ。というのは見ていたけど一回も使ったことなかったので使ってみたら結構おもしろいし便利だったし、実装も面白い感じだったのでまとめておきます。

そもそも何

WindowsからAndroidに接続して通知がみれる、SMSの送受信ができる。一部の機種では画面の転送とか電話の発着信もできる。

一部の機種というのは、ここに書いてあって、 Surface Duoシリーズと、Galaxyシリーズだけ。GalaxyなのはSamsungとがんばって作ってますよ、ということだから。

さらに、最新の機能を使うにはGalaxyの最近の機種か、Surface Duo 2じゃないとだめ。そうSurface Duo 2を買ったから試そうと思ったのでした。

画面転送

画面転送がアプリ単位でできます。これがわりと便利でおもしろい。

例えば、Panasonicのシーリングを操作してみたり f:id:tmyt:20220406221535p:plain

プリコネグランドマスターズをプレイしたり f:id:tmyt:20220406221723p:plain

ToDoを書き込んでおいたり

f:id:tmyt:20220406221801p:plain

というのが、Windows上から同時に起動できます

f:id:tmyt:20220406222127p:plain

Google Chat入れてないなってPlayストアからインストール中の図 f:id:tmyt:20220406222344p:plain

アプリはWindows側から起動できて、電話リンクにアプリ一覧が出てきます。

f:id:tmyt:20220406222722p:plain

ここから選ぶと、アプリが立ち上がって専用のウィンドウとして表示される。さらにこのアプリはスタートメニューとタスクバーに登録ができる(!!)

f:id:tmyt:20220406222824p:plain

タスクバーにもちゃんとAndroid側のアイコンで表示される(!!)めっちゃすごい…すごいがんばって実装されている…

f:id:tmyt:20220406222851p:plain

使ってみた感想

たくさん開くとだめらしいです。Surface Duo 2では7個?が上限らしい。

f:id:tmyt:20220406223400p:plain

ゲームが快適に遊べるほどのフレームレートでは転送されてこないです。プリグラぐらいなら遊べた。

気になるのがどうやって実装されているのかな。というところ。わかる範囲で挙動をみてみたところ、アプリごとのセカンダリディスプレイが起動しているようです。

display?.displayId?.toString() // とかすると、20以上の値がGetできる

なので、サポートされてる機種じゃないとアプリ単位での転送ができないってことらしいです。

アプリごとのディスプレイを作ってるので、Windows側から比較的柔軟に制御できるのかーかしこいなー、なんて。

Surface Duo 2を買いました

Surface Duo 2が日本国内で発売が始まって2か月半ぐらいが経ちました。突然思い立ってSurface Duo 2を買ったのでした。

初代Surface Duoと比べるとこんな感じ。左が2、右が1。

上下ベゼルが少し狭くなって画面の縦幅が少し大きくなりました。ヒンジ側のベゼルも少し小さくなってますね。全体的によくなったと思います。

f:id:tmyt:20220330141722p:plain

初代と比べて

よくなったところ

  • ディスプレイが90Hzになった
  • 指紋センサが電源ボタンと統合された
  • フラッシュライトが背面に移設された
  • NFCがついた
  • 背面にカメラがついた
  • 工作精度があがった
  • SD888速い
  • 開け閉めのフィーリングがよくなった
  • 閉じたときに若干楔形になるようになって保護シート貼ってもちゃんと閉まるようになった(気がする)
  • 5Gは…まぁあればうれしいかな…

いまいちなところ

  • カメラがダサい…
  • ちょっと高い

まとめ

よくなったところは書いてある通りで、とてもよくなりました。ディスプレイは滑らかだし、電源と指紋センサの位置がバラバラでいまいちとか思わなくなったし*1

NFC搭載はVISAタッチがGoogle Payで使えるようになったので*2、ついにSurface Duoだけでも決済できるようになったか!というインパクトがありとてもいいです。実際に何回かコンビニで使ってますが、画面を開かなくても電源ボタンを押して指紋認証だけ通してしまえば決済できるのでとても便利でした。

フラッシュライトが外側についたので、誤ってフラッシュライトをONにして目つぶしを食らわなくなったのも大きいです。

一方で、外側にカメラが付いたのはまぁいい感じなんですが、3眼のそこそこなカメラが付いたので見た目がやばいですね…開いて裏返すとこんな感じに…

f:id:tmyt:20220330142718p:plain

Surface Duo 2って結構薄い*3のでディスプレイモジュールの裏にさらにカメラモジュール載せるとこの厚さ*4にしかならなかったんだよ。と言われればそうかもしれない。けどおさめてほしかったなぁという気持ち。

カメラ部分が上部だけなので、完全に開いたときに下側に空間があるのでちょっと力をかけると曲がってしまう、もしかしたら割れるんじゃないかみたいな怖さがあります。

Duo 1のころは、画面を外に折り返したままポケットに突っ込むみたいなこともしばしばあったのですが、さすがにこの状態だと不意に力がかかって画面われそう…となるのでちゃんと閉めるようになりました。もしSurface Duo 3が出るのであればぜひカメラは収まるようにしていただきたいですね。

*1:最初指紋センサだった場所に触って動かんな。みたいなのをよくやりました

*2:https://www.smbc-card.com/brand/googlepay_visa/index.html

*3:5.5mm

*4:カメラが楔形になってるので最薄部で約8mm

Cloudflare WorkersでTwitter通知を作った

いままでIFTTTを使ってTwitterからDiscordへ通知していたのだけれど、Discordへの反映がとても遅い。最大1時間遅れでやってくる。しかも最近は3個までしか登録させてくれない。

そんな時にCloudflareを眺めていたらWorkersはスケジュール実行できますよ、と書いていたのでささっと通知するスクリプトを書いてみた。

gist.github.com

  • 環境変数のAPP_TOKENにTwitterのBearerトークンを入れる。
  • KeyValueを作って、KVという名前で登録する。
  • KyeValueに3つの値を入れる
キー
SID_{screenname} 0
UID_{screenname} ユーザの数値ID
WEBHOOK_{screenname} DiscrodのWebhookURL

これを設定してCronで1分にしておけばOK。毎分Twitterをクロールして更新があったらDiscordに素早く通知がくるようになりました。

Cloudflare Workers

こんな使い方をしていても今のところ無料。無料枠だと、1日に10万リクエストしか使えない。ということになっているのだけれど、どうやらこれはHTTPハンドラが呼び出された回数しかカウントされていないみたい。

今回みたいにスケジュール実行しか使ってないとカウントもされていなさそう*1だし、1回の実行が10ms*2を超えなければ何やっても大丈夫*3。AzureとかGCPとか使うより確実に安いし早いし楽だしこれはいい…

*1:少なくともリクエスト回数見てる限りそういうカウントがされていそう

*2:ただしこの10msにはI/Oをawaitしている時間は含まれていないので実際のところ案外長く実行できる

*3:たぶん