본문 바로가기

Unity/Portfolio Daily Log

캐주얼 슈팅 액션 대전 게임 (모바일) - 2 공격로직 및 공격 애니메이션

이번엔 공격 로직을 정리하겠다.

public interface IPlayerInput
{
    public Vector3 GetAttackDirection();
}

public class PlayerInput : MonoBehaviour, IPlayerInput
{
    private AttackJoystick attackJoystick;
    void Start()
    {
    	attackJoystick = GetComponentInChildren<AttackJoystick>();
    }
    
    public Vector3 GetAttackDirection() => new Vector3(attackJoystick.Horizontal, 0, attackJoystick.Vertical);
}

1. PlayerInput에 미리 만들어두었던 AttackJoysitck을 가지고와서 입력 값을 GetAttackDirection으로 반환한다.

private void LookAt()
    {
        lookDir = input.GetMoveDirection();
        lookDir.Normalize();
        aniCtrl.OnMovement(lookDir.x, lookDir.z);

        if (isDodge)
            lookDir = dodgeDir;
        
        if (isAttack)
        {
            Quaternion dirQuat = Quaternion.LookRotation(attackDir);
            transform.rotation = Quaternion.Slerp(transform.rotation, dirQuat, 0.3f);

        }
        if (!isAttack)
        {
            Quaternion dirQuat = Quaternion.LookRotation(lookDir);
            transform.rotation = Quaternion.Slerp(transform.rotation, dirQuat, 0.3f);
        }  
    }

공격을 하는 방향으로 캐릭터를 회전하고 싶기 때문에 LookAt 함수를 조금 수정했다. 

 

2 - 1. isAttack(공격 상태)일 때는 Quaternition.LookRotation()에 attackDir을 넣고

2 - 2. isAttack이 아닐 때는 기존의 방식 그대로 Quaternition.LookRotation()에 lookDir을 넣었다.

 

private void Attack()
    {
        attackDir = input.GetAttackDirection();
        attackDir.Normalize();
        
        if (attackDir != Vector3.zero)
        {
            aniCtrl.OnAttack(lookDir);
            isAttack = true;
        }
        else if (attackDir == Vector3.zero)
        {
            aniCtrl.ResetAttack();
            isAttack = false;
        }
    }

Attack()함수이다.

 

1. attackDir에 GetAttackDiection으로 attackJoystick 입력값을 반환한다.

 

2. 만약 attackDir이 Vector3.zero가 아니라면 라면 attackJoystick에서 입력값을 반환하고 있는 중이기 때문에 

AnimationController에 만들어 두었던 OnAttack함수를 실행 시킨다.

 

여기서 OnAttack에 lookDir 매개변수를 넣은 이유는 AnimationController 스크립트와 함께 보겠다.

 

public void OnAttack(Vector3 lookDir) 
    {
        if (lookDir == Vector3.zero) 
        {
            ani.SetTrigger("onAttack");
        }
        else { ani.SetTrigger("onMoveAttack"); }
    }

1. OnAttack은 Vector3 lookDir 값을 받는다.

 

2 - 1. 만약 lookDir이 zero라면 움직이고 있는 상태가 아니기 때문에 animator에 만든 onAttack을 Settrigger 한다. (제자리에서 총쏘는 애니메이션)

2 - 2. lookDir이 zero가 아니라면 움직이고 있는 상태이기 때문에 움직이면서 공격을 하는 애니메이션을 실행하게 했다.

 

애니메이터

1. Movement에서 Attack Sub State Machine 으로 넘어가게 했다.

2. 조건은 onAttack Trigger가 발생했을 때이다. 

3. Attack Sub State Machine을 만든 이유는 폴더에 정리를 하는 것처럼 보기 쉽게 하기 위함이다.

4. Attack 안에는 leftAttack과 rightAttack이 있는데 에셋에 있던 공격 모션이 왼쪽으로 쏘는 것 밖에 없어서 복사한 후 mirror를 체크해 오른쪽 공격 애니메이션을 만들었다.

5. 제자리에서 쏠 경우 leftAttack에서 rightAttack으로 가는 상태는 onAttack trigger가 켜질때이다.

 

6. 움직일 때 총을 쏘면 다리는 안 움직이는데 캐릭터가 움직여서 이상한 느낌을 줬다. 그래서 avatar mask 를 만들어 위쪽만 선택을 하였고 

7. UpperBody라는 레이어를 만들어서 onMoveAttack이 불릴 때 위쪽만 총쏘는 애니메이션을 재생하게 했다.