← Назад к вопросам

Приведи пример паттерна State в реальной жизни

2.0 Middle🔥 131 комментариев
#Паттерны проектирования

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Пример паттерна State в реальной жизни (в разработке игр на Unity)

Паттерн State — один из фундаментальных подходов в программировании, особенно в игровой разработке, где объекты часто меняют свое поведение в зависимости от контекста или внутренних условий. Его основная идея — инкапсулировать каждое состояние объекта в отдельный класс, что делает код более чистым, расширяемым и управляемым, избегая огромных условных конструкций (if/switch).

Конкретный пример: Система состояний персонажа

Рассмотрим классическую ситуацию: управление персонажем в 2D или 3D игре. Персонаж может находиться в различных состояниях: Idle (бездействие), Running (бег), Jumping (прыжок), Falling (падение), Attacking (атака), Dead (мертв). Использование паттерна State здесь идеально.

Без паттерна State код управления может выглядеть как монолит с множеством проверок:

public class PlayerController : MonoBehaviour
{
    private bool isRunning, isJumping, isAttacking;

    void Update()
    {
        if (isDead)
        {
            // Play death animation, disable input.
            return;
        }
        else if (isAttacking)
        {
            // Play attack animation, check hit.
        }
        else if (isJumping)
        {
            // Apply jump physics, check landing.
        }
        else if (Input.GetKeyDown(KeyCode.Space))
        {
            // Start jump...
        }
        // ... и так далее. Код становится запутанным.
    }
}

С применением паттерна State мы создаем четкую, модульную структуру.

1. Определяем интерфейс или базовый класс состояния

public abstract class PlayerState
{
    protected PlayerController player;

    public PlayerState(PlayerController player)
    {
        this.player = player;
    }

    public abstract void EnterState();
    public abstract void UpdateState();
    public abstract void ExitState();
}

2. Реализуем конкретные состояния

public class IdleState : PlayerState
{
    public IdleState(PlayerController player) : base(player) {}

    public override void EnterState()
    {
        player.animator.Play("Idle");
    }

    public override void UpdateState()
    {
        if (Input.GetKey(KeyCode.RightArrow))
        {
            player.ChangeState(new RunningState(player));
        }
        if (Input.GetKeyDown(KeyCode.Space))
        {
            player.ChangeState(new JumpingState(player));
        }
    }

    public override void ExitState() {}
}

public class JumpingState : PlayerState
{
    public JumpingPretate(PlayerController player) : base(player) {}

    public override void EnterState()
    {
        player.animator.Play("Jump");
        player.ApplyJumpForce();
    }

    public override void UpdateState()
    {
        // Проверяем физику: если персонаж начал падать, меняем состояние.
        if (player.velocity.y < 0)
        {
            player.ChangeState(new FallingState(player));
        }
    }

    public override void ExitState() {}
}

3. Основной класс персонажа управляет текущим состоянием

public class PlayerController : MonoBehaviour
{
    private PlayerState currentState;

    void Start()
    {
        currentState = new IdleState(this);
        currentState.EnterState();
    }

    void Update()
    {
        currentState.UpdateState();
    }

    public void ChangeState(PlayerState newState)
    {
        currentState.ExitState();
        currentState = newState;
        currentState.EnterState();
    }
}

Преимущества такого подхода в реальном проекте:

  • Читаемость и поддерживаемость: Логика каждого состояния локализована в своем классе. Добавить новое состояние (например, CrouchingState) — просто создать новый класс, не перелопачивать весь PlayerController.
  • Уменьшение ошибок: Транзиции между состояниями явные и контролируемые через ChangeState. Легко избежать конфликтов (например, атаки во время прыжка).
  • Совместимость с другими системами: Анимации, звуки, эффекты, связанные с состоянием, естественно помещаются в методы EnterState и ExitState.
  • Тестирование: Каждое состояние можно тестировать независимо.

Этот паттерн широко используется не только для персонажей, но также для:

  • UI-систем (меню, диалоги, всплывающие окна).
  • Игровых объектов (дверь: закрыта, открывается, открыта, закрывается).
  • AI поведения (поиск пути, атака, отступление).

В Unity часто паттерн State сочетают с State Machine компонентами аниматора (Animator Controller), но программная реализация, как показано выше, дает более гибкий и мощный контроль над логикой, особенно для сложных игровых механизмов.

Приведи пример паттерна State в реальной жизни | PrepBro