본문 바로가기

TIL

[ 24.08.13 ] 내일배움캠프 TIL - Attack Animation

[ ps ]

 

[ 백준 / C++ ] 5525 : IOIOI (tistory.com)

 

[ Unity ]

 

Player Attack 관련 애니메이션 동작이 아쉽다는 유저 피드백을 듣고 대대적인 수정에 들어갔다.

 

첫 번째로 공격 전 좌우 이동속도가 공격 시에도 유지되는 오류가 존재했다.

 

기존에는 공격 시 Move 메서드 호출을 막았는데,

좌우 이동속도를 결정하는 로직이 Move 메서드 내에 있어서 좌우 이동속도가 그대로 유지되었다.

 

좌우 이동속도를 결정하는 로직을 메서드로 빼고, 공격 시에 이 메서드를 호출함으로써 좌우 이동속도를 변경하였다.

private void Move()
{
    if (!stateMachine.isAttacking) ChangeVelocityX(GetMovementDirection().x * GetMovementSpeed());
}

private Vector2 GetMovementDirection()
{
    return Vector2.right * stateMachine.movementInput.x;
}

private float GetMovementSpeed()
{
    float moveSpeed = stateMachine.movementSpeed * stateMachine.movementSpeedModifier;
    return moveSpeed;
}

protected void ChangeVelocityX(float velocity)
{
    // before velocity
    Vector2 currentVelocity = stateMachine.player.rigidBody.velocity;

    // after velocity
    currentVelocity.x = velocity;

    // update velocity
    stateMachine.player.rigidBody.velocity = currentVelocity;
}
public class PlayerAttackState : PlayerBaseState
{
    // ...
    public override void Enter()
    {
        ChangeVelocityX(0f);
        stateMachine.isAttacking = true;

        if (!stateMachine.isComboAttacking) TogglePlayerWithAttack();

        base.Enter();
        StartAnimation(stateMachine.player.animationData.attackParameterHash);
    }
    // ...
}

 

두 번째로 Hit 애니메이션이 끝나야만 Attack 애니메이션이 시작되는 오류가 존재했다.

 

이거에 관해 고민하다가 Hit 관련 애니메이션을 코루틴으로 수정하여 Hit과 Attack 을 비동기적으로 처리하기로 했다.

 

코루틴의 장점을 몸소 느낄 수 있었다.

void OnDamaged(Vector2 targetPos)
{
    if (isDead) return;

    gameObject.layer = 12;
    StartCoroutine(FlashCoroutine());

    int dirc = transform.position.x - targetPos.x > 0 ? 1 : -1;
    rigidBody.AddForce(new Vector2(dirc, 1) * 2, ForceMode2D.Impulse);
    
    Invoke("OffDamaged", 1.5f);
}

IEnumerator FlashCoroutine()
{
    float flashDuration = 0.3f;
    float flashInterval = 0.15f;

    float timer = 0f;
    bool isFlashing = true;

    while (timer < flashDuration)
    {
        spriteRenderer.color = isFlashing ? new Color(1, 0, 0, 1f) : new Color(1, 1, 1, 1f);
        isFlashing = !isFlashing;

        yield return new WaitForSeconds(flashInterval);

        timer += flashInterval;
    }

    spriteRenderer.color = new Color(1, 1, 1, 0.5f);
}

void OffDamaged()
{
    gameObject.layer = 11;
    spriteRenderer.color = new Color(1, 1, 1, 1);
}

 

세 번째로 WeaponHitBox가 공격 타이밍에 맞지 않게 활성화되는 오류가 존재했다.

 

원래는 코루틴으로 Collider를 활성화했는데,

지상보다 공중에서 공격을 할 때 상대적으로 늦게 활성화되었고, 이를 도저히 수정할 수 없었다.

 

해결 방법은 생각보다 간단했는데,

Collider를 스크립트가 아닌 애니메이션 클립을 통해 원하는 프레임에 접근할 수 있었다.

Animation Clip