Last Updated 2024.05.05
今回はAnimationEventを使ってhitbox(当たり判定)をモーションごとに変化させる仕組みを実装した際の備忘録です。
Animator関連の小ネタ回みたいな内容になってしまってます。
現在再生中のAnimationStateの習得
現在どのモーションを再生中かの判定には、Animator内のAnimationStateを使用。
自分の場合、当たり判定の紐づけが必要な攻撃モーションに『hitboxOn』というAnimationEventを設定。Evantを受け取るスクリプト内でモーションを判定し、処理を分岐させています。
▼当たり判定のオンオフと、技ごとに相手の喰らい属性を指定するサンプル
private Animator animator;
private BoxCollider hitBox;
public string DamageMotion;//相手のダメージモーション
void Start()
{
animator = GetComponent<Animator>();
hitBox = GetComponent<BoxCollider>();//ヒットボックスの習得
}
void hitboxOn()
{
if (animator.GetCurrentAnimatorStateInfo(0).IsName("AdvancedAttack2"))
{
if (normalizedtime <= 0.4f)
{
DamageMotion = "Hardhit";//1段目
}
else if (0.5f <= normalizedtime)
{
DamageMotion = "Spin";//2段目
}
}
else if (animator.GetCurrentAnimatorStateInfo(0).IsName("Attack3"))
{
DamageMotion = "Hardhit";
}
else if (animator.GetCurrentAnimatorStateInfo(0).IsName("DashAttack"))
{
DamageMotion = "Hit";
}
else if (animator.GetCurrentAnimatorStateInfo(0).IsName("Launcher"))
{
DamageMotion = "Launch";
}
else if (animator.GetCurrentAnimatorStateInfo(0).IsName("AxisMoveATK"))//軸移動攻撃
{
hitBox.center = new Vector3(0.048f, 0.91f, 0.51f);//当たり判定の位置を指定
hitBox.size = new Vector3(.6f, .6f, .19f);//当たり判定の大きさを指定
DamageMotion = "Hardhit";
}
hitBox.enabled = true;//hitboxを有効化
}
void hitboxOff()
{
hitBox.enabled = false;
hitBox.center = centerPreset;//当たり判定の位置を初期化
hitBox.size = sizePreset;//当たり判定の大きさを初期化
}
以前取り扱った、当たり判定の位置や大きさを指定したり、(自分は切り分けてしまったので)記載していませんが、AudioClipを宣言、設定して音を鳴らしたりも出来ます。
正直、可読性はあまりよろしくないので、もう少しコンパクトな記述に出来ないかと模索中です。
StateにTagをつけて状態を判定する
StateのInspectorウィンドウの ≪Tag≫ に名前をつければ、大まかなStateの分類が可能です。攻撃中や喰らい中など、プレイヤーの状態を取るのに使えますね。
▼Tag名で習得する場合
animator.GetCurrentAnimatorStateInfo(0).IsTag("")
※IDで参照した方が文字列(static)参照より軽いので、あらかじめハッシュしておく方法もある。
▼タグをハッシュ値(ID)変換して状態を習得する場合
//Animatorでプレイヤーの状態を判定するスクリプト
public class PlayerState : MonoBehaviour
{
private Animator animator;
private static int tagHashAttack = Animator.StringToHash("Attack");
private static int tagHashDamage = Animator.StringToHash("Damage");
void Start()
{
animator = GetComponent<Animator>();
}
void Update()
{
//再生中のアニメーションTagを習得
if(animator.GetCurrentAnimatorStateInfo(0).tagHash == tagHashAttack)
{
Debug.Log("攻撃");
}
else if (animator.GetCurrentAnimatorStateInfo(0).tagHash == tagHashDamage)
{
Debug.Log("ダメージ");
}
}
}
自分の場合、これを「攻撃中の相手に攻撃をヒットさせたらカウンター扱い」といった特定条件の判定に使ってます。
▼[Unity]AnimatorControllerメモ ハッシュ値をキャッシュして軽くする https://note.com/weathervane/n/n8370941945cb