Game Development, 게임개발/개발

Observer Pattern를 Unity에서 이용하기

게임이 더 좋아 2022. 6. 5. 16:35
반응형
728x170

 

우선 이전의 글을 읽으면 더 이해가 잘 될 것이다.

[Game Developer, 게임개발자/디자인패턴] - Observer Pattern, 관찰자, 감시자 패턴 [디자인패턴]

 


 

Observer Pattern을 쓰는 이유를 알고 써보자

1. Loose Coupling 

2. Effectively Check

 

우선적으로 클래스 간의 커플링을 줄여주는 것이고

그 다음이 효율적인 실행이다.

 

 

예를 들어서 설명해보자.

** 레벨이 오르면 체력을 꽉 채워주고 싶다.

=> 레벨이 오르는지 확인해야함

=> 레벨이 오를 때 체력을 갱신해야함

 

 

1. Level.cs

using System.Collections;
using UnityEngine;
using UnityEngine.Events;

public class Level : MonoBehaviour {

    [SerializeField] int pointsPerLevel = 200;
    int experiencePoints = 0;

//그냥 코루틴
    IEnumerator Start()
    {
        while (true)
        {
            yield return new WaitForSeconds(.2f);
            GainExperience(10);
        }
    }

//각종 메서드
    public void GainExperience(int points)
    {
        experiencePoints += points;
    }

    public int GetExperience()
    {
        return experiencePoints;
    }

    public int GetLevel()
    {
        return experiencePoints / pointsPerLevel;
    }
}

 

 

2. Health.cs

using System;
using System.Collections;
using UnityEngine;

public class Health : MonoBehaviour {
    [SerializeField] float fullHealth = 100f;
    [SerializeField] float drainPerSecond = 2f;
    float currentHealth = 0;

//그냥 초기화
    private void Awake() {
        ResetHealth();
        StartCoroutine(HealthDrain());
    }


//각종 메서드
    public float GetHealth()
    {
        return currentHealth;
    }

    public void ResetHealth()
    {
        currentHealth = fullHealth;
    }

    private IEnumerator HealthDrain()
    {
        while (currentHealth > 0)
        {
            currentHealth -= drainPerSecond;
            yield return new WaitForSeconds(1);
        }
    }
}

 

 

우리가 레벨업 시에 체력을 꽉 채워준다고 하면 

바로 채울 수 있다.

그냥 Update 문에서 계속 레벨업을 했는지 체크하면 된다.

그리고 Level.cs에서 Health Class에 접근해서 체력을 Reset시켜주면 된다.

여기서 문제가 생기는데

1. Level이 Health를 알아야함

2. Level이 계속 Level을 매 프레임마다 체크하고 있음.

문제랄 것은 아니지만 분명 레벨업 할 때만 체크하면 될 것을 매 프레임마다 하고 있으니 짜증난다.

 

그래서 우리는 Unity Event를 이용한다.

[Unity, 유니티/Basic, 기본] - C#/Unity Event - 개념

 

 


 

다만 그 Unity Event를 이용하기 위해서는 그 Event만은 알아야 한다.

즉, Level과 Health의 Coupling을 최소로 하는 것이지

전혀 모를 수는 없다는 것이다.

 

짧게 말해서 유니티에서 어떻게 쓰느냐?

 

0. Level에서 LevelUp 되었을 때라는 Event를 작동시키고 싶다면

1. Level이 LevelUp을 가지고 있게 한다.

2. LevelUp은 LevelUp과 연관된 요소들만 Event를 등록한다.

3. 실제로 LevelUp 하는 부분은 Level.cs이며 Level Up과 동시에 해당 Event를 Invoke를 하면 된다.

 

내가 애용하는 MVC 패턴도 이와 비슷하다. Model(Dependency) Injection이라는 부분에서 Event와 같다.

=> MVP도 같다. 

 

짧게 말해서

매 프레임 체크할 필요가 없고 LevelUp 할 때 Invoke를 하면 되고

그 동작을 위해서 전체 클래스에 대해 접근할 필요가 전혀 없으며 해당 Event만 알고 있으면 되겠다.

 

모든 게임에 특정 상황을 체크하기 위해서 항상 Update문을 돌 필요는 없다는 이야기다.

 

 

 

 

 

반응형
그리드형