Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
学ぶ Attack State | Unityアニメーションシステム
Unityでの格闘ゲーム

Attack State

メニューを表示するにはスワイプしてください

public class AttackState : State
{
    string attackStateName; 
    bool isAttacking;
    Animator animator;
    Transform transform;
    float range;
    int damage;
    LayerMask playerLayer;

    public AttackState(Transform t, Animator animator, LayerMask playerLayer, string attackStateName, int damage, float range = 2.1f)
    {
        this.animator = animator;
        this.attackStateName = attackStateName;
        this.range = range;
        transform = t;
        this.damage = damage;
        this.playerLayer = playerLayer;
    }

    public override void StartState()
    {
        isStateFinished = false;
        animator.SetBool(attackStateName, true);
        isAttacking = false;
    }

    public override void EndState()
    {
        animator.SetBool(attackStateName, false);
    }

    public override void UpdateState(float deltaTime)
    {
        Attack();
    }

    public override void StartAction()
    {
        isAttacking = true;
    }

    public override void FinishMovement()
    {
        isAttacking = false;
    }

    void Attack()
    {
        if (!isAttacking) return;
        RaycastHit2D rayCastHit = Physics2D.Raycast(transform.position, Vector2.right * transform.localScale.x, range, playerLayer);
        if (rayCastHit)
        {
            if (rayCastHit.transform.TryGetComponent(out IGetAttacked getAttacked))
            {
                getAttacked.GetAttacked(damage);
                isAttacking = false;
            }
        }
    }
}

AttackState クラスの解説

AttackState クラスは、敵の攻撃動作を管理する特定のステートです。このクラスは State クラスを継承しており、攻撃ステートの開始、更新、終了、および攻撃アクションの処理を行うメソッドを含みます。

クラス定義とメンバ変数

クラス定義:

public class AttackState : State; このクラスは State クラスを継承しており、State で定義された抽象メソッドを実装する必要があります。

メンバ変数:

string attackStateName; アニメーターで使用される攻撃ステート名。 bool isAttacking; 敵が現在攻撃中かどうかを示すフラグ。 Animator animator; アニメーションを制御。 Transform transform; 敵のトランスフォーム。位置やレイキャストに使用。 float range; 攻撃範囲。 int damage; 攻撃によるダメージ量。 LayerMask playerLayer; プレイヤーを識別するためのレイヤーマスク。

コンストラクタ

コンストラクタは、AttackState を初期化するために必要なコンポーネント、すなわち位置決め用の Transform、アニメーション用の Animator、プレイヤーを識別するレイヤーマスク、攻撃状態名、ダメージ値、攻撃範囲を受け取ります。これらの値を対応するメンバ変数に設定します。

StartState メソッド

このメソッドは isStateFinished を false に設定し、アニメーター内の該当するブールパラメータを true に設定することで攻撃アニメーションを開始し、isAttacking フラグを false にリセットします。

EndState メソッド

このメソッドは、アニメーター内の該当するブールパラメータを false に設定することで攻撃アニメーションを停止します。

UpdateState メソッド

このメソッドは毎フレーム呼び出され、Attack メソッドをトリガーして攻撃アクションを実行します。

StartAction メソッド

このメソッドは isAttacking を true に設定し、攻撃アクションが開始されたことを示します。

FinishMovement メソッド

このメソッドは isAttacking を false に設定し、攻撃アクションが終了したことを示します。

攻撃メソッド

このメソッドは攻撃アクションを実行します。isAttacking が true の場合、敵が向いている方向にレイを発射します。レイが playerLayer 上のオブジェクトに当たると、ヒットしたオブジェクトの GetAttacked メソッドを呼び出し、ダメージを与えて攻撃アクションを終了します。

この方法を選んだ理由

  • 攻撃動作の制御: isAttacking フラグにより、攻撃のタイミングを正確に制御でき、ゲームイベントへの応答性が向上します。

  • 動的な攻撃実行: 敵の攻撃状態を継続的に更新することで、AttackState はプレイヤーへの正確かつ動的な攻撃を実現します。

  • アニメーションとの連携: アニメーターのパラメータを使用することで、敵のアニメーションと攻撃が正しく同期し、滑らかでリアルな体験を提供します。

