Unity Chapter 8-1. C# 프로그래밍 [고급] : 유니티 이벤트
카테고리: Unity Lesson 1
태그: C Sharp Unity Game Engine
인프런에 있는 이제민님의 레트로의 유니티 C# 게임 프로그래밍 에센스 강의를 듣고 정리한 필기입니다. 😀
🌜 [레트로의 유니티 C# 게임 프로그래밍 에센스] 강의 들으러 가기!
Chapter 8. C# 프로그래밍 : 고급
🔔 유니티 이벤트
유니티 이벤트란? Unity Event
C # 의
delegate
와event
기능을 사용하기 쉽게 유니티에서 제공하는 것
이 포스트에서 유니티 이벤트
에 대해 먼저 공부하여 이벤트에 대해 이해하고 나서, 다음, 다다음 포스트에서 delegate
와 event
에 대해 공부하려고 한다.
이벤트란? Event
- 어떤 이벤트가 발생하면 그 이벤트에 등록해 둔 모든 함수들이 자동으로 발동된다.
- 이벤트를 발생시키는 측도, 이벤트에 등록되있는 함수들도 서로에게 관심이 없다.
- 등록되있는 함수들은 언제 발동될지, 어떻게 발동될지 관심이 없다.
- 이벤트를 발생시키는 측도 자신에게 어떤 함수들이 등록되어있는지 관심이 없다.
- 코드들이 스파게티처럼 엮이지 않아 코드가 간결해진다.
이벤트를 사용하지 않은 경우
- 📜PlayerHelath에서 플레이어가 죽었음을 감지했을 때 일어나는 상황
1. “You Die!” 텍스트를 화면에 띄움
- 📜 UIManager
- 도전 과제가 해제되었다는 메세지를 화면에 출력
- 📜AchivementSystem
- 플레이어가 죽으면 5초 뒤에 게임을 재시작시킨다.
- 📜GameManger
- 📜 UIManager
시작하기에 앞서
- 에셋 스토어에서 “Standard Assets” 이라는 에셋을 Import 하였다.
- Characters - ThirdPersonCharacter - Prefabs - 🟦ThirdPersonConttroller
ThirdPersonConttroller
프리팹을 Hierarchy 창에 옮겨 오브젝트화 시켰다.- 미리 WASD 로 플레이어 오브젝트를 조작할 수 있게끔 구현이 되어 있다.
Plane
오브젝트를 만들어 플레이어가 서 있을 바닥을 만들어 주었다.RedZone
이라는 이름의 큐브 오브젝트를 만든 후Plane
보다 아래에 위치하게 한 후 스케일 툴로 크기를 늘려 준다.Plane
바닥으로부터 떨어져 이 곳에 닿으면 플레이어가 죽고 게임이 재시작 되게끔 만들 것이다.- Collider 컴포넌트에서 Is Trigger에 체크 해준다. (레드존에 닿으면 죽게끔 충돌 처리를 해주어야 하기 때문에)
📜UIManager.cs
- UI - Text를 만들어 준 후 이름을
Player State Text
로 바꿔준다.- 플레이어가 죽으면 이 텍스트를 화면에 띄울 것.
- 앵커 프리셋을 Alt키 누르고 stretch - stretch 로 해주고
- 가운데, 중앙 정렬
- Best Fit에 체크해준다.
- 📜UIManager.cs 를 Canvas에 붙여준다.
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!";
}
}
- OnPlayerDead()
- 플레이어가 죽으면 “You Die!” 메세지를 화면에 띄운다.
- 📜PlayerHealth.cs 에서 플레이어가 죽었을 때 실행시킬 것이다.
- playerStateText 슬롯에
Player State Text
을 넣어준다.
📜AchivementSystem.cs
- 기존 Canvas 안에 또 다른 UI - Text를 만들어준 후 이름을
Achivement Text
로 해준다. - 앵커 프리셋을 Alt키 누르고 stretch - stretch 로 해주고
- 오른쪽, 상단 정렬
- Best Fit에 체크해준다.
- 📜AchivementSystem.cs 를 Canvas에 붙여준다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; // ⭐⭐⭐
public class AchivementSystem : MonoBehaviour
{
public Text achivementText;
public void UnLockAchivement(string title)
{
Debug.Log("도전과제 해제! " + title);
achivementText.text = "도전과제 해제: " + title;
}
}
- UnLockAchivement(string title)
- 플레이어가 죽으면 도전 과제가 해제되었다는 메세지를 화면에 출력하게 할 것.
- 📜PlayerHealth.cs 에서 플레이어가 죽었을 때 실행시킬 것이다.
- achivementText 슬롯에
Achivement Text
을 넣어준다.
📜GameManager.cs
- 플레이어가 죽으면 5초 뒤에 게임을 재시작 시킨다.
- 📜GameManager.cs를
GameManager
라는 이름의 빈 오브젝트를 만들어 여기에 붙여준다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public void OnPlayerDead()
{
Invoke("Restart", 5f);
}
private void Restart()
{
SceneManager.LoadScene(0);
}
}
- OnPlayerDead()
- 플레이어가 죽으면 5초 뒤에 Restart() 함수를 발동시킨다.
- 📜PlayerHealth.cs 에서 플레이어가 죽었을 때 실행시킬 것이다.
- Restart()
- 5초 뒤에 게임을 재시작한다.
📜PlayerHealth.cs
ThirdPersonConttroller
오브젝트에 붙여준다.- 플레이어가
RedZone
에 닿으면 죽게끔 만드는 처리를 한다.
- 플레이어가
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerHealth : MonoBehaviour
{
public UIManager uiManager;
public AchivementSystem achivementSystem;
public GameManager gameManager;
private void Dead()
{
uiManager.OnPlayerDead();
achivementSystem.UnLockAchivement("뉴턴의 법칙");
gameManager.OnPlayerDead();
Debug.Log("죽었다!");
Destroy(gameObject);
}
void OnTriggerEnter(Collider other)
{
Dead();
}
}
- OnTriggerEnter 이벤트가 발생하면, 즉 플레이어가 죽으면
- Dead() 함수 실행
- 📜UIManager - “You Die!” 텍스트를 화면에 띄움
- 📜AchivementSystem - 도전 과제가 해제되었다는 메세지를 화면에 출력
- 📜GameManger - 플레이어가 죽으면 5초 뒤에 게임을 재시작시킨다.
- Destroy(gameObject); : 플레이어 오브젝트를 파괴한다.
- Dead() 함수 실행
- (uiManager, achivementSystem, gameManager) 각 슬롯에 각 스크립트들이 붙은 오브젝트들을 드래그 앤 드롭해준다.
유니티 이벤트를 사용하는 이유
- ⚡문제점⚡
- 실행시키는 측, 실행 되는 측 둘다 서로를 알고 있고 연결되어 있어야 한다는게 문제점.
- 📜PlayerHealth.cs 은 📜UIManager, 📜AchivementSystem, 📜GameManger 이 3개를 다 알고 있어야 한다.
- 각 3개 스크립트를 참조할 수 있는 변수를 선언하고 (uiManager, achivementSystem, gameManager)
- 유니티 슬롯에 각 3개의 스크립트가 붙어있는 오브젝트들을 죄다 드래그 앤 드롭 해주어야 함
- 그러나 📜AchivementSystem 는 보통 게임 제작이 완료된 후에 만든다. 📜PlayerHealth.cs 을 쓸 때에는 📜AchivementSystem 에 대한 정보를 모를 수 있다.
- 📜PlayerHealth.cs 은 딱 플레이어의 체력에 관한 내용만 들어가는게 좋은데 📜UIManager, 📜AchivementSystem, 📜GameManger 등등 여러 다른 오브젝트들까지 다 알고 있어야 함.
- 플레이어와 관련된 기능이 추가될 때마다 📜PlayerHealth.cs 에 또 참조할 수 있는 변수를 추가해야 한다.
- 따라서 스파게티 코드가 될 확률이 높다.
- 코드가 점점 복잡해지고
- 서로의 코드에 영향을 많이 받게 된다.
- 📜PlayerHealth.cs 은 📜UIManager, 📜AchivementSystem, 📜GameManger 이 3개를 다 알고 있어야 한다.
- 이벤트가 발생할시 실행되야 할 함수가 많다면 일일이 노가다로 유니티 슬롯에서 다 드래그 앤 드롭 해주어야 하는 불편이 따른다.
- 실행시키는 측, 실행 되는 측 둘다 서로를 알고 있고 연결되어 있어야 한다는게 문제점.
유니티 이벤트를 사용한 경우
using UnityEngine.Events
를 해주어야 한다.
유니티 이벤트 원리
실행 시키는 이벤트 측, 실행 되는 측. 둘 다 서로를 모른다. 그저 이벤트에 등록해놔서 발동되는 것일 뿐.
- 실행시키는 측, 실행 되는 측 둘다 서로를 몰라도 이벤트에 등록만 되어 있다면 알아서 실행된다.
- 따라섯 스파게티처럼 연결될 필요가 없어 코드가 훨씬 깔끔해진다.
- 플레이어가 죽는 이벤트인 📜PlayerHealth.cs 의 Dead() 이벤트에
- 플레이어가 죽으면 동시에 발동시킬 📜UIManager, 📜AchivementSystem, 📜GameManger 의 각 함수를 등록한다.
- 📜PlayerHealth.cs 과 📜UIManager, 📜AchivementSystem, 📜GameManger 는 서로에 대해 몰라도 된다. 서로에 대해 참조하고 있을 필요가 전혀 없다.
- 플레이어가 죽은 후 발동시킬 함수를 가진 오브젝트(스크립트)들을 유니티 슬롯에 일일이 넣어줄 필요도 없고
- 플레이어가 죽은 후 발동시킬 스크립트가 추가되더라도 또 참조 변수를 새로 선언해줄 필요가 없다.
- 그저 이벤트에 추가 등록해주면 될 뿐이다.
- 📜PlayerHealth.cs 의 입장 : 난 너희들이 누군지 모르지만 Dead() 이벤트에 등록되 있다면 Dead() 가 실행될 때 알아서 실행 되세요.
📜PlayerHealth.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class PlayerHealth : MonoBehaviour
{
public UnityEvent onPlayerDead;
private void Dead()
{
onPlayerDead.Invoke();
Debug.Log("죽었다!");
Destroy(gameObject);
}
void OnTriggerEnter(Collider other)
{
Dead();
}
}
- using UnityEngine.Events;
- 유니티 이벤트를 사용하기 위해선 필수
- public UnityEvent
onPlayerDead
onPlayerDead
라는 이벤트를 선언했다.
- onPlayerDead.Invoke();
- Dead() 함수 내부에서
onPlayerDead
이벤트를 발동시킨다. onPlayerDead
이벤트에 등록된 타 스크립트의 모든 함수들이 발동된다.
- Dead() 함수 내부에서
- 코드가 훨씬 간결해졌다!
- 실행할 함수를 가진 타 스크립트들을 참조하고 일일이 함수를 실행해 줄 필요가 없어졌으므로.
유니티 이벤트 등록하기
이벤트가 발동 할 시 실행될 함수 명단 등록
- 플레이어가 죽는 이벤트가 발생할시 실행시킬 함수가 속해 있는 스크립트가 붙은 오브젝트들을 드래그 앤 드롭 해준다.
GameManager
- 📜GameMangerCanvas
- 📜UIManager, 📜AchivementSystem
- 실행할 함수를 드롭 다운에서 선택해준다.
- “뉴턴의 법칙”에서 볼 수 있듯 매개변수가 있는, 입력이 필요한 함수들은 여기에 인수로 넘길 입력 내용도 같이 적어줄 수 있다.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기