1 분 소요

Intro

이번 포스팅에서는 플레이어의 공격 애니메이션을 추가합니다.

먼저, 플레이어는 현재는 없지만 무기를 장착할 수 있을겁니다. 따라서 무기를 장착했을때의 공격애니메이션이 있고

무기가없는상태(주먹)에서의 공격애니메이션이 따로 존재하도록 했습니다.

오늘은 먼저 무기가없는 상태에서의 공격애니메이션을 설정해주도록하겠습니다.

 

공격 애니메이션

주먹공격 애니메이션은 왼손공격과 오른손공격 2개를 준비했습니다. 이 애니메이션은 콤보공격으로 만들어볼 예정입니다.

애니메이터창에서 우클릭하여 Create Sub State Machine을 선택합니다.

이름은 Attack으로 작성하고, 파라미터에서 Trigger를 선택한 뒤 트리거이름을 Attack으로 작성합니다.

image

  이제 공격애니메이션을 서브스테이트머신에 추가합니다.

image

  공격애니메이션은 PunchLeft -> PunchRight 순서로 실행되도록한뒤, int형 파라미터 AttackCount를 생성합니다.

그 다음, Entry를 선택하여 Make Transition을 PunchLeft로 선택한 뒤 Condition에 AttackCount - Equal - 0으로 설정합니다.

뒤이어 실행될 PunchRight도 AttackCount를 0 그리고 Attack 트리거를 추가해줍니다.

따라서 AttackCount가 0일때는 기본적으로 PunchLeft 애니메이션이 실행되며 한번 더 키입력이되면 PunchRight까지 이어지도록 했습니다.

이때 각 애니메이션에서 애니메이션이 끝날수 있도록 Exit에 연결해줍니다.

image

 

공격을 위한 스크립트 작성(Attack.cs)

공격키는 LeftCtrl로 설정했고, 키이름을 Attack으로 변경했습니다.

이 작업은 에디터 - Edit - Project Settings - InputManager에서 가능합니다.

키 입력을 처리하는 PlayerInput 스크립트에 다음을 추가합니다.

    public bool attackKeydown;

    // 사용자 입력
    private void GetInput()
    {
        hAxis = Input.GetAxisRaw("Horizontal");
        vAxis = Input.GetAxisRaw("Vertical");
        attackKeydown = Input.GetButtonDown("Attack");
    }

Attack 스크립트를 생성하고, 플레이어 오브젝트에 달아줍니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Attack : MonoBehaviour
{
    [SerializeField] private PlayerInput playerInput;

    private Animator animator;

    int hashAttackCount = Animator.StringToHash("AttackCount");

    private bool hasWeapon = false;                                 // 무기 장착여부(현재는 기본 false)

    // AttackCount 설정
    public int AttackCount
    {
        get => animator.GetInteger(hashAttackCount);
        set => animator.SetInteger(hashAttackCount, value);
    }

    private void Awake()
    {
        animator = GetComponent<Animator>();
    }

    private void Update()
    {
        DoAttack();
    }

    private void DoAttack()
    {
        // 무기가 없을 때(주먹공격)
        if(!hasWeapon)
        {
            AttackCount = 0;
            if (playerInput.attackKeydown)
            {
                animator.SetTrigger("Attack");
            }
        }

      
    }
}
  • hashAttackCount 변수는 AttackCount 파라미터에 접근해 값을 전달할 수 있도록했습니다.
    • StringToHash를 사용하는 이유는 간단하게 문자열비교가 느리기때문입니다.
  • AttackCount는 get과 set를 사용하여 값을받아 적용하도록 했습니다.
  • 무기를 소지하고있는지 확인하는 변수 hasWeapon을 현재로서는 false로 설정하고, 공격키 입력을통해 Attack 트리거가 실행되도록했습니다.

 

문제점

이대로는 문제가있습니다. 공격키를 한번더 눌러놓게되면 공격애니메이션이 끝난 뒤 한번 더 실행되게됩니다.

이는 플레이어가 의도하지않은 애니메이션의 실행이 될 수 있으므로 AttackReset이라는 스크립트를 통해 해결했습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AttackReset : StateMachineBehaviour
{
    [SerializeField] private string triggerName;            // reset할 트리거

    public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        animator.ResetTrigger(triggerName);
    }
}

  • AttackReset 스크립트는 StateMachineBehaviour를 상속받아 OnStateExit 함수를 오버라이딩합니다.
  • Animator의 ResetTrigger를 통해 버튼을 계속눌러도 연속적으로 애니메이션이 호출되는것을 막을 수 있습니다.

저장한뒤 에디터로 돌아가서 애니메이터창을 열어 Attack 상태머신을 선택하고, Add Behavior에서 AttackReset 스크립트를 추가합니다.

트리거 이름에 Attack을 넣어주면됩니다.

image

실행

계속해서 키입력을 하는것을 Attack 트리거 체크표시를통해 볼 수 있습니다.

image

댓글남기기