VRChatのアバターに連打しても音を鳴らせるギミックを入れたくて、アニメーションをいい感じに組んだよという話です。
色々な人に教えてもらってうまくいったので、その知見を共有します。
どんなギミック?
アクセサリーに触ると音が出るギミックで、触るたびに音を鳴らすことが出来ます
…と説明するよりも見てもらったほうが早いかもですね、動画を貼りました。
作り方
流れとしてはこんな感じです。そんなにやることは多くないですね。
- アクセサリーに VRCContactSender を入れる
- AudioSource を追加する
- AudioSource のアクティブ状態を切り替えるアニメーションを用意する
- Animator を組む
ここではContactsやアニメーションについては詳しく書かないので、他のドキュメントを読んでみてください。
1. アクセサリーに VRCContactSender を入れる
触ったときにパラメータを変更したいのでVRCContactSenderを入れます。
詳しい説明は割愛しますが、当たり判定の範囲調整と、手もしくは指が触れたときに GBC Contact というパラメータが変化するようにしています。
Receiver Type は On Enter にしておくことで、触られたときに1フレームだけパラメータが変化するようにします。
2. AudioSourceを追加する
VRChatのアバターではスクリプトを使えないので、AudioSourceの「Play On Awake」をオンにしておきましょう。
これで、AudioSourceがActiveになったときに音が鳴るようになります。
3. AudioSource のアクティブ状態を切り替えるアニメーションを用意する
タイトルのとおりですが、Activeを切り替える対象はAudioSourceコンポーネントでもAudioSourceがついているGameObjectでもどちらでも問題ないです。
ここでのポイントですが、
- 0フレーム目に AudioSource の Is Active をオフにする
- 1フレーム目に AudioSource の Is Active をオンにする
というふうにすることで、アニメーションの再生開始時に必ず音が鳴るようになります。
ただ、これだけだとAudioSourceがオンのままになるので、あとからワールドにJoinするなどしてアバターが読み込まれたタイミングで音が流れてしまいます。
なので、音を鳴らし終わる秒数あたりでオフにしておきます。
今回は鳴らす音の長さが 0.824秒だったので、余裕を取って1秒でオフにするようにしました。
最終的にこのようになりました。
4. Animatorを組む
Animatorを組む際に最低限必要なのは、次の3つです。
- Sound On に先ほどつくったアニメーションを指定、Idle には何もアニメーションを指定しない
- Any State から Sound On に遷移させる
- Any State -> Sound On の Can Transition To Self をオンにする
おわり
GestureManager などで動作確認してみて問題なければアップロードして完成です!
Animator はやり方がたくさんあってなかなか難しいですね…
このやり方は、おそらくパフォーマンス的にも問題がないと思いますが、他にいい方法があるよという人はぜひ教えてください。