「カスタムモーション」記録 / 再生機能を作ってみた REALITY Advent Calendar 2023
さて、REALITY Advent Calendar 2023 3日目!UnityチームのIKEPです!
今年も開発合宿で美味しいご飯を堪能しながら、自分が作ってみたら面白そうだなーと思う機能を作ってみました!
作ったもの
「カスタムモーション」記録機能
フェイストラッキングやエモートなど、アバターの表情や体の動きを記録して自分だけのモーションを作成できる機能を作ってみました!
こうして記録した「カスタムモーション」データをREALITYのさまざまな場所で使えるように3つの機能を作りました!
1. カスタムアバターエモート再生機能
記録した「カスタムモーション」データの再生をアバターエモートとして再生できるように繋いでみました!
これであなただけのお気に入りのエモートをいつでも使えますね!!
もちろん、配信中に「カスタムモーション」を再生した場合は、視聴者にもその動きが同期されるようになっています!
2. 配信中待機モード(/idleコマンド)
2つ目は配信中の待機モーションとして使えるように配信コマンドに繋いでみました!
今のREALITYでは配信中にちょっと離席をした場合など、スマホの前から離れると、アバターが動かなくなってしまいます。
そこで、「/idle on」と配信コメントに入力すると、「カスタムモーション」がループ再生されるようにしてみました!
離席して戻ってきたら、「/idle off」と配信コメントに入力すると、いつも通りのフェイストラッキングでの配信を再開できます!
3. カスタムプロフィールエモート機能
3つ目はプロフィールエモートとして設定できるようにしてみました!
プロフィールエモートの設定画面で、1番左のアイコンを長押しすることで、「カスタムモーション」をプロフィールエモートとして設定できます!
すると、他のユーザさんが自分のプロフィールを閲覧した時に、「カスタムモーション」が再生されます!
これで、配信外でも様々なユーザさんに自分の個性をアピールできますね!
どうやって作ったの?
モーションのデータ構造自体は至ってシンプルで、アバターの顔に適用されているBlendShape値と、各BoneのRotation値を毎フレーム分記録しているだけです。
public class MotionData{
// 記録したフレーム数
public int frameCount;
// BlendShapeターゲット名、もしくは、Bone名にX,Y,Zをつけた名前をkeyとする。
// valueは対象の値の時系列リストデータ(frameCount分の長さを持つ)
public Dictionary<string, List<float>> motion = new ();
}
「カスタムモーション」記録機能については、各BlendShapeターゲットと各Boneから値を取得してこのデータ構造に従って記録しています。
その後、JSONデータに変換してローカルストレージに保存しています。
(もう少し賢い方法はありそうですが、合宿で開発時間も限られているので、動くの優先です…^^)
記録したモーションデータの再生はこの逆で、毎フレーム各値を各BlendShapeターゲットと各Boneに適用していく実装になっています。
(作ってから思ったのですが、Unity HumanoidのMuscle値形式でやるのであれば、OSSで公開されているMuscleCompressorと似たことをやってますね…)
そして、この記録/再生機能をREALITYの様々な機能から利用できるように、実装してあげています。
(この繋ぎ込みの方に意外と時間がかかっていたりします…)
例えば、配信での同期などについては、今年4月のエイプリルフール企画として実施したハンドトラッキング機能の中で開発した同期機能を利用したので、送信データの変換をしたりしています。
まとめ
トラッキングの機能を使って個人的に面白そうだな、と思ったことをやってみました!
実際には、アプリの処理負荷に応じて記録時と再生時の動きのスピードが変わってしまったり、記録したモーションデータの容量が大きくなったりと色々問題はありますが、どこかで活用できそうな気もしています!
明日のアドベントカレンダーは?
明日は、サーバエンジニアのゆーしさんの「アバタースタジオを作ろう」です!
お楽しみに!