본문 바로가기
게임 개발(유니티)/멋쟁이 사자처럼 3기_회고록

유니티 디자인패턴_Observer 패턴

by goraku97 2025. 1. 9.

Observer 패턴

객체 간의 일대다(one-to-many) 관계를 정의하여, 하나의 객체 상태가 변경되었을 때

관련된 다른 객체들이 자동으로 통지받고 업데이트되도록 하는 디자인 패턴

게임 오브젝트와 컴포넌트들 간의 통신 및 상호작용을 효율적으로 처리하기 위해 자주 사용됨.

(플레이어의 체력 감소, 레벨 완료, 또는 환경 변화 등, 상태 변화를 중심으로 동작하는 게임 시스템에 적합)

 

장점과 단점

 

스크립트 해석:

PlayerManager.cs
0.00MB

 

PlayerManager 스크립트

 

.RegisterObserver() : 매개변수를 옵저버로 등록. 옵저버로 등록되면,

                                   특정 개체의 상태가 변경될 때, 알림이 전달됨)

 

// HP : Health 클래스의 인스턴스

// healthManager를 옵저버로 등록
// (옵저버 패턴이란, 특정 객체의 상태가 변경될 때 등록된 옵저버들에게 알림을 전달하는 디자인 패턴)
HP.RegisterObserver(healthManager);

 

transform.Find(현재 오브젝트의 트랜스폼)에서 특정 경로를 따라 하위 오브젝트를 검색

// transform.Find(현재 오브젝트의 트랜스폼)에서 특정 경로를 따라 하위 오브젝트를 검색
Transform fill = transform.Find("Canvas/Slider/Fill Area/Fill");
if (fill != null)
{
 fill.gameObject.SetActive(false);
}

EnemyManager.cs
0.00MB

 

 

EnemyManager 스크립트

 

Health.cs
0.00MB

 

Health 스크립트

(체력을 관리하고 체력의 변화를 관찰자들에게 알리는 역할을 수행.(옵저버로 등록된 대상들을 관리)

 

RemoveObserver() : (매개변수에) 등록된 관찰자를 observers 리스트에서 제거

// 관찰자를 헤제하는 메서드
// 등록된 관찰자를 observers 리스트에서 제거
public void RemoveObserver(IHealthObserver observer)
{
   // 체력 변화를 더 이상 관찰할 필요가 없는 객체는 이 메서드를 통해 해제
   observers.Remove(observer);
}

 

NotifyObservers() : 상태 변경이 발생했을때, 등록된 관찰자들에게 알림

// 관찰자에게 체력 변경을 알리는 메서드
private void NotifyObserver()
{
   foreach (var observer in observers)
   {
      // OnHealthChanged 메서드를 호출하여 체력의 현재 값과 최대 값을 전달
      observer.OnHealthChanged(health, maxHealth);
   }
}

 

HealthManager.cs
0.00MB

 

 

HealthManager 스크립트

(체력 상태를 UI로 표시하기 위한 HealthManager 클래스로,

  Unity MonoBehaviour를 상속받으며 IHealthObserver 인터페이스를 구현)

 

value maxValue

public void OnHealthChanged(float newHealth, float maxHealth)
{
    // maxValue: 최대 체력 값
    hpSlider.maxValue = maxHealth;
    // value: 현재 체력 값
    hpSlider.value = newHealth;

SettingDatas.cs
0.00MB

 

 

SettingDatas 스크립트

(플레이어와 적의 최대 체력 데이터를 관리 및 보관하는 역할)

** 확장 가능성(이 클래스는 게임의 다른 설정 값을 추가로 저장할 수도 있음)

IHealthObserver.cs
0.00MB

 

 

IHealthObserver  스크립트

(IHealthObserver라는 인터페이스를 정의한 것으로,

 옵저버 패턴을 구현하기 위해 사용)

 

Interface :

클래스나 구조체가 특정 기능이나 동작을 구현하도록 계약(Contract)을 정의

인터페이스 자체는 구현(구체적인 동작)포함하지 않고, 단지 필요한 메서드, 속성, 이벤트, 인덱서 등을 선언만 함.

그리고 이를 구현하는 클래스나 구조체는 반드시 인터페이스에 정의된 내용을 구현해야 함.

인터페이스는 다중 상속을 허용하기 때문에, 여러 역할을 동시에 부여할 수 있음.

 

// 이 코드는 IHealthObserver라는 인터페이스를 정의한 것으로, 옵저버 패턴을 구현하기 위해 사용

// IHealthObserver는 옵저버 패턴에서 "관찰자" 역할을 하는 클래스가 구현해야 하는 체력 변경 감지 메서드를 정의
// IHealthObserver를 구현하는 클래스는 OnHealthChanged() 메서드를 반드시 정의해야 함.

public interface IHealthObserver 
{
    // float newHealth: 현재 체력 값. 변경된 체력 값을 전달받음. 
    // float maxHealth: 최대 체력 값. 변경된 최대 체력 값을 전달받음.
    void OnHealthChanged(float newHealth, float maxHealth);
}