UnityのAnimatorのTarget Matchingについてです。
Unity2018.3.1
どんな時に使う機能?
例えば今こんな感じのジャンプモーションがあるとします。
そしてこのジャンプモーションでこの台に飛び乗ることを考えます。
もちろん位置をスクリプトで制御してもいいのですが、その場合には
- ジャンプモーションの足が床から離れるタイミングを検知
- そのタイミングで移動を開始
- ジャンプモーションの着地までの時間を計算
- 着地までの時間でうまく移動を完了させる
といった面倒な処理が必要です。
これをある程度簡単にやってくれるのがTarget Matchingです。
使い方
Target Matchingはスクリプトでこんな感じに制御します。
using System.Collections.Generic; using UnityEngine; public class Example : MonoBehaviour { [SerializeField] private List<Transform> _jumpTargets; [SerializeField] private float _startNormalizedTime; [SerializeField] private float _endNormalizedTime; private Animator _animator; private int _jumpStateHash; private int _currentTargetIndex = -1; private MatchTargetWeightMask _mask; void Start () { _animator = GetComponent<Animator>(); _jumpStateHash = Animator.StringToHash("Jump"); _mask = new MatchTargetWeightMask(Vector3.one, 1f); } void Update () { // Jキーでジャンプ状態に遷移 if(Input.GetKeyDown(KeyCode.J)) { _animator.SetTrigger("jump"); if (_currentTargetIndex < _jumpTargets.Count - 1) { _currentTargetIndex++; } } // ジャンプ状態中はMatchTargetを呼ぶ if (_animator.GetCurrentAnimatorStateInfo(0).shortNameHash == _jumpStateHash) { _animator.MatchTarget ( _jumpTargets[_currentTargetIndex].position , _jumpTargets[_currentTargetIndex].rotation , AvatarTarget.LeftFoot , _mask , _startNormalizedTime , _endNormalizedTime ); } } }
ポイント二点です。
一点目はジャンプ中にUpdateでAnimator.MatchTarget()
を呼ぶことです。
引数にはジャンプ先のpositionとrotation、着地に使う部位などを渡します。
二点目はこの引数に移動を始める時間と着地する時間を与えることです。
この時間は正規化されたモーションの時間です。
これはアニメーションファイルのプレビューを見ながら手動で調整します。
結果
適当にオブジェクトを置いて再生するとこんな感じの結果が得られます。
良い感じに移動できています。
Humanoidでしか使えない
AvatarTargetとか使ってるしHumanoidしか使えないのかな、と思いGenericにして試してみました。
やはりGenericではTarget Matching動作しないようです。
マニュアルには特に表記はないですが、まあ当然ということでしょうか。