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:

Це новий віртуальний метод, який встановлює isStateFinished у значення true. Віртуальний метод означає, що похідні класи можуть перевизначити цей метод, якщо потрібно виконати додаткові дії при завершенні стану.

Чому були внесені ці зміни

Зміни вводять змінну 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(); Цей метод встановлює isStateFinished у значення false та активує анімацію бігу, встановлюючи булевий параметр "run" в аніматорі у true.

Метод UpdateState:

public override void UpdateState(float DeltaTime); Цей метод оновлює позицію та орієнтацію ворога відповідно до позиції гравця; Він змінює масштаб ворога для повороту у бік гравця, обчислює швидкість на основі параметра speed та застосовує цю швидкість до Rigidbody2D.

Метод EndState:

public override void EndState() Цей метод зупиняє анімацію бігу, встановлюючи булевий параметр "run" в аніматорі у значення false.

Як це працює для нашого ворога

  • Рух і анімація: Використовуючи Rigidbody2D та Animator, RunState забезпечує плавний рух ворога та відповідні анімації. Це робить поведінку візуально та фізично реалістичною;

  • Відстеження позиції гравця: Трансформ player дозволяє ворогу завжди рухатися до гравця, що є важливим для поведінки переслідування або бігу;

  • Обробка напрямку: Коригування 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);
}

Пояснення

Ініціалізація станів:

Змінні idle та runState ініціалізуються відповідними станами. Змінна idle є екземпляром IdleState з переданим аніматором, а runState — екземпляром RunState, який містить Rigidbody2D, 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)); Цей перехід перевіряє, чи поточний стан завершено. Якщо так, відбувається перехід у стан idle з імовірністю 100%.

  • finishRunning: finishRunning = new Transition(() => { return (ThresholdDistance >= Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(idle, 100)); Цей перехід перевіряє, чи гравець знаходиться ближче, ніж ThresholdDistance. Якщо так, відбувається перехід у стан idle з імовірністю 100%.

Додавання переходів до StateManager:

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

Ці рядки додають визначені переходи до stateManager.

Чому ми зробили саме так

Динамічні зміни станів:

Переходи дозволяють ворогу динамічно змінювати свою поведінку залежно від позиції гравця та статусу виконання поточного стану, що робить ворога більш чутливим та інтерактивним у ігровому середовищі.

Умовні переходи:

Використання умов (наприклад, перевірка відстані або завершення стану) гарантує, що переходи між станами відбуваються логічно та доречно, підвищуючи реалістичність ігрового процесу.

Переходи на основі ймовірності:

Використання StatePourcentage дозволяє створювати переходи на основі ймовірності, додаючи елемент непередбачуваності та різноманіття у поведінку ворога.

question mark

Що відбувається з animator, коли викликається метод StartState у класі RunState?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 3. Розділ 5

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

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:

Це новий віртуальний метод, який встановлює isStateFinished у значення true. Віртуальний метод означає, що похідні класи можуть перевизначити цей метод, якщо потрібно виконати додаткові дії при завершенні стану.

Чому були внесені ці зміни

Зміни вводять змінну 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(); Цей метод встановлює isStateFinished у значення false та активує анімацію бігу, встановлюючи булевий параметр "run" в аніматорі у true.

Метод UpdateState:

public override void UpdateState(float DeltaTime); Цей метод оновлює позицію та орієнтацію ворога відповідно до позиції гравця; Він змінює масштаб ворога для повороту у бік гравця, обчислює швидкість на основі параметра speed та застосовує цю швидкість до Rigidbody2D.

Метод EndState:

public override void EndState() Цей метод зупиняє анімацію бігу, встановлюючи булевий параметр "run" в аніматорі у значення false.

Як це працює для нашого ворога

  • Рух і анімація: Використовуючи Rigidbody2D та Animator, RunState забезпечує плавний рух ворога та відповідні анімації. Це робить поведінку візуально та фізично реалістичною;

  • Відстеження позиції гравця: Трансформ player дозволяє ворогу завжди рухатися до гравця, що є важливим для поведінки переслідування або бігу;

  • Обробка напрямку: Коригування 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);
}

Пояснення

Ініціалізація станів:

Змінні idle та runState ініціалізуються відповідними станами. Змінна idle є екземпляром IdleState з переданим аніматором, а runState — екземпляром RunState, який містить Rigidbody2D, 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)); Цей перехід перевіряє, чи поточний стан завершено. Якщо так, відбувається перехід у стан idle з імовірністю 100%.

  • finishRunning: finishRunning = new Transition(() => { return (ThresholdDistance >= Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(idle, 100)); Цей перехід перевіряє, чи гравець знаходиться ближче, ніж ThresholdDistance. Якщо так, відбувається перехід у стан idle з імовірністю 100%.

Додавання переходів до StateManager:

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

Ці рядки додають визначені переходи до stateManager.

Чому ми зробили саме так

Динамічні зміни станів:

Переходи дозволяють ворогу динамічно змінювати свою поведінку залежно від позиції гравця та статусу виконання поточного стану, що робить ворога більш чутливим та інтерактивним у ігровому середовищі.

Умовні переходи:

Використання умов (наприклад, перевірка відстані або завершення стану) гарантує, що переходи між станами відбуваються логічно та доречно, підвищуючи реалістичність ігрового процесу.

Переходи на основі ймовірності:

Використання StatePourcentage дозволяє створювати переходи на основі ймовірності, додаючи елемент непередбачуваності та різноманіття у поведінку ворога.

question mark

Що відбувається з animator, коли викликається метод StartState у класі RunState?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 3. Розділ 5
some-alt