TIL

[TIL] 내일배움캠프_Unity 옵저버 패턴

Hwone 2023. 10. 3. 02:56

옵저버 패턴 

: 객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 통지하도록 하는 디자인 패턴 

 

주로 특정 객체의 상태가 변경될 때, 이 변경을 다른 객체들에게 통지하고자 할 때 사용된다 

 

게임 개발의 관점에서 옵저버 패턴은 이벤트 시스템을 통한 상호작용이 떠오른다 

예를 들어 플레이어의 점수나 상태가 변경되었을 때를 생각할 수 있다 

 

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

public class PlayerHealth : MonoBehaviour
{
    private int currentHealth;
    public int MaxHealth = 100;

    // 옵저버들을 저장하는 리스트
    private List<IHealthObserver> healthObservers = new List<IHealthObserver>();

    private void Start()
    {
        currentHealth = MaxHealth;
    }
	//체력 변경 시 알리는 함수
    private void NotifyObservers()
    {
        foreach (var observer in healthObservers)
        {
            observer.OnHealthChanged(currentHealth, MaxHealth);
        }
    }
	
    // 체력 변경되는 함수
    public void TakeDamage(int damageAmount)
    {
        currentHealth -= damageAmount;
        currentHealth = Mathf.Clamp(currentHealth, 0, MaxHealth);
		
        //변경됨
        NotifyObservers();
    }
	//추가
    public void AddObserver(IHealthObserver observer)
    {
        healthObservers.Add(observer);
    }
	//삭제
    public void RemoveObserver(IHealthObserver observer)
    {
        healthObservers.Remove(observer);
    }
}

 

public interface IHealthObserver
{
    void OnHealthChanged(int currentHealth, int maxHealth);
}

public class HealthBar : MonoBehaviour, IHealthObserver
{
    public Image healthBarFill;

    public void OnHealthChanged(int currentHealth, int maxHealth)
    {
        float healthPercentage = (float)currentHealth / maxHealth;
        healthBarFill.fillAmount = healthPercentage;
    }
}

public class GameManager : MonoBehaviour
{
    public PlayerHealth playerHealth;
    public HealthBar healthBar;

    private void Start()
    {
        playerHealth.AddObserver(healthBar);
    }

    private void OnDestroy()
    {
        playerHealth.RemoveObserver(healthBar);
    }
}

 

플레이어의 체력이 변경될 때 마다 HealthBar 클래스에서 UI상의 체력바가 업데이트 된다 

 

이렇게 옵저버 패턴을 사용하면 HealthBar와 Player간의 관계를 느슨하게 유지되고, 새로운 이벤트나 상태가 추가될 때 기존 코드를 수정하지 않고도 쉽게 확장할 수 있다