[Unity]TIL (38) | 2023.09.14 | 유니티 디자인 패턴 : 옵저버 패턴

kjg5370·2023년 9월 14일
0

TIL

목록 보기
38/91
post-thumbnail

들어가기 앞서

오늘 팀 프로젝트가 끝나고 다른 팀들의 발표를 들었습니다.
모두가 열심히 한 결과가 아주 잘 나타나 있었고 다들 정말 열심히 만든 것 같았습니다.
저희 팀도 열심히 만들었고 다들 진행사항 같은 내용을 자주 공유하며 협업이 어떤 것인지 잘 느낄 수 있는 한주였던 것 같습니다.
이번에 맡은 부분을 제작하면서 처음에 짰던 코드의 구조적인 불편함 때문에 버그 같은 것이나 추가 기능들을 구현할 때 어려움이 있었습니다. 그래서 구조를 처음에 짤 때 유용하게 쓸 수 있는 디자인 패턴에 대해 공부해보려고 합니다.

오늘 배운 것

  • 옵저버 패턴

    소프트웨어 디자인 패턴 중 하나로, 객체 간에 일대다(one-to-many) 의 종속성을 정의하는 패턴.

    어떤 객체(주체, subject)의 상태가 변경되면 그 객체에 종속된 다른 객체(옵저버, observer)들에게 알려주고, 이들 옵저버들은 자동으로 업데이트되는 구조를 갖추고 있음.

    주로 분산 이벤트 처리 시스템, MVC(Model-View-Controller) 아키텍처 등에서 사용.

    • 옵저버 패턴의 장점

      • 느슨한 결합(Loose Coupling): 주체와 옵저버 간의 관계가 느슨하게 연결되어 있으므로, 주체나 옵저버의 변경이 서로에게 영향을 미치지 않고, 이로써 코드의 유연성과 확장성을 높일 수 있음.

      • 이벤트 처리: 이벤트 기반 시스템에서 주로 사용되며, 이벤트가 발생할 때마다 관련된 옵저버들을 효율적으로 알릴 수 있음.

      • 분리된 역할: 주체와 옵저버는 서로 다른 역할을 수행하므로, 시스템을 구조화하고 유지보수하기 쉽게 만듬.

      • 확장성: 새로운 옵저버를 추가하거나 기존의 옵저버를 제거할 때 주체 클래스를 변경하지 않아도 됨.


      출처 : https://2dongdong.tistory.com/47

    • 주체(Subject): 주체는 상태가 변경될 때 옵저버들에게 알리는 역할.
      주체는 옵저버들을 등록하고, 상태가 변경되었을 때 등록된 옵저버들에게 알림.

    • 옵저버(Observer): 옵저버는 주체의 상태를 감시하고, 상태가 변경되면 이를 감지하여 특정 동작을 수행.
      여러 개의 옵저버가 주체에 등록될 수 있으며, 이들은 주체의 상태 변경에 따라 갱신.

    • 등록(Register) 및 해제(Unregister): 옵저버는 주체에게 등록되어야 함.
      주체는 옵저버를 등록하거나 해제할 수 있는 메서드를 제공해야 함. (구독 서비스 같은 개념)

  • 유니티에서 옵저버 패턴 사용

    • 이벤트 처리: 게임 오브젝트 간의 상호 작용을 이벤트를 통해 처리하는 것.
      예를 들어, 플레이어 캐릭터가 적 캐릭터에게 공격을 가할 때, 이 공격 이벤트를 옵저버 패턴을 사용하여 구현할 수 있음.
      적 캐릭터는 공격을 받을 수 있는 옵저버로 등록되고, 플레이어 캐릭터는 공격 이벤트가 발생하면 등록된 적 캐릭터들에게 알리게 됨.

      	  public class PlayerCharacter : MonoBehaviour
      	{
      	    public event Action<Enemy> OnAttack; // 이벤트 선언
      
      	    public void Attack(Enemy enemy)
      	    {
      	        // 공격 동작 수행
      	        // ...
      
      	        // 이벤트 호출
      	        OnAttack?.Invoke(enemy);
      	    }
      	}
      
      	public class Enemy : MonoBehaviour
      	{
      	    private void Start()
      	    {
      	        PlayerCharacter player = FindObjectOfType<PlayerCharacter>();
      	        player.OnAttack += ReactToAttack; // 옵저버 등록
      	    }
      
      	    private void ReactToAttack(Enemy enemy)
      	    {
      	        // 공격에 대한 반응 구현
      	        // ...
      	    }
      	}
    • UI 업데이트: 게임 내 UI는 주로 게임 상태나 플레이어 상태의 변화에 따라 업데이트됨.
      예를 들어, 플레이어의 체력이 변경될 때 이를 UI에 반영하려면 옵저버 패턴을 사용할 수 있음.
      체력 변화를 감지하는 주체와 UI를 업데이트하는 옵저버를 구현하여 상호 작용할 수 있음.

      public class PlayerHealth : MonoBehaviour
      {
          public Text healthText;
      
          private int health = 100;
      
          private void Start()
          {
              UpdateUI();
          }
      
          public void TakeDamage(int damage)
          {
              health -= damage;
              UpdateUI();
          }
      
          private void UpdateUI()
          {
              healthText.text = "Health: " + health.ToString();
          }
      }
    • 게임 이벤트 및 애니메이션: 게임 내 이벤트(예: 폭발, 충돌)나 애니메이션 이벤트(예: 캐릭터의 공격 모션)는 옵저버 패턴을 사용하여 관리. 이벤트가 발생하면 해당 이벤트를 관리하는 시스템이 옵저버에게 알리고, 이에 따른 동작을 수행.

        public class Explosion : MonoBehaviour
      {
          public delegate void ExplosionEventHandler();
          public static event ExplosionEventHandler OnExplode; // 이벤트 선언
      
          private void Start()
          {
              Explode();
          }
      
          private void Explode()
          {
              // 폭발 동작 수행
              // ...
      
              // 이벤트 호출
              OnExplode?.Invoke();
          }
      }
      
      public class PlayerController : MonoBehaviour
      {
          private void Start()
          {
              // 이벤트 핸들러 등록
              Explosion.OnExplode += PlayExplosionSound;
          }
      
          private void PlayExplosionSound()
          {
              // 폭발 사운드 재생
              // ...
          }
      }

