Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
学ぶ ランステート | 敵の行動
Unityでの格闘ゲーム

bookランステート

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

public abstract class State
{
    public bool isStateFinished;

    public abstract void StartState();
    public virtual void UpdateState()
    {
    }
    public abstract void EndState();
    public virtual void FinishState()
    {
        isStateFinished = true;
    }
}

変更点と追加点

isStateFinished 変数:

このブール型変数は、ステートの実行が完了したかどうかを示す指標。

FinishState メソッド:

この新しい仮想メソッドは、isStateFinishedtrue に設定。 仮想メソッドであるため、派生クラスでステート終了時に追加処理が必要な場合はオーバーライド可能。

これらの変更が行われた理由

これらの変更は、状態の完了を追跡するための isStateFinished 変数と、状態完了の通知を標準化する FinishState メソッドを導入しています。これにより、派生クラスで状態完了時にカスタムロジックを追加できるようになります。

ラン状態

public class RunState : State
{
    Rigidbody2D rb;
    Animator animator;
    Transform player;
    float speed;
    Vector2 scale;
    Vector2 velocity;

    public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed)
    {
        this.animator = animator;
        player = p;
        this.speed = speed;
        this.rb = rb;
        scale = rb.transform.localScale;
        velocity = new Vector2();
    }

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

    public override void UpdateState(float DeltaTime)
    {
        scale.x = rb.position.x > player.position.x ? -1 : 1;
        rb.transform.localScale = scale;

        velocity.x = scale.x * speed;
        rb.velocity = velocity;
    }

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

RunState クラスは State クラスを継承しており、敵キャラクターの走行動作を管理します。このクラスで追加・変更された内容に注目します。

コンストラクター:

public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed);

このコンストラクターは、RunState を必要なコンポーネントで初期化します。移動用の Rigidbody2D、アニメーション用の Animator、プレイヤーの追跡用の Transform、敵の走る速さを指定する speed を受け取ります。

StartState メソッド:

public override void StartState(); このメソッドは isStateFinishedfalse に設定し、アニメーターの "run" ブールパラメータを true にすることで走るアニメーションを開始します。

UpdateState メソッド:

public override void UpdateState(float DeltaTime); このメソッドは、プレイヤーの位置に基づいて敵の位置と向きを更新します。 敵のスケールを調整してプレイヤーの方向を向かせ、速度を speed に基づいて計算し、その速度を Rigidbody2D に適用します。

EndState メソッド:

public override void EndState() このメソッドは、アニメーター内の「run」ブールパラメータを false に設定することで、走行アニメーションを停止。

敵キャラクターにおける動作の仕組み

  • 移動とアニメーション: Rigidbody2DAnimator を使用することで、RunState は敵キャラクターの滑らかな移動と対応するアニメーションを実現。視覚的・物理的にリアルな挙動を表現;

  • プレイヤー位置の追跡: player の Transform により、敵キャラクターは常にプレイヤーの方向へ移動。追跡や走行動作に不可欠;

  • 向きの制御: プレイヤーの位置に基づいて scale.x を調整することで、走行中も敵キャラクターが正しくプレイヤーの方を向くようにし、リアリズムを強化;

  • 動的な状態更新: UpdateState メソッドが毎フレーム呼び出され、プレイヤーの位置に応じて敵キャラクターの移動や向きを継続的に調整。応答性と動的な挙動を実現。

敵キャラクターの初期化

private void Start()
{
    idle = new IdleState(animator);
    runState = new RunState(GetComponent<Rigidbody2D>(), animator, player, speed);
    stateManager = new StateManager(idle);

    FarAwayTransition = new Transition(() =>
    {
        return (ThresholdDistance < Vector2.Distance(transform.position, player.position));
    }, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));

    toIdleTransition = new Transition(() =>
    {
        return stateManager.GetCurrentState().isStateFinished;
    }, new StatePourcentage(idle, 100));

    finishRunning = new Transition(() =>
    {
        return (ThresholdDistance >= Vector2.Distance(transform.position, player.position));
    }, new StatePourcentage(idle, 100));

    stateManager.AddStateTransition(idle, FarAwayTransition);
    stateManager.AddStateTransition(dashState, toIdleTransition);
    stateManager.AddStateTransition(runState, finishRunning);
}

説明

ステートの初期化:

変数 idlerunState は、それぞれのステートで初期化される。idle 変数はアニメーターを渡して作成された IdleState のインスタンスであり、runStateRunStateRigidbody2D、プレイヤーの Animator、および速度値を含む Transform のインスタンス。

StateManager の初期化:

stateManager = new StateManager(idle); StateManager は開始ステートとして idle ステートで初期化される。

遷移の定義:

  • FarAwayTransition: FarAwayTransition = new Transition(() => { return (ThresholdDistance < Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));; この遷移は、プレイヤーが ThresholdDistance より遠いかどうかを判定する。

  • toIdleTransition: toIdleTransition = new Transition(() => { return stateManager.GetCurrentState().isStateFinished; }, new StatePourcentage(idle, 100)); この遷移は、現在のステートが終了したかどうかを判定する。真の場合、100% の確率で idle ステートに遷移する。

  • finishRunning: finishRunning = new Transition(() => { return (ThresholdDistance >= Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(idle, 100)); この遷移は、プレイヤーが ThresholdDistance より近いかどうかを判定する。真の場合、100% の確率で idle ステートに遷移する。

StateManagerへの遷移追加:

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

これらの行は、定義された遷移をstateManagerに追加します。

このように実装した理由

動的な状態変化:

遷移を利用することで、敵キャラクターはプレイヤーの位置や現在の状態の完了状況に応じて動的に行動を変化させ、ゲーム内でより反応的かつインタラクティブな存在となります。

条件付き遷移:

距離や状態の完了などの条件を用いることで、状態遷移が論理的かつ適切に発生し、ゲームプレイのリアリズムが向上します。

確率ベースの遷移:

StatePourcentageを使用することで、確率に基づいた遷移が可能となり、敵の行動に予測不可能性や多様性が加わります。

question mark

animatorクラスでStartStateメソッドが呼び出されたとき、RunStateには何が起こりますか?

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

すべて明確でしたか?

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

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

セクション 3.  5

AIに質問する

expand

AIに質問する

ChatGPT

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

セクション 3.  5
some-alt