유니티 이벤트 완벽하게 이해하기 1
유니티 이벤트에 대해 정리해 보았습니다.
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를 사용하면 다른
형태의 함수도 등록이 가능합니다.