【Unity】任意のAnimation Stateと現在再生されているStateを比較する

はじめに

Animatorのパラメーター/ステートは文字列ではなくハッシュ値で管理するとよい

(例)

protected Animator m_Animator;

//~~~

m_Animator.SetTrigger("Attack");

ではなく

protected Animator m_Animator;

readonly int hashAttack = Animator.StringToHash("Attack");

//~~~

m_Animator.SetTrigger(hashAttack);

の方が好ましい

現在のステートを取得する

AnimatorStateInfo、Animator.GetCurrentAnimatorStateInfoを使用する

docs.unity3d.com

protected AnimatorStateInfo m_CurrentStateInfo;   //現在のハッシュ値が入る
protected Animator m_Animator;

void Awake(){
   m_Animator = GetComponent<Animator>();
}

void Update(){
    m_CurrentStateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);
}

Base Layerのみを使う場合

f:id:sirataki76:20200922203926p:plain

protected AnimatorStateInfo m_CurrentStateInfo;
protected Animator m_Animator;

//State Hash
readonly int hashStateLocomotion = Animator.StringToHash("Locomotion");

void Awake(){
   m_Animator = GetComponent<Animator>();
}

void Update(){
    m_CurrentStateInfo = m_Animator.GetCurrentAnimatorStateInfo(0);    //Base Layerのみの取得なので0を入れる

    Debug.Log(IsStateLocomotion());
}

bool IsStateLocomotion(){
    bool isState = m_CurrentStateInfo.shortNameHash == hashStateLocomotion;

    return isState;
}

 

いくつかのLayerを組み合わせて使う場合

例としてBase Layerの他にAttack、Damage用にの2つのレイヤーを追加したもの(計3つのレイヤー)を使用する

f:id:sirataki76:20200922211520p:plain

複数のレイヤーからStateを比較するときはfullPathHashを使って比較する

protected AnimatorStateInfo[] m_CurrentStateInfo = new AnimatorStateInfo[3];
/*
protected AnimatorStateInfo[] m_NextStateInfo = new AnimatorStateInfo[3];
protected bool[] m_IsAnimatorTransitioning = new bool[3];
*/
protected Animator m_Animator;

//Parameter Hash
readonly int hashAttack = Animator.StringToHash("Attack");

//State Hash
readonly int hashStateLocomotion = Animator.StringToHash("Base Layer.Locomotion");    //Layer名.State名
readonly int hashStateAttack_1 = Animator.StringToHash("Attack.AttackSM.Attack_1");    //Layer名.StateMachine名.State名

void Awake(){
   m_Animator = GetComponent<Animator>();
}

void Update(){
    for(int i = 0; i < 3; ++i){
        m_CurrentStateInfo[i] = m_Animator.GetCurrentAnimatorStateInfo(i);
        /*
        m_NextStateInfo[i] = m_Animator.GetNextAnimatorStateInfo(i);
        m_IsAnimatorTransitioning[i] = m_Animator.IsInTransition(i);
        */
    }
}

bool IsStateLocomotion(){
    bool isState = m_CurrentStateInfo[0].fullPathHash == hashStateLocomotion;

    return isState;
}

bool IsStateAttack(){
    bool isState = m_CurrentStateInfo[1].fullPathHash == hashStateAttack_1;    //AnimatorStateInfo[]のIndexをレイヤーと同じ番号にすること

    return isState;
}

今回はAnimator.GetCurrentAnimatorStateInfoのみを用いたが、他にもAnimator.GetNextAnimatorStateInfoやAnimator.IsInTransitionを使って比較できたりもする

Unity - Scripting API: Animator.StringToHash

Unity - Scripting API: Animator.GetCurrentAnimatorStateInfo

Unity - Scripting API: Animator.GetNextAnimatorStateInfo

Unity - Scripting API: Animator.IsInTransition

【Unity】アクションゲームで使える攻撃判定を作る

やりたいこと

任意の座標・大きさの範囲内にあるコライダーを取得したい

 

結論

Physics.OverlapBoxNonAlloc

Physics.OverlapSphereNonAlloc

Physics.OverlapCapsuleNonAlloc

docs.unity3d.com

 

を使う

 

解説(?)

3Dで攻撃判定を作るときBoxColliderやCapsuleColliderを使う手段もありますが、攻撃判定を一度に複数用意したい・判定の大きさを変えたいとなった際ちょっと不便です

また、Colliderは触れたものすべてをメモリに溜め込むため(Layerである程度ふるいにかけることはできますが)一度の判定で膨大な数のオブジェクトを取得してしまうこともあります

 

対してPhysics.Overlap~NonAllocは個数や大きさ、座標を簡単に変えられたり、決めた要素数以上のオブジェクトを取得しない仕組みになっているため、GCの発生を抑えることができます

 

以下サンプル

 

Get Collider

 

 

【Unity】コントローラーのスティックが回されたかどうかを判別する・2

やりたかったこと

サルゲッチュシリーズやベヨネッタシリーズにあるコントローラーのスティックを回して何らかのアクションをさせること

方法

16方向に判定するための座標を置き、コントローラーの入力によって触れた時スコアを加算する
スコアが設定した値を超えた時回転したと判定する

スクリプト

【Unity】コントローラーのスティックが回されたかどうかを判別する

moonrabbit.hatenadiary.com

やりたかったこと

サルゲッチュシリーズやベヨネッタシリーズにあるコントローラーのスティックを回して何らかのアクションをさせること

