Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Tags
more
Archives
Today
Total
관리 메뉴

booooox

[Unity] Animation Event (시작, 끝 이벤트) 본문

Unity/System

[Unity] Animation Event (시작, 끝 이벤트)

booooox 2024. 7. 23. 16:23
반응형

1. Animation Event : 애니메이션 실행 도중 해당 시점에서 호출 되는 이벤트

 

2. 기대효과 : 애니메이션 실행 중 원하는 시점에서 이벤트(함수 등)을 발생 시킬 수 있다.

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

[RequireComponent(typeof(Animator))]
public class AnimationEventDispatcher : MonoBehaviour
{
    [Header("=== Reference ===")]
    private Animator animator;
    private List<AnimationClip> AnimationClipList = new List<AnimationClip>();

    protected virtual void Awake()
    {
        this.TryGetComponent<Animator>(out animator);
        SetAnimationEvent();
    }

    private void SetAnimationEvent()
    {
        // Get AnimationClips
        foreach (var clip in animator.runtimeAnimatorController.animationClips) {
            bool isAnimationStartHandler = false;
            bool isAnimationCompleteHandler = false;

            // For Only One Event
            foreach (var clipEvent in clip.events) {
                if (clipEvent.functionName == "AnimationStartHandler") isAnimationStartHandler = true;
                else if (clipEvent.functionName == "AnimationCompleteHandler") isAnimationCompleteHandler = true;
            }

            // Set Animation Start Event
            if (!isAnimationStartHandler) {
                AnimationEvent animationStartEvent = new AnimationEvent();
                animationStartEvent.time = 0;
                animationStartEvent.functionName = "AnimationStartHandler";
                SetAnimationParameter<string>(ref animationStartEvent, clip.name);
                clip.AddEvent(animationStartEvent);
            }

            // Set Animation Complete Event
            if (!isAnimationCompleteHandler) {
                AnimationEvent animationEndEvent = new AnimationEvent();
                animationEndEvent.time = clip.length;
                animationEndEvent.functionName = "AnimationCompleteHandler";
                SetAnimationParameter<string>(ref animationEndEvent, clip.name);
                clip.AddEvent(animationEndEvent);
            }
            AnimationClipList.Add(clip);
        }
    }

    protected virtual void SetAnimationParameter<T>(ref AnimationEvent animationEvent, T value)
    {
        switch (typeof(T).Name) {
            case nameof(String) :
                animationEvent.stringParameter = Convert.ToString(value);
                break;
            case nameof(Int32) :
                animationEvent.intParameter = Convert.ToInt32(value);
                break;
            case nameof(Single) :
                animationEvent.floatParameter = Convert.ToSingle(value);
                break;  
        }
    }

    protected virtual void AnimationStartHandler(AnimationEvent animationEvent)
    {
        Debug.Log($"{animationEvent.stringParameter} animation start.");
    }

    protected virtual void AnimationCompleteHandler(AnimationEvent animationEvent)
    {
        Debug.Log($"{animationEvent.stringParameter} animation complete.");
    }
}

 

3. 사용법 : 

    1) MonoBehaviour 대신 AnimationEventDispatcher를 상속 시켜준다.

    2) 애니메이션 이벤트를 추가 시 SetAnimationParameter<타입>(ref 이벤트, 타입변수); 를 추가한다.

public class FirstPersonShooting_Anim : AnimationEventDispatcher
{
	...
}

 

4. 주의점 : 부모인 AnimationEventDispatcher 클래스에 사용되는 함수은 ovrride를 사용하여 구현 하여야 한다.

public class FirstPersonShooting_Anim : AnimationEventDispatcher
{
	protected override void AnimationStartHandler(AnimationEvent animationEvent)
	{
   		...
		animationStartAction?.Invoke(animationEvent);
	}

	protected override void AnimationCompleteHandler(AnimationEvent animationEvent)
	{
		...
		animationCompleteAction?.Invoke(animationEvent);
	}
    
	...
}

 

반응형