본문 바로가기
게임 개발

[Unity] 보스 키우기 (3) - 코루틴 최적화

by chobbo 2024. 6. 21.

캐릭터가 죽었을 때 Die 애니메이션을 실행하고

해당 애니메이션이 끝나면 오브젝트를 꺼주려고 한다.

 

처음엔

IEnumerator WaitForDieAnim()
{
    Animator.SetTrigger(AnimationData.DieParameterHash);

    while (!Animator.GetCurrentAnimatorStateInfo(0).IsTag("Die")) yield return null;
    while (Animator.GetCurrentAnimatorStateInfo(0).normalizedTime < 1.0f) yield return null;

    gameObject.SetActive(false);
}

 

다음과 같이 Die 태그를 가진 애니메이션이 실행되고

해당 애니메이션이 끝나는 조건을 While 문을 사용해서 판별해 주었으나

비효율적인 방법이었다.

 

알고보니 현재 재생 중인 애니메이션의 길이를 직접 구할 수 있어

WaitForSeconds 형식의 animLength 변수를 미리 생성해둔 후

 

코루틴이 실행될 때 해당 변수가 비어있다면

처음으로 애니메이션 변수를 불러왔다면

변수에 값을 넣어주고

그렇지 않으면 있는 변수 길이 만큼 기다렸다가 

오브젝트를 꺼주는 방법으로 수정하였다.

IEnumerator WaitForDieAnim()
{
    Animator.SetTrigger(AnimationData.DieParameterHash);

    if(animLength == null)
    {
        animLength = new WaitForSeconds(Animator.GetCurrentAnimatorStateInfo(0).length);
    }

    yield return animLength;

    gameObject.SetActive(false);
}

 

피격시 실행되는 코루틴도 처음엔 실행할 때 마다 

yield return new WaitForSeconds();를 사용했었는데,

GC가 발생할 수 있는 방법이라

다음과 같이 미리 WaitForSeconds 변수를 선언해둔 후 

이를 가져오는 방법으로 수정하였다.

private WaitForSeconds hitEffectSeconds;

private void Awake()
{
    hitEffectSeconds = new WaitForSeconds(hitEffectDuration);
}

IEnumerator HitEffect()
{
    skinnedMeshRenderer.material.color = hitColor;
    yield return hitEffectSeconds;
    skinnedMeshRenderer.material.color = originColor;
}

 

 

이제 한마리 완성..

주말부터는 다양한 종류 (원거리, 진화된 몬스터)의 Enemy를 구현하려고 한다