結果

方法に納得していないものの一応できた

方法

キャンバスの4~8方向にコライダーを置き、コントローラーの入力によって触れた時スコアを加算する
スコアが設定した値を超えた時回転したと判定する

スクリプト

github.com

【Overwatch】ルシオの立ち回り/アビリティの使い方

このブログ記事ではライバルマッチにおける、私のルシオの立ち回り、アビリティの使い方を書きます、参考になれば幸いです

ルシオのアビリティ、通常時はヒール/スピード アンプ・イット・アップ中はヒールブースト/スピードブーストと本記事では記述します

※4/16追記 ウォールライド

※2018/5/29追記 ルール別立ち回り

立ち位置はメインヒーラーの護衛

  • ルシオは瞬間的、大幅な回復はできないのでタンクの回復はアナやマーシーに任せてオフェンス、ディフェンスヒーローの回復をするよう心掛けましょう

この時、ヒールブーストはアナ、ゼニヤッタのみに使用する事(膠着状態を想定、味方にクリティカルが発生したらやむなし)です、可能ならばアンプの無駄使いは避けましょう。(膠着状態が崩れた時の複数に大幅な回復が必要な時やスピードブースト時の為の温存)

特にアナは被弾すると自分にビンを使ってしまうプレイヤーが多いため、早めの回復をしてあげましょう

(アナはタンク同士の動向を見て回復阻害などを行う事があるので、タンクの補助がしやすい環境を作る事を意識しましょう)

  • ゲームプレイ中のルシオの立ち位置としてはアナのナノブースト暴発を防ぐ意味も兼ねて全ての味方を視界に入れた後方、かつ敵ラインハルトのシャターを食らわない距離/位置が良いでしょう、ただし、新ルシオ(効果範囲10m)になると立ち位置が大幅に変わることが予想されます

4/12のパッチ以降、前線になるべく留まり後衛が狙われた時に後退するという立ち回りをしています

 

ルール別立ち回り

コントロール・アサルト

  • いわゆるダイブ構成時

ウィンストン、D.Va、トレーサーやゲンジなどが敵陣へ突入する際、他チームメイトに機動力の低いヒーローがいた場合はチームメイトをスピードブーストで牽引、いない場合は突入したヒーローをヒール・スピードで支援をしながらフォーカスを合わせましょう

  • ラインハルト等の構成時

メインタンクのシールドが前線となるのでラインハルト、ザリアやオリーサの前進後退を見分けヒール・スピードの支援をしていきましょう

 


ペイロード

基本的に前線を構築しているヒーローを支援します

例外としてはペイロードを押しているヒーロー/メインヒーラーが狙われた場合迎撃へ行く等です

 

ソニックアンプリファイア

  • 着弾までの偏差を覚えてエリミネーション数を稼ぎましょう、頭の位置を覚えてヘッドショットを狙うとなお良し
  • 命中率は30%、ダメージは5500を越せば上々でしょう
  • ルシオは衝撃波で相手をノックバックさせることができるので、トレーサーやゲンジ等からアナやマーシーを守ってあげましょう

いつでも衝撃波を出せるよう、弾は衝撃波分常に残しておくと良いでしょう

ヒール/スピード

ルシオの要とも言えるアビリティです

  • 基本的に常時ヒールで前線の体力を回復し、試合が動いた時にスピードブーストをしましょう。因みにアンプを適用しない、スピードのアシストは成績に加算されません

以前は「常にスピードを出して当たらなければどうという事はない」という考えでしたが、常時ヒールをする事でアルティメットゲージを少しでも稼ぐ事の方が重要だと今は考えています

  • スピードブーストを使うタイミングとしてはラインハルトのシャター、ザリアのサージ、ゲンジの龍神剣等と合わせてあげると良いでしょう
  • アナやマーシーの復帰時にスピードブーストで迎えに行くことも良いと思います(ただし、前線は気付いていない事が多いのでVC等で伝達ができない場合は控えましょう)
  • ラインハルトなどのタンクが敵ロードホッグに引っ張られてしまった場合、体力が僅かに残りますのでスピードブーストで逃がしてあげましょう

(オフェンス等体力が低いヒーローが引っ張られてかつ自分がロードホッグをノックバックさせられる位置にいる場合は、ロードホッグが味方を引っ張り終わる瞬間を狙って衝撃波を出しましょう)

ここでアシストについて簡単に解説します

スピードブースト中に味方がダメージを与えたままキルが発生すると攻撃アシストが貰えます、逆にヒールブースト中に味方がダメージを与えたままキルが発生すると防衛アシストが貰えます

このアシストは攻撃/防衛共に8を越せば上々でしょう

ウォールライド

4/12のパッチによりウォールライド中の移動速度が20%上昇、壁からのジャンプ時に更にスピードの上昇が得られるようになりました

これにより地面を走るより壁を走った方が速い、即ち戦闘中や復帰時のアドバンテージを得ることができます

壁からのジャンプのスピード上昇はバニーホップをすることで1秒程保持できます(要検証)

私が利用するルートをいくつか動画で紹介したいと思います

サウンドバリア

基本的な使い方は敵アルティメットから生き延びる為に使用します。

  • スピードブーストやヒールブーストを重ねて被害を抑えることも重要です

気を付ける事はこのアビリティはバリアを貼るだけなので回復が必要なヒーローはバリアが解けると体力はそのまま、ということです

 

以上で終わります