はじめに
どうも。「バーチャルためにならない改変お姉さん」の水無月せきなです。
前回は VRChat で自動ドアを作った話を書きました。その投稿後、ふと「 Unity 自動ドア」で調べたら先人が何人もいらっしゃいました。
__調べる時は「 VRChat 」に限定するべきではない__とがっくりしながら学んだ次第です。
さて今回は、そんな中でもなかなか例が見当たらなかった、良い感じにアニメーションをキャンセルする方法についてです。
何が問題だったか
すべてスクリプトによる制御で作った自動ドアですが、他の方の反応や前述の通りネットに既にあった記事の内容を元に、Animation を利用した方法に改めました。
その時困ったのが、「扉が開いている最中にプレイヤーが範囲内から全員いなくなった場合、開く動作をキャンセルして閉じる動作へ__自然に__切り替える」ことです。
どういうことかと言うと、アニメーションのキャンセル自体はトランジションの Has Exit Time
のチェックを外して条件を設定すれば、その条件を満たした時にすぐに遷移することでキャンセルできます。
ですが、キャンセルしたことで「閉じようとしているアニメーション」のステートから「開こうとしているアニメーション」のステートに遷移するような場合、瞬時に全開になってから閉じる動作に入るという全然自然じゃない動きになったりします。
理想としては現実の自動ドアのように、閉じかけたその位置から開こうとしてほしいわけです。
解決法
あくまで今回の自動ドアでの一例ですが、
- 開閉のアニメーションはトランジションで表現する
- トランジションの
Interruption Source
をNext State
にする
で解決しました。
開閉をトランジションで表現
突破口になったのは、こちらの記事です。
「サンプルのギミック」の説明で、この一文を見つけました。
各animationには状態のみが保持され、動くanimationは遷移時間で表現しています。
今回の問題点は、各ステートのアニメーションの再生位置をどうやって調整するかみたいな所がありました。つまり、開閉の動きをステートのアニメーションで表現している限り生じる問題です。じゃあ、アニメーションで開閉させなければ?
これが1点目です。
次のトランジションを割り込ませる
「閉じている状態」<==>「開いている状態」でステートを結んでいる時、動作のキャンセルは「次の」ステートから自分のステートに戻るトランジションへの移行です。
Interruption Source
で Next State
を指定すると遷移先のステートからのトランジションが割り込み可能になります。
割り込みは他にもあるので、詳しくは公式のマニュアルをご参照ください。
おわりに
以上で自然に動作をキャンセルできるようになりましたが、運良く上手く行った感じもしています。
他に自然なキャンセル方法をご存知の方は教えてくださると嬉しいです。