본문 바로가기
Development/멋쟁이사자처럼 게임개발 부트캠프

[멋쟁이사자처럼 Unity 게임 부트캠프 4기] 11일차 - 델리게이트 & 이벤트

by jjeondeuk1008 2025. 3. 16.
반응형

[ 목차 ]

     


     

    11일차 ! 곧 2주를 향해 다가간다.

     

    이제 오늘을 마지막으로 C#에 대해 배우고,

    내일부터는 유니티로 넘어간다.

     

    오늘을 포함해 지금까지 배웠던 것을

    이제 게임 만들면서 활용할 것이다. 벌써부터 기대중

     

    그럼 마지막 C# 콘솔 공부 화이띵!!!

     

     

     


     

    1. 델리게이트 (Delegate)

     

    델리게이트(Delegate)는 메시지 출력을 위한 메서드 참조이다.

    string 매개변수를 받고 반환값이 없는 void 메서드를 참조할 수 있는 타입이다.

    class Program
    {
        delegate void MessageHandler(string message);
    
        //델리게이트에 연결할 메서드
        //메서드 형과 타입 이런 게 일치해야 받아줌
        static void DisplayMessage(string message)
        {
            Console.WriteLine($"메시지: {message}");
        }
    
        static void DisplayUpperMessage(string message)
        {
            Console.WriteLine($"대문자 메시지: {message.ToUpper()}");
        }
    
        static void Main(string[] args)
        {
            Console.WriteLine("== 간단한 델리게이트와 이벤트 예제 ===");
    
            //1. 델리게이트 사용해보기
            Console.WriteLine("델리게이트1");
    
            //델리게이트 변수 선어 및 메서드 연결
            //DisplayMessage 메서드를 messageHandler 변수에 할당
            MessageHandler messageHandler = DisplayMessage;
    
            //델리게이트 호출 - 연결된 메서드가 실행됨
            messageHandler("안녕하세요");
    
            //델리게이트 다른 메서드 추가(멀티캐스트 델리게이트)
            //+= 연산자로 메서드 추가
            messageHandler += DisplayUpperMessage;
    
            //여러 메서드가 연결된 델리게이트 호출
            //등록된 모든 메서드가 순사대로 호출됨
            Console.WriteLine("여러 메서드 호출: ");
            messageHandler("Hello ");
        }
    }

     

     

    호출 순서를 알아보자.

     

    1번

    Main에서 시작되는 것이니 기존 호출인 문자열을 출력하고,

     

    2번

    델리게이트 변수 선언 및 메서드에 연결한 것이 다음 실행이다.

    변수에 displayMessage 메서드를 가져온다.

    displayMessage는 (메시지: {message})이다.

     

    3번

    델리게이트를 호출한다.

    (메시지: {message}) 여기에서 message가 "안녕하세요"로 적용되어

     

    이 값이 4번으로 향해

    메시지: 안녕하세요

    이렇게 호출 된다.

     

    5번

    연산자로 메서드를 추가한다.

    연결된 메서드가

     

    6번으로 이동해

    문자열을 하나 호출하고,

    messageHandler("Hello ")

     

    코드가 7번으로 이동해

    메시지: Hello

    이렇게 호출한다.

     

    Hello 값8번으로 이동해

    ToUpper()를 통해 대문자로 변환이 되어

    대문자 메시지: HELLO

    마지막인 호출을 하는 것이다.

     

     

     


     

    2. 이벤트

     

    이벤트는 특정 상황이 발생했을 때 알림을 보내는 것이다.

     

    이벤트헨들러(EventHandler)는 C#에서 제공하는 기본 델리게이트 타입이다.

    이벤트가 발생했을 때 실행될 메서드인 것이다.

     

     

    아래의 예제를 통해 코드 실행 순서에 따라 자세하게 더욱 설명하겠다.

     

    Charater 클래스에서

    Name과 Health로 캐릭터의 이름과 체력을 저장하는 변수이다.

    get만 수정이 가능하며, private set은 외부에서 수정할 수 없게 하였다.

     

    아직 실행은 되지 않는다.

     

    Program 클래스에서

    Hero_OnDamaged 메서드 (이벤트 헨들러)가 정의된다.

     

    아직 실행이 되지 않는다.

     

    우선 Main 함수에서 실행을 시작하게 된다.

    캐릭터 생성으로 Character 객체인 hero를 생성한다. (이름: "용사", 체력: 100)

     

    += 연산자를 통해

    hero의 OnDamaged 이벤트에 Hero_OnDamaged 메서드를 등록한다.

    "이벤트 알림: 용사가 데미지를 입었습니다!" 출력한다.

     

    -= 연산자를 통해

    .Hero_OnDamaged 메서드 이벤트 구독을 취소한다.

    그래서 이벤트가 발생해도 호출되지 않는다.

    //게임 캐릭터 클래스
    class Character
    {
        //속성
        public string Name { get; private set; }
        public int Health { get; private set; }
    
        //이벤트 정의 - 캐릭터가 데미지를 입었을 때 발생
        //EventHandler는 C#에서 제공하는 기본 델리게이트 타입
        //이벤트는 외부에서 직접 호출할 수 없고, +=와 -= 연산자로만 접근 가능
        public event EventHandler OnDamaged;
    
        //생성자
        public Character(string name, int health)
        {
            Name = name;
            Health = health;
        }
    
        //데미지를 입는 메서드
        public void TakeDamage(int amount)
        {
            Health -= amount;
            Console.WriteLine($"{Name}가 {amount}의 데미지를 입었습니다. 남은체력: {Health}");
    
            //이벤트 발생 (구독자가 있는 경우에만)
            //?. 연산자 OnDamaged가 null이 아닐 때만 invoke 메서드 호출
            //EventArgs.Empty는 추가 데이터가 없을 때 사용하는 빈 이벤트 인자
            OnDamaged?.Invoke(this, EventArgs.Empty);
        }
    }
    
    class Program
    {
        //이벤트 핸들러 메서드
        //EventHandler 델리게이트와 일치하는 시그니처를 가져야함
        //sender: 이벤트를 발생시킨 객체 (여기서는 Character 객체)
        //e: 이벤트와 관련된 추가 데이터(여기서는 사용하지 않음)
        static void Hero_OnDamaged(object sender, EventArgs e)
        {
            //sender를 character 타입으로 형변환
            Character character = (Character)sender;
    
            Console.WriteLine($"이벤트 알림: {character.Name}가 데미지를 입었습니다! "
                + $"현재 체력: {character.Health}");
        }
    
        static void Main(string[] args)
        {
            //캐릭터 생성
            Character hero = new Character("용사", 100);
    
            //이벤트 구독 +=
            //이벤트가 발생했을 때 실행될 메서드 등록
            hero.OnDamaged += Hero_OnDamaged;
    
            //데미지 입히기
            //TakeDamage 메서드 내에서 OnDamaged 이벤트가 발생함
            hero.TakeDamage(30);
    
            //이벤트 구독 취소 -=
            //더이상 이벤트 발생시 메서드가 호출되지 않음
            hero.OnDamaged -= Hero_OnDamaged;
            Console.WriteLine("이벤트 구독 취소 ");
            hero.TakeDamage(20);
    
        }
    }

     

     

     

     


     

     

    드디어 마지막 콘솔 공부가 끝이났다.

     

    11일이라는 숫자만 봐서는 짧게 느껴지지만,

    대략 2주에 걸쳐 배웠다.

     

     

    고생했다 . . . . . .

     

    다음에 있을 유니티도 힘내ㅈ ㅏ.. . . .


    목차