コンテキストでの動作

攻撃状態への遷移: 敵が AttackState に入ると、StartState メソッドが呼ばれ、攻撃アニメーションが開始され、isAttacking フラグがリセットされます。

攻撃中: 毎フレーム UpdateState メソッドが呼ばれ、攻撃が必要かどうかを Attack メソッドで判定します。

攻撃開始: StartAction メソッドで isAttacking が true になり、Attack メソッドが攻撃アクションを実行できるようになります。

攻撃の実行: Attack メソッドがレイを発射してプレイヤーを検出し、ヒットした場合はダメージを与えます。

攻撃終了: FinishMovement メソッドで isAttacking が false になり、攻撃アクションが停止します。

攻撃状態からの離脱: 敵が AttackState を離れると、EndState メソッドが呼ばれ、攻撃アニメーションが停止します。 このように AttackState を構成することで、敵がプレイヤーに対して応答性と動的な攻撃を行い、アニメーションや状態間のスムーズな遷移を実現しています。

クローズトランジション:

closeTransition = new Transition(() =>
{
    return (ThresholdDistance >= Mathf.Abs(transform.position.x - player.position.x));
}, new StatePourcentage(attack2, 50f), new StatePourcentage(attack1, 50f));

stateManager.AddStateTransition(idle, closeTransition);
stateManager.AddStateTransition(idle, FarAwayTransition);
stateManager.AddStateTransition(dashState, toIdleTransition);
stateManager.AddStateTransition(dashState, finishRunning);
stateManager.AddStateTransition(runState, finishRunning);
stateManager.AddStateTransition(attack2, toIdleTransition);
stateManager.AddStateTransition(attack1, toIdleTransition);

closeTransition: このトランジションは、プレイヤーが敵から一定の水平距離(ThresholdDistance)以内にいるかどうかを判定します。 条件が満たされた場合、attack1 または attack2 のいずれかに50%の確率でランダムに遷移します;

コード例:
 ```csharp
 closeTransition = new Transition(() =>
 {
     return (ThresholdDistance >= Mathf.Abs(transform.position.x - player.position.x));
 }, new StatePourcentage(attack2, 50f), new StatePourcentage(attack1, 50f));
 ```

closeTransitionのIdleステートへの追加:

stateManager.AddStateTransition(idle, closeTransition); この行は、closeTransition を idle ステートに追加し、敵がアイドル状態のときにこの条件を判定できるようにします。

なぜこのように実装したのか

遷移システムにより、敵キャラクターはプレイヤーの接近に応じて攻撃状態へ切り替わり、インタラクションが強化される。異なる攻撃を確率的に選択することで予測不可能性が増し、ゲームの難易度と興味が高まる。

コンテキスト内での動作

Idle状態: 敵キャラクターがidle状態の間、ThresholdDistanceを使用してプレイヤーがcloseTransition内にいるかを常に確認する。 プレイヤーが十分近い場合、closeTransitionが発動し、敵キャラクターはattack1またはattack2へ遷移する。

Attack状態:

attack1またはattack2に入ると、敵キャラクターは攻撃を実行する。 攻撃が終了すると、既存のtoIdleTransitionによって敵キャラクターは再びidle状態に戻り、再度closeTransition条件を確認する準備が整う。

このcloseTransitionを追加することで、敵キャラクターはプレイヤーが近距離にいる際により動的かつ予測不可能に対応できるようになる。これにより、敵の行動がより反応的かつ魅力的になり、ゲームプレイが向上する。

question mark

AttackState クラスで、プレイヤーが範囲内にいるかを検出しダメージを与える役割を持つメソッドはどれですか?

正しい答えを選んでください

すべて明確でしたか?

どのように改善できますか?

フィードバックありがとうございます!

セクション 1. 章 18

AIに質問する

expand

AIに質問する

ChatGPT

何でも質問するか、提案された質問の1つを試してチャットを始めてください

some-alt