기억 할 것 & 진행 사항

  • 델리게이트(Delegate)
    C# 및 다른 몇 가지 프로그래밍 언어에서 사용되는 개념으로, 함수를 담는 변수와 유사한 역할을 할 수 있음.
    델리게이트는 메서드에 대한 참조를 저장하고 호출할 수 있는 형식.
    함수 포인터의 개념과 유사하지만 더 안전하고 객체 지향적인 방식으로 작동.
  1. 메서드를 변수에 저장할 수 있습니다.
  2. 메서드를 다른 메서드에 전달할 수 있습니다.
  3. 메서드를 동적으로 변경하거나 대체할 수 있습니다.

진행 사항

팀 프로젝트 제출 및 발표 완료
팀 프로젝트에서 부족했던 부분 회고(진행중)
졸업작품 중간 발표 준비(미완)

내일 할 일

  • 하루 계획
    • 오전
      • 09:00 ~ 10:00 : 알고리즘 코드카타
      • 10:00 ~ 10:30 : 팀 회의
      • 10:30 ~ 14:00 :
        • 오늘 계획 (Task)
          • 팀 프로젝트 회고
          • 졸업작품 중간 발표 준비
      • 12시-1시: 점심식사
    • 집중 코딩
      • 14:00 ~ 18:00
    • 저녁
      • 6시-7시: 저녁식사
      • 19:00 ~ 20:00 : 집중 코딩 시간 부족한 부분 해결해보기
      • 20:00 ~ 21:00: TIL 작성, 마무리 회고 진행
      • 21:00 : 내일은 위한 휴식!
profile
학생입니다

0개의 댓글