Помогите правильно настроить считывание клавиш(c#-Unity)

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

Что мне нужно: когда я нажимаю на левую кнопку мышки и отпускаю ее, у меня активируется атака в полете.
Сам полёт, если я не нажимаю ЛКМ, работает правильно. На данный момент у меня это работало только с зажатой клавишей мыши(немного другой код), но если я отпущу её, то всё сломается опять. Может быть, нужен другой метод считывания нажатие клавиши? Потому что в данном случае, считывание клавиши вызывается постоянно(fixupdate/update), и, соответственно, если клавиша не нажата в определенном моменте, то соответственно ее значение будет false, и при этом «состояние атаки в падении» обнуляется.

и есть еще один вопрос, как правильно подождать какое то время перед выполнением следующего кода? Например, я хочу чтобы во время бега был рывок: например, на 2 секунды у меня скорость становится sprintspeed*2, а потом автоматически переходит на sprintspeed.

public MovementState state;
public enum MovementState
{
    idle,
    walking,
    sprinting,
    crouching,
    air
}
bool mousedown = false;
private void Update()
{
    Vector3 colliderCenter = capsuleCollider.center;
    Vector3 origin = transform.position;
    // ground check
    grounded = Physics.Raycast(origin, Vector3.down, playerHeight * 0.5f + 1f, whatIsGround);
    Debug.DrawRay(origin, Vector3.down * (playerHeight * 0.5f + 1f), Color.blue); // Рисуем луч
    MyInput();
    SpeedControl();
    UpdateAnimationStates();
    if (Input.GetMouseButtonUp(0))
    {
        animator.SetBool("inAirAttack", true);
    }
    if (grounded)
        rb.drag = groundDrag;
    else
        rb.drag = 0;
    // Дополнительная проверка на отсутствие препятствия над персонажем
    if (!keyDown)
    {
        StandUp(); // Если нет препятствия и персонаж не приседает, то вставляем
    }     
private void FixedUpdate()
{
    MovePlayer();
    StateHandler();
    if (Input.GetKeyDown(sprintKey))
    {
        run = true;
    }

    if (Input.GetKeyUp(sprintKey))
    {
        run = false;
    }
    if (Input.GetMouseButtonDown(0))
    {
        mousedown = true;
    }
}

private void StateHandler()
{
    RaycastHit hit;
    Vector3 origin = transform.position;
    if (grounded)
    {

        // Mode - Sprinting
        if ((Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0) && Input.GetKey(sprintKey))
        {
            state = MovementState.sprinting;
            moveSpeed = sprintSpeed;
        }
        // Mode - Crouching
        else if (Input.GetKey(crouchKey))
        {
            state = MovementState.crouching;
            moveSpeed = crouchSpeed;
        }
        // Mode - Walking
        else if (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0)
        {
            state = MovementState.walking;
            moveSpeed = walkSpeed;
        }
        // Mode - Idle
        else
        {
            state = MovementState.idle;
        }
    }
    //Mode - Air
    else if (!Physics.Raycast(origin, Vector3.down, out hit, playerHeight * 0.5f + 3f, whatIsGround))
    {
        state = MovementState.air;
        //Debug.Log("air");
    }
}

private void UpdateAnimationStates()
{
    Vector3 origin = transform.position;
    // Сбрасываем все параметры перед установкой новых значений
    animator.SetBool("IsWalking", false);
    animator.SetBool("IsRunning", false);
    animator.SetBool("IsStanding", false);
    animator.SetBool("inAir", false);
    animator.SetBool("inAirAttack", false);
    // Устанавливаем параметры в аниматоре
    switch (state)
    {
        case MovementState.idle:
            animator.SetBool("IsStanding", true);
            break;
        case MovementState.walking:
            animator.SetBool("IsWalking", true);
            break;
        case MovementState.crouching:
            animator.SetBool("IsSitting", true);
            break;
        case MovementState.sprinting:
            animator.SetBool("IsRunning", true);
            break;
        case MovementState.air:
            animator.SetBool("inAir", true);
            break;
        default:
            break;
    }
}

}


Ответы (2 шт):

Автор решения: Ykizakyi Zukio

Не точно но наверное:

Он будет циклично выполнять действие пока левая кнопка мыши нажата

Input.GetMouseButton(0);
Input.GetMouseButtonDown(0);

Второй когда кнопка мыши была нажата и происходит дейсвие

→ Ссылка
Автор решения: KingPeas

Судя по описанию ваших требований вам надо смотреть в сторону Конечного автомата или еще его часто называют машиной состояний(как пример). В Unity есть встроенный инструмент Animator, правда говорят он не быстрый, но на начальном этапе очень удобный для использования.

Машина состояний которым и является Аниматор позволит вам очень гибко настроить связи и условия перехода между разными состояниями персонажа, которые у вас выражаются в анимациях. Кроме того если покопаться то можно найти как в моменты перехода выключать одни скрипты и включать другие, или можно менять через ту же анимацию свойства в самом объекте чтобы перестать слушать клавиатуру. Так нажав кнопку на прыжок, вам больше нет необходимости ее слушать,а пока идет анимация прыжка вы не сможете выполнить несовместимые действия вроде копания и т.п. Почитайте документацию по Animator, инструмент очень мощный и гибок для настройки.

→ Ссылка