· 

【Unity】当たり判定を技ごとに変化させる

Last Updated  2024.05.23


 今回は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)変換して状態を習得する場合のサンプル

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// Animatorでプレイヤーの状態を判定するスクリプト

public class PlayerState : MonoBehaviour
{
    // 現在の状態
    public enum nowPlayerState
    {
        Normal,
        Attack,
        Damage,
    }    public nowPlayerState _1PPlayerState;// _1Pプレイヤーの状態

    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)
        {
            _1PPlayerState = nowPlayerState.Attack;
        }
        else if (animator.GetCurrentAnimatorStateInfo(0).tagHash == tagHashDamage)
        {
            _1PPlayerState = nowPlayerState.Damage;
        }
        else {
            _1PPlayerState = nowPlayerState.Normal;
        }
    }
}

 自分の場合、これを「攻撃中の相手に攻撃をヒットさせたらカウンター扱い」といった特定条件の判定に使ってます。


参考元

 

▼UnityのAnimatorの状態にタグを設定し条件を簡単にする

https://gametukurikata.com/animationanimator/animatorstatetag

▼[Unity]AnimatorControllerメモ ハッシュ値をキャッシュして軽くする https://note.com/weathervane/n/n8370941945cb