애니메이션 클립내에서 keyframe에 event를 삽입하고 해당 event에 function이름을 등록하여 그 시점에 해당 애니메이션 클립을 재생하는 애니메이터를 가진 게임오브젝트내에 특정 함수를 실행시킬수 있다.
클라이언트 개발자의 입장에서는 아티스트가 직접 키 프레임을 넣어주어도 좋지만 나같은 경우에는 코드상에서 해당부분을 체크하는게 편하기 때문에 두가지 방법을 사용한다.
먼저 위에서 설명한 내용을 코드로 직접 설정하는 방법
Animator anim = Getcomponent<Animator>();
if(anim)
{
for(int i = 0; i<anim.runtimeAnimatorController.animationClips.Length;++i)
{
AnimationClip clip = anim.runtimeAnimatorController.animationClips[i];
AnimationEvent animationEvent = new AnimationEvent();
animationEvent.time = 0; // animationEvent가 호출되는 애니메이션 시간
animationEvent.functionName = "AnimationEventCallBackFunction"; // 애니메이션 콜백 이름 ( 해당 함수는 지금 등록하는 Monobehavior 스크립트에 존재해야한다.
//animationEvent.floatParameter = 2f;
//animationEvent.intParameter = 1;
animationEvent.stringParameter = clip.name; // 위에서 설정한 functionName으로 등록한 함수에 파라미터가 있을경우 넣어줄수 있다. 그렇게 되면 그 함수는 파라미터를 받을수 있는 함수여야한다 동시에 파라미터를 하나만 받을수 있다
clip.AddEvent(animationEvent);
}
}
이렇게 코드 상에서 에디터상에서 찾아서 확인하여 아티스트가 입력하는거보다 자동으로 끝지점과 시작지점에 이벤트를 달아줄수 있다.
<aside> 💡 에셋번들이나, 어드레서블에서 로드하는게 아니라면 해당 호출로 인하여 실제 애니메이터 클립에 이벤트가 추가되는 현상이 있으니 주의하자! (주로 리소스는 타 프로젝트에서 에셋번들로 빌드후 로드했기 때문에 이런현상은 나오지 않았지만 리소스 로드를 했을때는 주의하도록 하자!)
</aside>
그리고 또하나의 방법은 코루틴을 이용하여 체크하는 방법도 있다.
{
Animator animator = GetComponent<Animator>();
StartCoroutine(startAnim(animator, animCallbackHandler));
}
private void animCallbackHandler()
{
print("callback");
}
private IEnumerator startAnim(Animator animator, Action callBack)
{
animator.SetBool(ANIMATOR_SELECT_PARAM, true);
yield return new WaitForEndOfFrame();
float animationTime = animator.GetCurrentAnimatorClipInfo(0).Length;
yield return new WaitForSeconds(animationTime);
callBack?.Invoke();
yield break;
}
<aside> 💡 여기서 애니메이터에 SetBool하여 상태를 변경후 한 프레임을 기다리는 이유는 다음 애니메이션은 바로 전환되지 않고 다음프레임에 전환되기 때문에 변경되는 애니메이션 클립의 Length를 구하기 위해 필요하다.
</aside>