이벤트 호출마다 다른 함수 호출

Jinho Lee·2024년 11월 29일
0

개요

  • 이벤트가 Invoke 될때마다 다른 함수가 호출되도록 하고 싶다. 어떤 방법이 가능할까?

  • Unity에서 이벤트가 Invoke될 때마다 다른 함수가 호출되도록 하려면, 이벤트 핸들러의 동작을 유동적으로 변경할 수 있는 다양한 방법이 있다. 아래에서 각각의 방법을 설명합니다.

방법

1. 다이나믹 리스너 관리

UnityEvent.RemoveListenerUnityEvent.AddListener를 사용하여 이벤트를 Invoke하기 전에 다른 리스너를 등록하거나 제거하는 방법입니다.

  • 코드 예제
using UnityEngine;
using UnityEngine.Events;

public class DynamicEventExample : MonoBehaviour
{
    public UnityEvent myEvent = new UnityEvent();
    private int callCount = 0;

    private void Start()
    {
        // 첫 리스너 등록
        AddNextListener();

        // 여러 번 Invoke 호출
        myEvent.Invoke();
        myEvent.Invoke();
        myEvent.Invoke();
    }

    private void AddNextListener()
    {
        myEvent.RemoveAllListeners(); // 이전 리스너 제거

        if (callCount == 0)
        {
            myEvent.AddListener(Function1);
        }
        else if (callCount == 1)
        {
            myEvent.AddListener(Function2);
        }
        else if (callCount == 2)
        {
            myEvent.AddListener(Function3);
        }

        callCount++; // 다음 호출을 위한 증가
    }

    private void Function1()
    {
        Debug.Log("Function 1 Called");
        AddNextListener(); // 다음 리스너로 교체
    }

    private void Function2()
    {
        Debug.Log("Function 2 Called");
        AddNextListener(); // 다음 리스너로 교체
    }

    private void Function3()
    {
        Debug.Log("Function 3 Called");
        AddNextListener(); // 다음 리스너로 교체
    }
}

2. 큐(Queue)를 사용한 함수 호출

함수 호출 순서를 큐로 관리하여 이벤트 호출 시마다 큐의 다음 함수가 실행되도록 합니다.

  • 코드 예제
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class QueueEventExample : MonoBehaviour
{
    public UnityEvent myEvent = new UnityEvent();
    private Queue<UnityAction> functionQueue = new Queue<UnityAction>();

    private void Start()
    {
        // 함수 등록
        functionQueue.Enqueue(Function1);
        functionQueue.Enqueue(Function2);
        functionQueue.Enqueue(Function3);

        // 이벤트에 처리 함수 등록
        myEvent.AddListener(InvokeNextFunction);

        // 여러 번 Invoke 호출
        myEvent.Invoke();
        myEvent.Invoke();
        myEvent.Invoke();
    }

    private void InvokeNextFunction()
    {
        if (functionQueue.Count > 0)
        {
            UnityAction nextFunction = functionQueue.Dequeue();
            nextFunction.Invoke(); // 다음 함수 실행
        }
        else
        {
            Debug.Log("No more functions in the queue.");
        }
    }

    private void Function1()
    {
        Debug.Log("Function 1 Called");
    }

    private void Function2()
    {
        Debug.Log("Function 2 Called");
    }

    private void Function3()
    {
        Debug.Log("Function 3 Called");
    }
}

3. 이벤트 핸들러 동적으로 생성

이벤트 핸들러를 동적으로 변경하여 매 호출 시 새로운 동작을 지정합니다.

  • 코드 예제
using UnityEngine;
using UnityEngine.Events;

public class DynamicHandlerExample : MonoBehaviour
{
    public UnityEvent myEvent = new UnityEvent();
    private int callCount = 0;

    private void Start()
    {
        myEvent.AddListener(() => OnEventCalled(callCount));
        
        // 여러 번 Invoke 호출
        myEvent.Invoke();
        callCount++;
        myEvent.Invoke();
        callCount++;
        myEvent.Invoke();
    }

    private void OnEventCalled(int callIndex)
    {
        switch (callIndex)
        {
            case 0:
                Debug.Log("First Function Called");
                break;
            case 1:
                Debug.Log("Second Function Called");
                break;
            case 2:
                Debug.Log("Third Function Called");
                break;
            default:
                Debug.Log("No more functions.");
                break;
        }
    }
}

4. 리스트로 함수 관리

리스트에 여러 함수를 저장하고, 호출될 때마다 리스트에서 순차적으로 함수를 호출합니다.

  • 코드 예제
using System.Collections.Generic;
using UnityEngine;

public class ListEventExample : MonoBehaviour
{
    public UnityEvent myEvent = new UnityEvent();
    private List<System.Action> functionList = new List<System.Action>();
    private int currentIndex = 0;

    private void Start()
    {
        // 함수 등록
        functionList.Add(Function1);
        functionList.Add(Function2);
        functionList.Add(Function3);

        // 이벤트 등록
        myEvent.AddListener(InvokeNextFunction);

        // 여러 번 Invoke 호출
        myEvent.Invoke();
        myEvent.Invoke();
        myEvent.Invoke();
    }

    private void InvokeNextFunction()
    {
        if (currentIndex < functionList.Count)
        {
            functionList[currentIndex]?.Invoke();
            currentIndex++;
        }
        else
        {
            Debug.Log("No more functions in the list.");
        }
    }

    private void Function1()
    {
        Debug.Log("Function 1 Called");
    }

    private void Function2()
    {
        Debug.Log("Function 2 Called");
    }

    private void Function3()
    {
        Debug.Log("Function 3 Called");
    }
}

5. 상태 기반 함수 호출

이벤트를 호출할 때마다 상태를 바꾸고, 상태에 따라 호출할 함수를 결정합니다.

  • 코드 예제
using UnityEngine;

public class StateEventExample : MonoBehaviour
{
    public UnityEvent myEvent = new UnityEvent();
    private int state = 0;

    private void Start()
    {
        myEvent.AddListener(CallBasedOnState);

        // 여러 번 Invoke 호출
        myEvent.Invoke();
        myEvent.Invoke();
        myEvent.Invoke();
    }

    private void CallBasedOnState()
    {
        switch (state)
        {
            case 0:
                Function1();
                break;
            case 1:
                Function2();
                break;
            case 2:
                Function3();
                break;
            default:
                Debug.Log("No more states.");
                break;
        }

        state++; // 다음 상태로 전환
    }

    private void Function1()
    {
        Debug.Log("Function 1 Called");
    }

    private void Function2()
    {
        Debug.Log("Function 2 Called");
    }

    private void Function3()
    {
        Debug.Log("Function 3 Called");
    }
}

어떤 방법을 선택해야 할까?

  1. RemoveListenerAddListener:
    간단한 리스너 교체가 필요할 때.
  2. Queue 사용:
    함수 호출 순서를 명확히 관리해야 할 때.
  3. 다이나믹 핸들러:
    상태 기반의 다이나믹한 함수 호출이 필요할 때.
  4. 리스트 기반 관리:
    여러 함수를 유연하게 추가/제거하거나 순서를 변경해야 할 때.
  5. 상태 기반 호출:
    상태에 따라 분기 로직이 자연스러운 경우.
  • 위 방법 중 작업의 복잡도와 요구사항에 따라 적합한 방법을 선택합니다.

0개의 댓글

관련 채용 정보