敵を近接攻撃すると敵が怯むアニメーションをして唸り声を上げるようにします。
まずBlenderで怯むアニメーションを作りました。
アニメーターコントローラーに新しいステートを作ってこれを設定します。新しいトリガーパラメーターも作って、他のステートからこのステートへの遷移も追加します。
怯むステートへはトリガーによって瞬時に遷移します。Transition Durationを0にしないことで、アニメーションがうまくブレンドされるはずです。また、スクリプトでAnimator.GetAnimatorTransitionInfoを使って遷移中に別の処理をさせることができます。
その後アニメーションが終わると自動的に歩くステートに遷移します。
そして、敵のスクリプトでHPを減らした後に、HPが0より大きいときは怯むトリガーをセットして、唸り声を出すようにします。唸り声はランダムで変えます。
[SerializeField] Image HpImage;
float HP = 1f;
public void SetHP(float f)
{
if (animator.GetCurrentAnimatorStateInfo(0).IsName("Flinch")) return;
HP += f;
HP = Mathf.Clamp(HP,0f,1f);
HpImage.fillAmount = HP;
if (HP > 0f)
{
Flinch();
}
}
public void Flinch()
{
// 怯むアニメーションに遷移
animator.SetTrigger("Flinch");
// 声を出す
audioSources[1].clip = voices[Random.Range(0, voices.Length)];;
audioSources[1].Play();
}
敵が怯んでいるときは、敵への攻撃が無効になるようにしています。
また、敵の攻撃が当たったときの音と唸り声が競合しないように、敵にオーディオソースコンポーネントを2つ付けることにしました。
そして、歩いているときに怯むステートに遷移するときに敵の動きを止めて、怯むアニメーションが85%進んだときに動きを再開します。敵の攻撃中から遷移したときは、攻撃のはじめから敵は動きを停止しているので問題ありません。
// 歩く→怯む
if (animator.GetAnimatorTransitionInfo(0).IsName("Armature|Walk -> Flinch"))
{
isAttacking = true;
agent.isStopped = true; // 動きを停止
//StopCoroutine("Groan");
}
// ---
// 怯んでいるとき
if (animator.GetCurrentAnimatorStateInfo(0).IsName("Flinch"))
{
// アニメーションの終わり
if (isAttacking && animator.GetCurrentAnimatorStateInfo(0).normalizedTime >= 0.85f)
{
isAttacking = false;
agent.isStopped = false; // 動きを再開
}
}
これで攻撃を受けた敵が怯むようになりました。