게임 엔진/Unity

[Unity] 글로벌 이벤트 관리 방법

AlgorFati 2020. 7. 6. 15:25

글로벌 이벤트 관리 방법

이벤트를 관리하는 시스템을 하나 만듦으로서 굉장히 편하게 게임 개발을 진행할 수 있다.

게임오브젝트간의 상호작용이 필요한 상황에서는 필연적으로 종속성이 생길 수 밖에 없다.

하지만 이 종속성을 Event Manager라는 하나의 오브젝트로 모으도록 할 수 있다.

 

내 캐릭터가 어떤 영역에 들어갔을 때, 문이 열리는 상황을 가정해 보자.

문이 열리는 행동을 어떤 영역이 이벤트를 발생시켜서 수행해야 하는데,

객체 간 서로 상호참조를 통해 코드를 구현하면 코드가 너무 지저분해진다.

그러므로 먼저 EventManager 클래스를 생성하자.

 

 

EventManager.cs

EventManager는 게임 내 모든 오브젝트 간 상호작용 이벤트를 다루는 클래스이다.

싱글턴 클래스로 설계하여 어떤 오브젝트에서도 접근이 가능하다.

여기에 문이 열릴 경우, 닫힐 경우에 발생하는 이벤트와 이벤트를 수행하는 함수를 정의해준다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class EventManager : MonoBehaviour
{
	public static EventManager Instance;

	// Edit -> Project Settings -> Script Execution Order
	// Add EventManager -100 을 통해 Awake가 다른 객체들보다 먼저 호출됨을 보장한다.
	void Awake()
	{
		Instance = this;
	}

	public event Action<int> onDoorTriggerEnter;

	public void OnDoorTriggerEnter(int id)
	{
		if (onDoorTriggerEnter != null)
		{
			onDoorTriggerEnter(id);
		}
	}

	public event Action<int> onDoorTriggerExit;

	public void OnDoorTriggerExit(int id)
	{
		if (onDoorTriggerExit != null)
		{
			onDoorTriggerExit(id);
		}
	}
}

 

 

 

DoorController.cs

DoorController  클래스는 Door 오브젝트에 붙어있는 스크립트로 Door를 직접 움직여주는 역할을 담당한다.

이 객체는 생성될때 Door를 여는 작업과 닫는 작업에 대한 함수를 EventManager의 이벤트에 등록한다.

그리고 파괴될 때 이벤트를 제거한다.

또한 이 객체는 Door의 이벤트 수행 시 id를 통해 현재 이벤트가 자기 자신이 보낸 이벤트인지 확인한다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DoorController : MonoBehaviour
{
	public int id;

    // Start is called before the first frame update
    void Start()
    {
		EventManager.Instance.onDoorTriggerEnter += OnDoorOpen;
		EventManager.Instance.onDoorTriggerExit += OnDoorExit;
	}

	void OnDoorOpen(int id)
	{
		if (id == this.id)
		{
			LeanTween.moveLocalY(gameObject, 3.6f, 1f);
		}
	}

	void OnDoorExit(int id)
	{
		if (id == this.id)
		{
			LeanTween.moveLocalY(gameObject, 0.9f, 1f);
		}
	}

	private void OnDestroy()
	{
		EventManager.Instance.onDoorTriggerEnter -= OnDoorOpen;
		EventManager.Instance.onDoorTriggerExit -= OnDoorExit;
	}
}

 

 

TriggerArea.cs

TriggerArea는 이벤트가 발생하는 영역이다.

충돌의 시작, 끝에 대한 함수를 정의하고 EventManager를 통해 각 상황에 이벤트를 발생시킨다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TriggerArea : MonoBehaviour
{
	public int id;

	private void OnTriggerExit(Collider collision)
	{
		EventManager.Instance.OnDoorTriggerExit(id);
	}

	private void OnTriggerEnter(Collider other)
	{
		EventManager.Instance.OnDoorTriggerEnter(id);
	}
}

 

 

 

Inspector

인스펙터에서 다음과 같이 게임오브젝트를 생성시켜준다.

빈 게임 오브젝트 -> EventManager.cs

 

빈 게임 오브젝트(Wall) 

    3D Cube 오브젝트 -> DoorController.cs  (id = 1)

    3D Box Collider -> TriggerArea  (id = 1)

 

빈 게임 오브젝트(Wall)

    3D Cube 오브젝트 -> DoorController.cs  (id = 2)

    3D Box Collider -> TriggerArea  (id = 2)

 

 

 

결과 화면

다음과 같이 문이 열림을 확인할 수 있다.