ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 유니티 이벤트 완벽하게 이해하기 1
    Unity, C#/Event 2019. 2. 18. 18:43

    유니티 이벤트에 대해 정리해 보았습니다.

     

     

    Unity 이벤트

     

    C#의 이벤트와 델리게이트를 유니티가 사용하기 편하도록 랩핑 해놓은 것입니다.

    이벤트를 발동시키는 측도 그 이벤트에 기능을 등록시켜놓은 측도 서로에게 관심이 없도록 함으로써

    코드가 스파게티처럼 엮이지 않도록 합니다. 

     

    ex) 플레이어가 죽었을 때 일어나는 각종 상황

    UI에 "죽었음" 출력

    - 도전과제 출력

    - 게임 재시작

     


     

    이벤트를 사용하지 않을 때

     

    UIManager.cs

    - UI를 사용하기 위해 using UnityEngine.UI; 를 추가합니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
     
    public class UIManager : MonoBehaviour {
     
        public Text playerStateText;
        public void OnPlayerDead()
        {
            playerStateText.text = "You Die!!!";
        }
    }
    cs

     

    EventManager.cs

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.SceneManagement;
     
    public class GameManager1 : MonoBehaviour {
     
        public void OnPlayerDead()
        {
            Invoke("Restart", 5f);
        }
     
        private void Restart()
        {
            SceneManager.LoadScene(0); // 0 : 현재씬
        }
    }
    cs

     

     

    AchievementSystem.cs

    - UI를 사용하기 위해 using UnityEngine.UI; 를 추가합니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
     
    public class AchievmentSystem : MonoBehaviour {
        public Text achivementText;
     
        public void UnLockachivement(string title)
        {
            Debug.Log("도전과제 해제!!! - " + title);
            achivementText.text = "도전과제 해제 : " + title;
        }
     
    }
    cs

     

     

    PlayerHealth.cs

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
     
    public class PlayerHealth : MonoBehaviour {
     
        public UIManager uiManager;
        public AchievementSystem achivementSystem;
        public GameManager gameManager;
     
        private void Dead()
        {
            uiManager.OnPlayerDead();
            achivementSystem.UnLockachivement("뉴턴의 법칙");
            gameManager.OnPlayerDead();
     
            Debug.Log("죽었다!");
            Destroy(gameObject);
        }
     
        void OnTriggerEnter(Collider other)
        {
            Dead();
        }
    }
    cs

    이벤트를 사용하지 않으면 PlayerHealth 클래스에서 UIManager, AchievementSystem,

    GameManager를 모두 가지고 있어야 합니다. 

    나중에 플레이어의 죽음에 영향을 받는 다른 클래스가 생성되면 그 클래스도 

    추가해 줘야 합니다. 그러다 보면 코드가 점점 복잡해 지고, 서로의 코드에 영향을 받게

    됩니다.


     이벤트를 사용할 때 (Unity에서 만들어 놓은 이벤트를 사용합니다.)

     

     

    Player 아래에 Dead라는 Event를 만들고 거기에 UIManager / GameManager / AchievementSystem

    에서 Dead라는 Event에 자신들의 함수를 등록해 둡니다. 

    Player는 Dead에 어떤 함수가 등록되어 있는지 알지 못합니다. 상대방은 언제 함수가 실행될지 알 수

    없습니다. 

     

     

    UIManager.cs / UIManager.cs / AchievementSystem.cs 는 위 코드와 같습니다.

     

    PlayerHealth.cs

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Events;  // 유니티 이벤트를 사용하기 위해 필요합니다.
     
    public class PlayerHealth : MonoBehaviour {
     
        public UnityEvent onPlayerDead;
     
        private void Dead()
        {
            onPlayerDead.Invoke(); // Invoke : 발동하다.
        }
     
        void OnTriggerEnter(Collider other)
        {
            Dead();
        }    
    }
    cs

     

    유니티 이벤트를 사용함으로써 코드가 깔끔해졌습니다. 

    플레이어의 죽음에 영향을 받는 클래스가 증가하더라도 더이상 PlayerHealth.cs 의 코드가 늘어나지도 않습니다.

     

     

    유니티 에디터에 보면 Player Health에 위와 같은 리스트가 추가 되어 있는데 이것이 UnityEvent 입니다. 

    여기에 플레이어가 죽었을 때 같이 실행되길 바라는 클래스의 함수를 연결해 주면 됩니다. (public 함수만 연결이 가능합니다.)

    이제 플레이어가 죽으면 위에 연결해 놓은 함수들이 차례대로 실행이 됩니다. 

     

    참고로 UGUI에서 Button 을 만들면 OnClick 이라는 것을 볼 수 있는데 이것도 UnityEvent 입니다. 

     

     

    결론적으로 UnityEvent를 사용하면 

     

    1. 코드가 깔끔해져서 보기가 편합니다.

    2. 클래스끼리 서로 연결되어 있지 않기 때문에 확장성이 뛰어납니다.

    3. 일반적인 C# 델리게이트와 이벤트를 사용하면 같은 형태의 함수만 등록 가능하지만 UnityEvent를 사용하면 다른

        형태의 함수도 등록이 가능합니다. 

     

     
     

    댓글

Designed by Tistory.