우선 옵저버 패턴의 장단점을 알고가자.
옵저버는 일대다 방식으로 이벤트 처리에 유용하고, 런타임에 동적으로 객체를 추가하고 제거 할 수도 있다. 그러나 무질서 할 수도 있지만 이것을 없애는 것이 필요하다면 모든 객체에게 알림을 보낼 때 일정 조건을 추가 하면 된다. 그리고 메모리 누수가 발생 할 수도 있을 것이다.
자세한 내용은 아래 참고
언제 사용하는가?
변경이나 상태를 자주 바꾸는 컴포넌트에 주로 사용 할 것이다.
예시로 나는 인벤토리창의 Item을 뽑겠다.
Item 의 Image.sprite 를 바꾸고, Item 과 관련된 Script 나 ScriptableObject 에 대해서 쓸 예정이다.
또는 게임 도중 플레이어가 생명력이 바뀌거나 카메라 위치가 달라질 수 있는데 그것에 대한 코드를 내가 작성 해보았다.
public interface IObserver
{
void Notify();
}
public interface ISubject
{
void RegisterObserver(IObserver observer);
void RemoveObserver(IObserver observer);
void NotifyObservers();
}
public class Subject : MonoBehaviour , ISubject
{
private List<IObserver> observers = new List<IObserver>();
public CameraController cameraController;
public HUDController hudController;
private void Start()
{
RegisterObserver(cameraController);
RegisterObserver(hudController);
}
public void NotifyObservers()
{
foreach (var observer in observers)
{
observer.Notify();
}
}
public void RegisterObserver(IObserver observer)
{
observers.Add(observer);
}
public void RemoveObserver(IObserver observer)
{
observers.Remove(observer);
}
}
public class CameraController : IObserver
{
public void Notify()
{
// 카메라 기능
}
}
public class HUDController : IObserver
{
public void Notify()
{
// HUD 기능
}
}
옵저버 패턴의 대안
c# 의 event system 이 있다. 특히나 컴포넌트간의 관계를 설정 할 필요가 없다면 c# event를 이용하는 것이 더욱 유용하다
그렇다면 Event 로는 어떻게 작성하는데?
using UnityEngine;
public class Subject : MonoBehaviour
{
// Define an event that represents the action to be notified
public event System.Action OnNotify;
private void Start()
{
// Subscribe the methods of observers to the event
OnNotify += cameraController.Notify;
OnNotify += hudController.Notify;
}
// Call this method when you want to notify observers
public void NotifyObservers()
{
// Invoke the event, triggering the subscribed methods
OnNotify?.Invoke();
}
}
public class CameraController : MonoBehaviour
{
public void Notify()
{
// Camera functionality
}
}
public class HUDController : MonoBehaviour
{
public void Notify()
{
// HUD functionality
}
}