CSharp 이벤트

양승준·2025년 5월 16일

CSharp

목록 보기
20/20
post-thumbnail

Unity C# Action / Event / UnityEngine.Event / UnityEngine.Events.UnityEvent 학습 정리

1. Action

항목내용
정의.NET(C#) 기본 제공 delegate 타입
용도콜백, 간단한 이벤트 처리
특징가볍고 빠름, 코드 전용
인스펙터 표시❌ 표시 안 됨

예제

using System;
using UnityEngine;

public class ActionExample : MonoBehaviour
{
    public Action onPlayerDead;

    void Start()
    {
        onPlayerDead += PlayerDied;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.K))
            onPlayerDead?.Invoke();
    }

    void PlayerDied()
    {
        Debug.Log("Player has died!");
    }
}

2. Event (C# Event Keyword)

항목내용
정의delegate 기반의 C# 이벤트 시스템
용도외부에서는 +=, -= 등록/삭제만 허용 (호출 금지)
특징캡슐화 강화
인스펙터 표시❌ 표시 안 됨

예제

using System;
using UnityEngine;

public class CSharpEventExample : MonoBehaviour
{
    public event Action onGameStart;

    void Start()
    {
        onGameStart += GameStarted;
        onGameStart?.Invoke();
    }

    void GameStarted()
    {
        Debug.Log("Game Started!");
    }
}

3. UnityEngine.Event

항목내용
정의Unity의 GUI/입력 시스템 이벤트 객체
용도GUI/키보드, 마우스 입력 검사
특징OnGUI() 내에서 사용
인스펙터 표시❌ 표시 안 됨

예제

using UnityEngine;

public class UnityEngineEventExample : MonoBehaviour
{
    void OnGUI()
    {
        Event e = Event.current;
        if (e.type == EventType.KeyDown && e.keyCode == KeyCode.Space)
        {
            Debug.Log("Space Key Pressed!");
        }
    }
}

4. UnityEngine.Events.UnityEvent

항목내용
정의Unity 사용자 지정 가능 Inspector 이벤트 클래스
용도Inspector에서 함수 연결
특징Inspector 표시, AddListener/RemoveListener 가능
인스펙터 표시✅ 표시 됨

예제

using UnityEngine;
using UnityEngine.Events;

public class UnityEventExample : MonoBehaviour
{
    public UnityEvent onButtonPressed;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            onButtonPressed?.Invoke();
        }
    }
}

판단 포인트 비교표

구분ActionEventUnityEngine.EventUnityEvent
활용코드 컨트롤안전한 코드 이벤트GUI/키보드 입력 검사Inspector 함수 연결
가시성
이벤트 다중 등록가능가능불가능 (1회성)가능
주 사용처내부 콜백외부 호출 제한 이벤트OnGUI(), 에디터 입력UI/게임 이벤트 및 시각 연결

요약 정리

  • Action: 가볍고 빠른 코드 콜백에 적합
  • Event: 외부 안전성을 위한 캡슐화된 Action
  • UnityEngine.Event: OnGUI 기반 입력 처리 전용 (GUI 시스템)
  • UnityEvent: Unity Inspector에서 함수 연결 가능한 이벤트 시스템

활용 예시 통합: InGameManager

UnityEvent를 포함하여 상태별 이벤트 분기 처리 예시입니다:

using Scripts;
using UnityEngine;
using UnityEngine.Events;

public class InGameManager : MonoBehaviour
{
    private bool _isFirstFrameCheck = false;

    [SerializeField] private GamePlayState _playState;
    [SerializeField] private GameResultState _resultState;

    [SerializeField] private GameObject _playerObject;
    private PlayerHp _playerHpCmp;

    [SerializeField] private float _inGameClearMinutes = 5.0f;
    private float _inGameClearTime;
    private float _inGameStartTime;
    private float _inGameCurrenttTime;

    public UnityEvent PlayingEvent;
    public UnityEvent PausedEvent;
    public UnityEvent StoppedEvent;

    private void Start()
    {
        InitializePlayer();
        InitializeTime();
        InitializeState();
    }

    private void Update()
    {
        CheckFirstFrame();
        CheckResultState();
        UpdateTime();
    }

    private void InitializePlayer()
    {
        if (_playerObject == null)
            _playerObject = GameObject.FindGameObjectWithTag("Player");

        if (_playerObject != null)
            _playerHpCmp = _playerObject.GetComponent<PlayerHp>();
    }

    private void InitializeTime()
    {
        _inGameClearTime = _inGameClearMinutes * 60.0f;
        _inGameStartTime = 0;
        _inGameCurrenttTime = _inGameStartTime;
    }

    private void InitializeState()
    {
        _resultState = GameResultState.None;
        _playState = GamePlayState.Playing;
    }

    private void UpdateTime()
    {
        _inGameCurrenttTime += Time.deltaTime;
    }

    private void CheckFirstFrame()
    {
        if (_isFirstFrameCheck) return;

        _isFirstFrameCheck = true;
        PlayingEvent?.Invoke();
    }

    private void CheckResultState()
    {
        if (_resultState != GameResultState.None)
            return;

        if (_playerHpCmp.CurrentHealth <= 0)
            _resultState = GameResultState.Fail;
        else if (_inGameClearTime <= _inGameCurrenttTime)
            _resultState = GameResultState.Clear;
    }

    public void SetPlayState(GamePlayState state)
    {
        _playState = state;

        switch (state)
        {
            case GamePlayState.Playing:
                PlayingEvent?.Invoke();
                break;
            case GamePlayState.Paused:
                PausedEvent?.Invoke();
                break;
            case GamePlayState.Stopped:
                StoppedEvent?.Invoke();
                break;
        }
    }
}

profile
지모창말, 미모창.

0개의 댓글