Action 델리게이트

Hyeon O·2025년 5월 19일

개요

미리 정의된 델리게이트 타입인 Action에 대해서 정리해본다.

기본 개념

델리게이트는 메서드를 변수처럼 사용할 수 있게하는 도구로

반환형이 없는 Action,

반환형이 있는 Func,

커스텀으로 사용하는 delegate,

총 3가지 타입이 있다.

Action은 반환값이 없는 메서드를 참조할 수 있는 델리게이트 타입이다.

즉, void로 선언된 메서드를 참조할 수 있다.

매개변수의 개수에 따라 다양한 오버로드가 존재하고

Action, Action<T>, Action<T1, T2> … 최대 16개까지 매개변수 지원한다.

반대로 반환값이 있는 메서드는 Func 델리게이트를 사용해야 한다.

사용법

기본적인 사용법은 다음과 같다.

using System;

public class DelegateExample
{
    void SayHello()
    {
        Console.WriteLine("Hello!");
    }

    void Run()
    {
		    //델리게이트 연결
        Action sayHello = SayHello;

        // 델리게이트 호출
        sayHello();  // 출력: Hello!
    }
}
//-------------------------------------------------------------
// 람다식으로 표현
using System;

public class DelegateExample
{
    void Run()
    {
        // 람다식으로 바로 구현
        Action sayHello = () => Console.WriteLine("Hello!");
        sayHello();  // 출력: Hello!
    }
}
//---------------------------------------------------------------
//매개 변수 포함
Action<string> greet = (name) => Console.WriteLine($"Hello, {name}!");
greet("우앜"); 

Action<string, int> showInfo = (name, age) => Console.WriteLine($"{name}은 {age}살입니다.");
showInfo("현오", 25);
구문설명
Action act = MyMethod;일반 함수 연결
act += AnotherMethod;여러 메서드 연결 가능
act -= MyMethod;제거도 가능
act?.Invoke();null 체크 안전 호출

기본적인 사용방법을 바탕으로 유니티에서 사용해보면 다음과 같이 구성할 수 있다.

using System;
using UnityEngine;

public class ActionExample : MonoBehaviour
{
    Action onGameStart;                     // 매개변수 없는 Action 선언
    Action<int> onScoreChanged;            // int 매개변수를 받는 Action 선언

    private int score = 0;

    void Start()
    {
        // 1. Action에 메서드 연결 (메서드 이름 전달)
        onGameStart += GameStart;
        onScoreChanged += UpdateScoreUI;

        // 2. Action 실행
        onGameStart?.Invoke();             // null 체크 후 호출 (이벤트 방식)
        AddScore(10);                      // 점수 추가 함수 호출
    }

    void GameStart()
    {
        Debug.Log("게임이 시작되었습니다!");
    }

    void AddScore(int amount)
    {
        score += amount;

        // 3. 점수 변경 Action 실행
        onScoreChanged?.Invoke(score);     // score 값을 전달하며 실행
    }

    void UpdateScoreUI(int currentScore)
    {
        Debug.Log($"현재 점수: {currentScore}");
    }
}

Action onGameStart; : 인자도 없고 반환값도 없는 메서드를 등록할 수 있는 델리게이트이다.

반면 Action<int> onScoreChanged; 는 인자를 하나 받지만 반환값은 없는 메서드를 등록할 수 있는 델리게이트이다.

이후 Start()에서 델리게이트를 onGameStart += GameStart; 와 같이 메서드를 구독한다.

onGameStart?.Invoke(); 로 메서드를 호출한다. ?를 통해 null이 아닐 경우 호출한다.

유니티에서는 버튼 클릭 이벤트에 Action 델리게이트를 통해서 구현한다.

예를 들어,

public class UIButton : MonoBehaviour
{
    public Action onClick;

    public void OnClick()
    {
        onClick?.Invoke(); // 안전한 호출
    }
}
//----------------------------------------------
public class UIManager : MonoBehaviour
{
    [SerializeField] UIButton myButton;

    void Start()
    {
        myButton.onClick = () => Debug.Log("버튼 클릭됨!");
    }
}

onClick 델리게이트를 선언하고

이벤트 메소드에 델리게이트를 구독하여

안전한 호출이 가능하다.

또 다른 예시로는

public class Enemy : MonoBehaviour
{
    public Action onDeath;

    public void Die()
    {
        Debug.Log("적 사망");
        onDeath?.Invoke();  // 등록된 모든 델리게이트 실행
    }
}
//------------------------------------------------------------
public class GameManager : MonoBehaviour
{
    [SerializeField] Enemy enemy;

    void Start()
    {
        enemy.onDeath += OnEnemyKilled;
    }

    void OnEnemyKilled()
    {
        Debug.Log("적을 처치했습니다!");
    }
}

public Action onDeath; 는 적이 죽었을 때 호출되는 델리게이트로

외부에서 +=연산으로 이벤트 리스너에 등록할 수 있는 델리게이트 필드이다.

onDeath?.Invoke();onDeath 에 등록된 모든 메서드를 호출한다.

null체크는 아무것도 등록되지 않았을 경우에 무시된다.

이 구조는 "죽었을 때 다른 애들이 뭔가 하게 만들고 싶다"는 목적을 위해 "옵저버 패턴"을 간단히 구현한 것과 유사하다.

음 롤에서 다리우스 궁극기로 적을 처치했을 때, 주변 미니언이 공포에 걸리는 이벤트에 이런 방식을 적용할 수 있을 것 같다.

GameManager에 Start()에서 이벤트에 메서드를 등록하고

OnEnemyKilled() 에서 실제 반응을 처리한다.

profile
천천히, 꾸준하게, 끝까지

0개의 댓글