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();
}
}
}
판단 포인트 비교표
| 구분 | Action | Event | UnityEngine.Event | UnityEvent |
|---|
| 활용 | 코드 컨트롤 | 안전한 코드 이벤트 | 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;
}
}
}