개발/유니티

[유니티] 델리게이트와 이벤트

kimchangmin02 2025. 7. 18. 20:53

1-1

개념

 

우유 카드를 받은뒤,

 

 

 

event가 발생하면

 

 

그제서야 우유 사러가는 아이랑 비슷

1. 델리게이트(Delegate)는 바로 '심부름 쪽지'📜야!

엄마가 너한테 심부름을 시킬 거야.
그런데 지금 당장 시키는 게 아니라, 쪽지에 적어서 줬어.

[심부름 쪽지]

받는 사람: 우리 아들/딸

할 일: 슈퍼마켓 가서 우유 사오기!

이 **'심부름 쪽지'**가 바로 **델리게이트(Delegate)**야!

  • '우유 사오기'라는 임무(함수) 자체는 아니지?
  • 대신 **'어떤 임무를 해야 하는지'**를 적어놓은 **종이(변수)**잖아.
  • 이 쪽지를 가지고 있다가, 나중에 필요할 때 보고 심부름을 할 수 있어.

컴퓨터 세상에서는 "나중에 이 일을 시켜줘!" 하고 '할 일(함수)'을 담아두는 특별한 쪽지가 바로 델리게이트야.


2. 이벤트(Event)는 바로 '초인종' 띵동!🔔 이야!

자, 너는 '우유 사오기' 심부름 쪽지를 들고 신나게 놀고 있어.
언제 심부름을 가야 할지 모르겠지?

그때 갑자기 현관에서 "띵동!" 하고 초인종이 울렸어.
엄마가 "초인종 울리면 슈퍼 다녀와~" 라고 약속했거든.

 "띵동!" 하는 초인종 소리가 바로 **이벤트(Event)**야!

  • "어떤 사건이 발생했다!"는 신호인 거지.
  • 예를 들어 "손님이 왔다!", "택배가 왔다!" 같은 신호 말이야.

컴퓨터 세상에서는 "플레이어가 점프 버튼을 눌렀다!", "몬스터가 나타났다!" 같은 '사건 발생 신호'가 바로 이벤트야.


3. 그래서 둘이 합치면 어떻게 될까?

자, 이제 합쳐보자!

  1. [준비] 엄마가 너한테 **'우유 사오기' 심부름 쪽지(델리게이트)**를 줬어.
  2. [사건 발생!] 초인종이 "띵동!"(이벤트) 하고 울렸어.
  3. [실행!] 너는 그 소리를 듣고, "아! 초인종이 울렸네!" 하면서 가지고 있던 **심부름 쪽지(델리게이트)**를 보고 "우유 사오기" 심부름을 하러 가는 거야!

이걸 유니티 게임에 그대로 옮겨볼게.

  1. [준비] 개발자가 컴퓨터에게 **'캐릭터 점프시키기' 방법이 적힌 쪽지(델리게이트)**를 만들어 줘.
  2. [사건 발생!] 플레이어가 스페이스 바를 "탁!"(이벤트) 하고 눌렀어.
  3. [실행!] 컴퓨터는 "오! 스페이스 바가 눌렸네!" 하면서 **'캐릭터 점프시키기' 쪽지(델리게이트)**를 보고 캐릭터를 폴짝 뛰게 만들어!

플레이어가 점프 버튼을 누르면 (이벤트 발생! 🔔)

→ 캐릭터가 점프하는 방법을 실행시켜라! (델리게이트 실행! 📜)

⭐ 이게 왜 중요할까?

만약에 **초인종(이벤트)**이 울렸을 때 여러 가지 일을 시키고 싶으면 어떡할까?

  • (너는) 우유 사러 가기
  • (아빠는) 현관문 열어주기
  • (강아지는) 멍멍 짖기

이렇게 '초인종'이라는 신호 하나에 **여러 개의 '심부름 쪽지'**를 연결해 놓을 수 있어. 그래서 엄청 편하고 깔끔하게 프로그램을 만들 수 있는 거야!


