LoginSignup
2

More than 1 year has passed since last update.

VRChatでOSCを使ってケモ耳をアナログ時計にした

Last updated at Posted at 2022-05-26

はじめに

アバターの耳をアナログ時計にしてみたかったのでしてみました。簡単に手順を紹介します。各種用語の説明についてはリンク先をご覧ください。

できたもの

アホ毛を引っ張ると両耳で時刻を教えてくれます。アホ毛を固定するとそのまま時刻を表示しつつけ、元の位置に戻すと解除されます。

誰向け

  • このアホ毛耳時計がどうやって実現されているのかなんとなく知りたい人
  • Avatars 3.0PhysBonesがちょっとわかる人
  • Animatorを組むときにWriteDefaultsの挙動がちょっとわかってる人向け
  • ちょっとコード書ける人
    • 本記事では簡単なOSCクライアントをgolangで実装しています
    • golang以外で実装したい人はOSC Overview - VRChatを参考にしてください。

用意したもの

  • lyuma/Av3Emulator v2.9.8
    • ダウンロードしてUnityPackageをProjectフォルダーにD&Dすると導入できます
  • VRChat v2022.2.1
  • Unity 2019.4.31f1
  • VRCSDK3-AVATAR-2022.05.04.17.47
  • Golang1.16

手順

大まかな手順は下記の通りです。

  1. アホ毛を引っ張れるようにする
  2. VRChatのExpressionMenuから耳を操作できるようにする
  3. 時刻をOSCでVRChatに送る
  4. タスクスケジューラーにOSCクライアントを登録する

アホ毛を引っ張れるようにする

アホ毛をお持ちの方はアホ毛に下図のようにPhysBonesを追加しMaxStretchOptionsのParameterとIs Animatedを指定します。
image.png

Editorの再生ボタンを押して、アホ毛が固定できることを確認します。また、Optionsで指定したパラメーター(今回の場合ahoge)からahoge_Stretchが生成されます。
このパラメーターはPhysBone AV3 Parametersと呼ばれ、VRCExpressionParametersのように定義しなくてもローカルとリモートで同期されます。
image.png

VRChatのExpressionMenueから耳を操作できるようにする

ExpressionParameterから操作できる必要はないのですがデバッグ用です。

FXLayerに時計用のアニメーションを追加する

Playable Layers FXを読む限り、耳は非HumanoidBoneであることとFXLayerは(おそらく)GestureLayerの非ヒューマノイドボーンのTransformを上書するという点からFXLayerで耳のTransfomのAnimationさせるのでよさそうです。

Animatorの作成

まずは下図のようにAnimatorのParametersに先ほど生成したahoge_Stretchと時計の時と分のためのParameterを追加します。
image.png

次に左耳用と右耳用の空のアニメーションを作成し、下図のように左耳と右耳用のAnimatorを組みます。私の環境ではFXLayerはすべてWriteDefaultがOnなのでWriteDefaultをOnにしています。Offの人はNewStateでデフォルトの耳のアニメーションを作り追加しましょう。
また、Layersの上から下の順にanimationが実行され上書されることに注意が必要です。
image.png

Transitionは下図のようになっています。
image.png

image.png

animationの作成

下図のようにFXLayerのコントローラーをAnimatorのContollerに設定します。
image.png

HierarchyでAnimatorコンポーネントがついたGameObjectを選択し、Animationタブを開くと、FXLayerのAnimation
一覧がでてくるので先ほど作った空のアニメーションを選択します。その後、いい感じに60フレーム分(0~59)のアニメーションを作成します。また、Animationで耳の長さを変えたい場合は、回転させるボーンの子のボーンのPositionを移動させるのが良いです。
image.png

デフォルトだと回転の仕方が滑らかなので線形にします。keyframeを右クリックしてLinearを指定します。カーブの編集 - Unity マニュアルが参考になります。
image.png

右耳のAnimationも同様に作成します。

ExpressionParameterとMenuを設定

image.png
image.png

Editor上で実行してlyuma/Av3Emulatorで確認

lyuma/Av3Emulator v2.9.8を導入し、ToolsからAvatar3.0Emulatorを追加し、Editor上で再生、GameViewでアホ毛を右クリックで掴んで左クリックで固定、Hierarcyでアバターを選択し、InspectorのGesture Manager Av 3 MenuでExpressionMenuを操作します。
image.png

OSCクライアントの実装

私はgolangで書きましたがclientはなんでもいいです。VRChat的にはこれがおすすめのようです。

OpenSound Control - WikipediaはアプリケーションプロトコルでトランスポートはUDPが多いようです。(時々VRChatのデバッグ画面でOSCの受信が確認できないのはUDPだからなのか?)

VRChatでOSCを有効化する

下図のようにアクションメニューからOSCをEnabledにすると、AvatarParametersのconfigファイルが生成されます。
image.png

OSCのアドレスを確認

OSC用のアドレスはC:\Users\{User}\AppData\LocalLow\VRChat\VRChat\OSC\{userId}\Avatars\{avatarId}.jsonにあります。OSC Avatar Parameters
image.png

golangでのOSCクライアントの実装

golangだとこんな感じで書けます。

OSCSend.go
package main

import (
	"time"

	"github.com/hypebeast/go-osc/osc"
)

func main() {
	client := osc.NewClient("127.0.0.1", 9000)

	for {
		msgMin := osc.NewMessage("/avatar/parameters/LeftMin")
		msgHour := osc.NewMessage("/avatar/parameters/RightHour")
		t := time.Now()
		hour := t.Hour()
		minute := t.Minute()
		// fmt.Print(t.Local().Hour(), t.Local().Minute(), "\n")
		// 分を60分に対応する[0,1]のfloatに変換
		fminute := float32(minute) / float32(60)
		// 時間を12時間に対応する[0,1]のfloatに変換
		fhour := float32(int(hour%12))/float32(12) + fminute/float32(12)
		// fmt.Print(fhour, fminute, "\n")
		msgMin.Append(float32(fminute))
		msgHour.Append(float32(fhour))
		client.Send(msgHour)
		client.Send(msgMin)
		time.Sleep(time.Second)
	}
}

ビルド

go build OSCSend.go
  • GUIを表示したくない場合
go build -ldflags="-H windowsgui" OSCSend.go

OSCSend.exeの名前の実行ファイルが生成されます。

タスクスケジューラーでWindowsログオン時にプログラムを実行する

VRChat起動時に毎回OSCをアプリを起動するのは手間なのでWindows標準アプリのタスクスケジューラーに任せます。

Windowsの検索欄から「タスク スケジューラ」を入力し起動します。

下図のようにタスクの作成からトリガータブを選択、新規ボタンからタスクの開始をログオン時に指定します。
image.png

下図のように先ほどビルドした実行ファイルを指定します。
image.png

これでWindows起動時にOSCクライアントが起動するようになりました。この状態でVRChatを起動すればOSCで時間情報を受信し両耳に時間が反映されるはずです。
image.png

最後に

Avatar3.0周りはそれぞれで環境が違うので同じように実装できるとは限らないのですが、部分的にでも誰かのお役に立てれば幸いです。また、ツール開発者に感謝を!

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
2