목차

반응형

1. 롤 공격 애니메이션 속도 분석

2. 원하는 결과물

3. 스크립트 설명

 

 

 

 

1. 롤 공격 애니메이션 속도 분석

게임에서 공격 속도에 따라서 애니메이션을 어떻게 해야 할까?

일단 갓겜 롤을 기준으로 생각해보자.

 

먼저 공격 속도 변수에 대해서 생각해보자. 공격속도는 1회 공격하는 회수에 대한 값이다.

2.5 -> 초당 2.5회 공격

0.5 -> 초당 0.5회 공격

 

두 개의 영상을 준비했다. 크 친절함 보소

 

 

첫 번째 영상은 공격속도 0.2의 그레이브즈

 

두 번째 영상은 공격속도 4.5의 제이스

 

그레이브즈

그레이브즈의 경우 공격 속도가 0.2면 5초에 한 번 공격하는 꼴인데 정상 속도의 공격 애니메이션을 재생하고 약 3~4초간 기다리는 것을 볼 수 있다.

 

제이스

제이스의 경우 공격 속도가 4.5니까 1초에 대략 4대를 때리는데 어찌 보면 좀 어색할 정도로 망치를 엄청 빨리 휘두른다. 즉 애니메이션의 배속이 된 것을 알 수 있다.

 

우리가 구현해야 하는 공격 애니메이션 속도 방식은 다음과 같다.

 

공격 애니메이션을 기본적으로 재생했을 때 걸리는 시간을 1초라고 가정하자.

그렇다면 해당 캐릭터는 공격 속도가 1이면 애니메이션 속도를 변경하지 않고 계속해서 공격하면 문제없다.

만약에 버프나 통하여 공격 속도가 1보다 빨라지면 애니메이션의 재생속도도 빨라진만큼 배속을 해줘야하고 공격속도가 디버프를 통하여 1보다 느려지면 기본 속도로 재생을 시켜주고 남은 시간은 기다리도록 하면 된다.

 

여기서 프레임 개념이 필요하다.

 

이것은 유니티 캐릭터가 공격하는 애니메이션이다.

공격 애니메이션은 기본적으로 1초에 한번 재생되는 것을 기본으로 하였다.

그리고 프레임 재생 비율은 1초에 30 프레임이다.

 

공격 속도 개념과 같이 설명하자면...

공격속도 2 -> 1초에 두번 공격 -> 1초에 60 프레임재생 -> 60/30 비율로 재생 -> 두 배속

공격 속도 1 -> 1초에 한번 공격 -> 1초에 30 프레임재생 -> 30/30 비율로 재생 -> 정배 속

공격 속도 0.5 -> 2초에 한번 공격 -> 2초에 30 프레임재생 -> 30/60 비율로 재생? -> 정배 속으로 재생하고 대기

 

 

2. 원하는 결과물

설명이 좀 길었는데 최대한 친절하게 설명하기 위해서 노력했다.

내가 만들고 싶은 결과물은 다음과 같다.

 

롤과 똑같은 방식이다.

 

3. 유니티 프로젝트 설명

 

공격 애니메이션 에셋은 아래 무료 에셋을 사용했다.

https://assetstore.unity.com/packages/3d/animations/warrior-pack-bundle-1-free-36405

 

Warrior Pack Bundle 1 FREE - Asset Store

This is a sample package of the Warrior Pack Bundle 1 Note: This asset works in Unity 5. This asset contains 3 animations for each of the 4 warriors in the pack (12 animations total), so that you can test and evaluate if they will work for your project bef

assetstore.unity.com

 

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class AttackController : MonoBehaviour
{
    
    /// <summary>
    /// 캐릭터의 애니메이터
    /// </summary>
    [SerializeField] private Animator animator;

    /// <summary>
    /// UI - 공격속도 인풋박스
    /// </summary>
    [SerializeField] private InputField inputFieldAttackSpeed;
    
    /// <summary>
    /// UI - 공격 정보 표기
    /// </summary>
    [SerializeField] private Text textInfo;

    
    // Start is called before the first frame update
    void Start()
    {
        //최초 공격속도 설정
        SetAttackSpeed(attackSpeed);
    }

    /// <summary>
    /// UI로 공격 속도 변경시
    /// </summary>
    public void OnInputFieldChange(InputField inputField)
    {
        SetAttackSpeed(float.Parse(inputField.text));
    }

    /// <summary>
    /// 실제 공격속도 변경해주기
    /// </summary>
    private void SetAttackSpeed(float _attackSpeed)
    {
        attackSpeed = _attackSpeed;
        
        //공격 쿨타임 계산
        attackCoolTime = 1f / attackSpeed;
        
        //최초 공격 바로 시작하도록 설정
        currentAttackCoolTime = attackCoolTime;
        
        //공격속도가 1보다 빠르면 애니메이션 빠르게 재생하기 위해서 배속 설정, 아니면 기본속도 1로 재생
        if (attackSpeed > 1) animator.SetFloat("AttackSpeed", attackSpeed);
        else animator.SetFloat("AttackSpeed", 1);
        
        //UI 초기화
        inputFieldAttackSpeed.text = attackSpeed.ToString();
        textInfo.text = string.Format("공격 속도 : {0}\n" +
                                      "공격 애니메이션 재생하는데 걸리는 시간 : {1}\n" +
                                      "공격 쿨타임 {2}/{3}",attackSpeed,1f/attackSpeed, currentAttackCoolTime,attackCoolTime);
    }
    
    /// <summary>
    /// 공격 시작
    /// </summary>
    public void StartAttack()
    {
        StartCoroutine("EnumAttack");
    }

    /// <summary>
    /// 공격 종료
    /// </summary>
    public void EndAttack()
    {
        StopCoroutine("EnumAttack");
    }

    /// <summary>
    /// 공격속도
    /// </summary>
    private float attackSpeed;

    /// <summary>
    /// 1회 공격하는데 기다려야하는 시간 -> 공격속도 변경시 계산
    /// </summary>
    private float attackCoolTime;

    /// <summary>
    /// 공격하고나서 시간이 얼마나 경과했는지 카운트
    /// </summary>
    private float currentAttackCoolTime;
    
    /// <summary>
    /// 지속적으로 공격
    /// </summary>
    private IEnumerator EnumAttack()
    {
        while (true)
        {
            //만약 공격 쿨타임이 돌았으면
            if (currentAttackCoolTime >= attackCoolTime)
            {
                //쿨타임 초기화하고 공격을 개시한다.
                currentAttackCoolTime = 0;
                Attack();
            }

            textInfo.text = string.Format("공격 속도 : {0}\n" +
                                          "공격 애니메이션 재생하는데 걸리는 시간 : {1}\n" +
                                          "공격 쿨타임 {2}/{3}",attackSpeed,1f/attackSpeed, currentAttackCoolTime.ToString("F2"),attackCoolTime);
            currentAttackCoolTime += Time.deltaTime;       
            yield return null;
        }
    }

    /// <summary>
    /// 공격 트리거 발동
    /// </summary>
    private void Attack()
    {
        animator.SetTrigger("PunchTrigger");
    }
}

 

 

 

이 부분이 핵심이다. 공격 속도가 빠르면 애니메이션의 Speed Multipler 설정에 추가해둔 AttackSpeed라는 Parameter에 따라 빠르게 재생될 수 있도록 하면 된다.

 

해당 스크립트 파일과 전체 프로젝트는 파일로 공유하도록 하겠다.

 

 

프로젝트 전체 다운로드

 

AttackController.cs
0.00MB

 

반응형