딱 세 줄 요약!

  • 델리게이트(Delegate): "이거 해!" 라고 시킬 미래의 심부름 쪽지 📜
  • 이벤트(Event): "지금이야!" 라고 알려주는 신호탄 또는 초인종 🔔
  • 게임에서는: 버튼 누르면(이벤트!) → 점프해라(델리게이트)! 이렇게 쓰여

 

 

 

 

 

 

1-2

코드

 

// using UnityEngine; // 유니티에서 쓸 거니까 맨 위에 적어주자!

// 1. 심부름 쪽지 양식(Delegate) 만들기
// "이런 형태의 심부름을 담을 수 있는 쪽지입니다~" 하고 컴퓨터에게 알려주는 거야.
public delegate void PlayerAction(); // 플레이어가 할 행동(Action)이라는 뜻!

 

 

 

 

// 2. 실제 심부름 내용(메서드) 만들기
// 위에서 만든 PlayerAction 쪽지 양식과 모양이 똑같아야 해! (void, 빈 괄호)

void Jump()
{
    Debug.Log("캐릭터가 하늘 높이 점프했다!");
}

void SayHooray()
{
    Debug.Log("만세! 게임에서 이겼다!");
}

 

 

 

 

 

public class Character : MonoBehaviour
{
    // 1. 심부름 쪽지 양식 (Delegate)
    public delegate void PlayerAction();

    // 3. "점프 버튼 누르면" 이라는 신호를 줄 초인종(Event) 만들기
    // 이 초인종이 울리면 PlayerAction 형태의 심부름들이 실행될 거야.
    public event PlayerAction OnPlayerJump;


    // 4. 게임이 시작되면, 초인종에 심부름들을 연결(등록)해놓자!
    void Start()
    {
        // OnPlayerJump 라는 초인종이 울리면...
        OnPlayerJump += Jump;       // Jump 심부름도 실행하고,
        OnPlayerJump += SayHooray;  // SayHooray 심부름도 실행해라!
    }

    // ... (아래에 심부름 내용과 초인종 누르는 코드가 이어집니다)
}

 

 

 

 

 

1-3

이해안되는 부분

(자바랑 메소드 선언이 좀 다른것같은데)

 

 

 

 

1-3(1)

이건 '메서드 구현'이 아니에요 -> '규칙(타입) 선언'이에요

// "앞으로 'PlayerAction'이라는 이름을 '메서드를 담는 특별한 변수 타입'으로 사용하겠다"
// "이 변수에는 void 리턴과 파라미터 없는 메서드만 담을 수 있다"는 약속!
public delegate void PlayerAction();

 

 

 

 

1-3(2)

이것도 '메서드 구현'이 아니에요 -> '변수 선언'이에요

// "PlayerAction 타입의 특별한 변수를 만드는데, 이름은 OnSpaceBarPressed 이다."
// "event 키워드를 붙여서 안전하게 만들겠다."
public event PlayerAction OnSpaceBarPressed;

 

이건 '변수'를 선언하는 거예요. int a;  String name; 처럼요.

  • PlayerAction: 변수의 타입 (우리가 위에서 발명한 '메서드 담는 타입')
  • OnSpaceBarPressed: 변수의 이름
  • event: 이 변수를 좀 더 안전하게 만들어주는 특별한 옵션

즉, OnSpaceBarPressed 라는 변수는 이제 Jump()  Cheer() 같은 메서드들을 저장할 수 있는 공간이 된 거예요.

 

 

1-3(3)

OnSpaceBarPressed += Jump; <왜 ()가 없지???

    • Jump() (괄호 있음): "지금 당장 Jump 메서드를 실행해라!" 라는 명령입니다.
    • Jump (괄호 없음): Jump 라는 메서드(함수) 그 자체, 즉 기능 설명서를 의미합니다.

OnSpaceBarPressed += Jump; 이 코드는,
"OnSpaceBarPressed 라는 심부름 목록 '점프하기'라는 심부름 쪽지 자체를 추가해줘" 라는 뜻입니다.

우리는 지금 '초인종이 울리면 뭘 할지' 목록을 만드는 중이지, '지금 당장 점프'를 시키는 게 아니잖아요?

 

 

 

 

1-3(4)

OnSpaceBarPressed가 뭔가 심부름 목록같은데, 왜지
아 delegate 를 선언해서?