- 스테이트 패턴: 스테이트 패턴은 객체의 내부 상태에 따라 그 객체의 동작을 변화시키는 설계 방법입니다. 이 패턴을 사용하면 객체의 상태가 바뀔 때 실행되는 동작을 쉽게 관리할...
1. ✨ 프로그램 패턴과 유니티 활용

-
지난 5월에 진행했던 프로그래밍 패턴 세션의 연장선으로, 이번 시간에는 미처 다루지 못했던 나머지 패턴들을 다룬다.
-
주로 다룰 패턴으로는 스테이트, 옵저버, 커맨드 패턴이 있으며, 이후에는 MVC, MVP, 스트레티지 패턴 등의 활용을 보여줄 계획이다.
-
유니티는 이미 많은 프로그램 패턴을 사용 중이며, 이를 명확히 이해하면 다양한 플랫폼에서의 앱 개발에 유용하다.
-
스테이트 패턴은 게임 내 다양한 오브젝트의 상태를 제어하는 데 사용되며, 유니티의 메카니즘 시스템이 이에 해당한다.
-
이번 프레젠테이션은 유니티가 배포하는 한글화된 전자책을 기반으로, 코드를 살펴보며 디자인 패턴을 이해하는 것을 목표로 한다.
-
참석자들은 6월의 더위에 대해 언급하며, 서울의 기온이 35도에 달했다고 말한다.
-
지난 5월에 시작한 게임 프로그래밍 패턴에 대한 시리즈가 이번에 계속 진행될 것이라고 한다.
-
참여자들은 많은 사람들이 참석한 것에 대해 놀라움을 표하며, 더 많은 내용을 알아보겠다고 다짐한다.
-
현재 방송 시간이 4시 6분이며, 4시에 방송을 시작할 것이라고 알린다.
-
유니티를 사용하면 이미 컴포넌트 패턴으로 프로젝트를 진행하고 있는 것과 다름없다.
-
유니티는 많은 패턴을 사용하고 있으며, 이러한 패턴을 명시적으로 이해하면 유니티를 더욱 효과적으로 활용할 수 있다.
-
디자인 패턴과 프로그램 패턴은 앱 개발이나 웹 개발 등 다양한 플랫폼에서 광범위하게 사용된다.
-
프로그램의 규모가 커질수록 필요한 프로그램 패턴의 중요성이 더욱 부각된다.
-
모든 어플리케이션에 가이드 패턴을 강제로 추가하기보다는, 규모와 성격에 맞는지 판단하여 도입하는 것이 좋다.
-
오늘 다룰 주제는 세 가지 패턴으로 한 시간 동안 진행될 예정이다.
-
지난 시간에 다룬 내용은 솔리드 원칙, 팩토리, 오브젝트 풀, 싱글턴이며, 이번에는 스테이트, 옵저버, 커드 패턴에 집중한다.
-
원래는 두 파트로 끝내려 했으나, 다룰 내용이 많아 세 파트로 확장되어 진행될 예정이다.
-
다음 시간에는 모델-뷰-컨트롤러(MVC) 또는 프레젠터(MVP) 패턴과 추가로 스트레티지, 데코레이터, 어댑터 패턴 등을 다룰 예정이다.
-
참가자들은 여유롭게 내용을 청취하며, 후에 다시 보기 가능하니 감사한 마음으로 좋아요도 눌러달라고 요청하고 있다.
-
유니트에서 배포하고 있는 전자책이 있으며, 그 내용을 기반으로 진행하고 있다.
-
번역 작업이 완료되어 한글판도 제공되며, 이전에는 영어 문서만 소개했다.
-
영상 하단에는 한글로 번역된 전자책 링크가 있으며, 간단한 개인 정보 입력 후 이메일로 전자책을 받을 수 있다.
-
전자책의 내용이 좋기 때문에 꼭 완독해보길 권장한다.
-
오늘 진행되는 내용은 전자책의 내용과 디자인 패턴을 코드와 함께 살펴보는 데 초점을 맞추고 있다.
-
유니티를 사용하면서 이미 프로그램 패턴, 특히 디자인 패턴을 활용하고 있다는 점이 언급된다.
-
스테이트 패턴은 애니메이션 상태 전이를 제어하기 위한 것으로, 메카님 시스템의 유한 상태 기계(FSM) 형태로 사용된다.
-
이 스테이트 패턴은 게임에서 주로 애니메이션과 NPC에 적용되며, 유니티에서는 이를 시스템화하여 제공한다.
-
다양한 오브젝트의 상태를 제어하는 것이 스테이트 패턴의 핵심이며, 이와 관련한 데모도 제공될 예정임을 알린다.
-
이전 회차에서 보여준 de모를 바탕으로 이번 시간에도 스테이트 패턴에 대한 데모가 포함될 것이라고 제시된다.
-
유니티 스퀘어라는 웹사이트에 접속하여 관련 자료를 확인할 수 있다.
-
해당 사이트에 접속하면 첫 번째 페이지에서 필요한 정보를 바로 확인할 수 있다.
-
관련 자료는 이북 형식으로 제공되며, 데모와 함께 확인할 수 있다.
-
이북의 내용 중 첫, 두 번째, 세 번째 페이지에서 필요한 링크를 찾아 받을 수 있다.
-
모든 자료는 자유롭게 배포되고 있다.
2. 🚀 상태 패턴 및 활용 예시
-
상태 패턴은 객체의 내부 상태에 따라 스스로 행동을 변경하는 구조로, 다양한 게임 상황에서 활용된다. 예를 들어, 캐릭터가 대기, 움직임, 점프하는 상태 간의 전환을 관리할 수 있다.
-
이 패턴을 통해 상태를 별도의 클래스로 캡슐화하고, 각각의 상태 전환을 처리하여 코드의 가독성과 유지보수성을 높일 수 있다. 특히, 애니메이션이나 네트워크 상태에서 효과적이다.
-
그러나 상태가 추가될 때마다 클래스 수가 증가하여 복잡성이 높아질 수 있으며, 이를 잘 이해하지 못하면 코드가 복잡해 보일 수 있다.
-
무한 상태 기계(FSM)로 상태 패턴을 활용할 때, 관리가 용이하고 각 상태에 대해 명확한 전이 조건을 설정할 수 있다. 이로 인해 개발 시 디자인 패턴의 배경 지식이 중요해진다.
-
다양한 예시로는 게임 캐릭터의 행동 또는 몬스터의 AI에 적용할 수 있으며, 이를 통해 필요한 상태를 추가하여 기능 확장이 용이하다.
-
간단한 스테이트를 통해 캐릭터의 상태 전환을 시각적으로 보여준다.
-
캐릭터는 프로토타입 제작 시 캡슐 형태로 구현되며, 각 상태는 다양한 움직임으로 표현된다.
-
세 가지 상태(상태, 워크 스테이트, 프 스테이트)의 전환을 코드로 보여주고 있다.
-
간단한 데모를 통해 캐릭터의 상태 변화가 시각적으로 표현되고 있다.
-
캐릭터의 움직임에 따라 상태 변화가 발생하는 것을 보여주는 데모가 있다.
-
자이 스테이트 패턴은 객체의 내부 상태에 따라 스스로 행동을 변경하는 패턴이다.
-
상태 클래스는 상태 전환을 관리하며, 다양한 상태에 대해 유연하게 적용될 수 있다.
-
게임에서 주로 사용되며, 캐릭터 애니메이션 조정뿐만 아니라 네트워크 연결 상태 등 다양한 상황에 적용 가능하다.
-
이 패턴을 통해 상태를 각기 다른 클래스로 분리하여, 코드의 가독성과 유지보수성을 향상시킬 수 있다.
-
하지만 상태가 추가될 때마다 클래스가 증가하여 복잡성이 증가할 수 있는 단점이 있다.
-
디자인 패턴은 모든 상황에서 적용할 필요는 없으며, 필요한 곳에만 적용하면 된다.
-
패턴을 미리 알고 있으면 특정 상황이나 환경에서 적절한 패턴을 적용할 수 있다는 감이 온다.
-
디자인 패턴은 상황에 따라 유용한 정보로, 알아두면 좋은 내용이다.
-
코드에서는 특정 상태를 무조건 분리해야 한다는 압박감이 없으며, 규모에 따라 결정하면 된다.
-
스테이트 패턴은 게임에서 주로 사용되며, 이를 유한 상태 기계(FSM)로 시스템화했다고 볼 수 있다.
-
유한 상태 기계는 우리말로 유상태 기계라고도 불리며, 과거 번역에서는 "유한 상태 기계"라는 표현이 많이 사용되었다.
-
플레이어 캐릭터는 스탠딩, 워킹, 점프와 같은 여러 가지 상태를 가지며, 이 상태 간의 전이는 특정 조건에 따라 이루어진다.
-
FSM은 이전 상태, 전환, 전환 이벤트, 동작의 네 가지 요소로 구성되며, 기본적인 구조를 이해하면 추가적인 기능을 확장하기 어렵다.
-
스위치 케이스를 사용하여 상태 전환을 처리하면 간단한 FSM을 구성할 수 있으나, 추가 및 확장이 어려운 단점이 있다.
-
상태 인터페이스를 분리하여 사용하며, 상태 전환에는 세 가지 주요 상황이 있다: 상태 진입, 상태 업데이트, 상태 이탈이다.
-
상태 전환 조건에는 점프하거나 걷기 시작하는 등의 이벤트가 있으며, 이에 따라 상태가 변경된다.
-
각각의 상태는 전이 조건을 정의하여 따로 클래스로 관리하는 것이 유지보수에 용이하도록 한다.
-
스테이트 머신은 여러 상태를 통합 관리하는 역할을 하며, 현재 상태와 이전 상태를 구분할 수 있다.
-
AI의 간단한 로직에서도 FSM(Finite State Machine)을 활용할 수 있어, 게임의 몬스터 AI와 같은 다양한 분야에 적용 가능하다.
-
게임에서 캐릭터는 힐링, 패트롤, 어택, 도망의 네 가지 상태를 가진다.
-
체력이 부족할 경우 도망하여 힐링을 한 후 다시 패트롤을 시작하는 구조이다.
-
플레이어가 시야에 들어오면 공격을 하며, 데미지를 입은 경우 도망간다.
-
상태 기반 로직을 통해 다양한 행동을 처리하도록 설계되어 있다고 언급된다.
-
쓰레드 게임 키스와 같은 3D 게임 프로젝트에서 이러한 상태 관리 패턴을 잘 보여준다.
-
스테이트 머신 비헤이비어는 유니티에서 제공하며, 상태 간의 전환과 기능 확장을 위해 스크립터블 오브젝트를 사용한다.
-
스테이트 머신이 구체적인 행동 로직을 모노비헤이비어와 분리하여 유지보수가 용이하게 하고, 필요한 기능만을 구현하도록 디자인된 구조이다.
-
각 스테이트별로 클래스를 나누어 애니메이션 및 상태 처리를 통해 복잡한 게임 로직을 효율적으로 관리하며, 상태 추가 시 기존 코드를 수정할 필요가 없다.
-
상태간의 변화를 애니메이터에서 플래그를 설정하여 관리하고, 스크립트에서 조건부 호출을 통해 다양한 행동을 제어한다.
-
스테이트 패턴의 장점은 코드의 확장성과 유지 보수 용이성에 있으며, 단점으로는 클래스 수가 증가하면서 복잡성이 커질 수 있다는 점을 유념해야 한다.
3. 📊 옵저버 패턴의 개념과 활용
-
옵저버 패턴은 주체가 있고 그 주체를 지켜보는 여러 옵저버들이 있으며, 상태 변화 시 옵저버들에게 알림을 주는 방식이다.
-
주체와 옵저버 간의 Loose coupling으로 설계되어 유지보수와 확장성에 유리하다.
-
옵저버 패턴은 UI 이벤트 시스템이나 네트워크 통신 등에서 주로 사용되며, 다양한 상황에서 유용하게 활용될 수 있다.
-
유니티에서는 이벤트 액션과 유니티 이벤트 같은 기능으로 옵저버 패턴을 쉽게 사용할 수 있으며, 이는 둘 간의 협업을 용이하게 만든다.
-
장점에도 불구하고 복잡성과 성능 문제, 그리고 예측 불가능한 호출 순서 등의 단점이 존재하므로 신중하게 설계해야 한다.
-
옵저버 패턴은 관찰자 패턴으로, 주의 대상을 관찰하고 이벤트가 발생하면 역할을 수행하는 구조이다.
-
프로그램 내에서 대표적으로 게임에서 옵저버 패턴의 예시가 발견되며, 대한민국에서는 '스타 리그'와 같은 유명 게임이 연상된다.
-
실습 데모를 통해 옵저버 패턴을 시연하며, 유니티 플랫폼을 사용하여 구현되었음을 언급한다.
-
데모 실행 시 두 가지 소리와 파티클 및 애니메이션 효과가 발생하여 옵저버 패턴의 기능을 시각적으로 표현한다.
-
버튼 클릭 시 리액션 처리로써 사용자의 상호작용을 나타내는 예시를 보여준다.
-
옵저버 패턴은 하나의 주체(서브젝트)와 여러 개의 옵저버로 구성된다. 서브젝트는 상태 변경 시 옵저버들에게 알림을 전한다.
-
옵저버들은 서브젝트를 관찰하며, 서브젝트의 상태가 변경될 때 이들을 등록한 콜백이 호출된다.
-
서브젝트와 옵저버는 강하게 얽히지 않기 때문에, 이 패턴은 확장성과 유지보수에 유리하다.
-
이 모델은 다양한 UI 디자인 패턴, 예를 들어 MVC나 MVVM에서 활용되며 효율적인 이벤트 핸들링을 가능하게 한다.
-
옵저버 패턴은 시스템 설계에서 자연스럽게 구현되며, 많은 경우 개발자가 의식하지 않고 사용하게 된다.
-
델리게이트는 특정 함수의 실행을 대신하는 대리자 역할을 하는 객체로, 함수를 담는 변수를 의미한다.
-
델리게이트를 사용하면 다양한 함수를 하나의 델리게이트에 대입하여 호출할 수 있으며, 예를 들어, 프린트 넘을 호출할 수 있다.
-
멀티캐스트 델리게이트를 통해 여러 함수를 동시에 추가하고 실행할 수 있으며, 이러한 기능 덕분에 여러 함수가 한 번에 호출된다.
-
델리게이트는 서로 다른 클래스에서의 콜백 등록에 유용하며, 특히 유니티에서의 게임 개발 상황에서 많이 활용된다.
-
간편하면서도 강력한 델리게이트 기능은 복잡한 코드 작업을 간소화하는 데 기여한다.
-
델리게이트는 이벤트 액션 형태로 제공되며 주로 보이드 메소드로 구성된다. 즉, 반환값 없이 행위만 수행하는 구조이다.
-
이벤트는 델리게이트를 기반으로 정의되며, 캡슐화를 통해 클래스 외부에서 호출되지 않도록 보호하는 역할을 한다.
-
이벤트 액션은 사용이 간편하여 유니티 시스템에서 많이 활용되며, 텔레포트 기능 예시처럼 다양한 기능을 등록하고 호출할 수 있다.
-
옵저버 패턴을 통해 이벤트 관리가 용이해지며, 유지 보수와 확장이 쉽도록 서로 간의 결합 점을 감소시킨다.
-
유니티 이벤트와 유니티 액션은 프로그래머가 사용하기 쉽도록 설계되었으며, 특히 인스펙터 지원이 있어 비전문가도 활용 가능하다.
-
옵저버 패턴은 시스템의 복잡성을 증가시키며, 다양한 옵저버가 존재할 경우 예측 불가능하게 작동할 수 있다.
-
등록 및 해제 과정에서 실수를 하게 되면 메모리 누수와 같은 문제가 발생할 수 있다.
-
옵저버들이 많아질 경우 성능 저하가 일어날 수 있으며, 특히 디버깅이 어려워질 수 있다는 점이 있다.
-
잘못된 설계로 인해 순환 참조가 발생할 위험이 있으며, 이는 무한 루프에 빠지게끔 할 수 있다.
-
이러한 단점에도 불구하고, 옵저버 패턴은 장점이 강력하여 여전히 유용하다는 주장을 할 수 있다.
-
옵저버 패턴은 유니티와 매우 긴밀하게 연결된 패턴이다.
-
오늘 논의된 패턴은 총 세 개이며, 마지막으로 커맨드 패턴이 소개될 것이다.
4. 📦 커맨드 패턴의 이해와 활용
-
커맨드 패턴은 요청을 객체 형태로 캡슐화하여 명령을 실현하는 객체와 명령을 내리는 객체를 분리하는 방식이다.
-
이 패턴은 각 요청을 캡슐화하여 단일 책임 원칙을 준수하며, 새로운 명령을 추가할 때 기존 코드를 수정할 필요가 없다.
-
결합도를 낮추고 추상화하여 코드의 유연성을 높이며, 재사용성을 증가시킬 수 있다.
-
하지만 패턴을 사용하면 클래스 수가 증가하여 복잡성이 높아짐에 따라 오버헤드가 발생할 수 있다.
-
따라서 이 패턴은 모든 상황에 적용할 필요는 없으며, 필요에 따라 신중히 도입하는 것이 중요하다.
-
커맨드 패턴은 명령을 패킹하여 택배처럼 나르는 방식이다.
-
이 패턴은 요청을 캡슐화하여 명령을 실행할 객체에 전달한다.
-
요청을 각각 캡슐화함으로써 단일 책임 원칙을 지킬 수 있다.
-
이론적인 이해에 이어, 코드 예제를 통해 더 명확한 이해가 가능할 것으로 추정된다.
-
커맨드 패턴을 사용하면 새로운 명령 추가 시 기존 코드를 수정할 필요가 없으므로 코드의 유연성이 증가한다.
-
이 패턴은 모듈 추가 및 확장 시 기존 코드를 건드리지 않고 작업할 수 있도록 설계되어 있다.
-
서로 다른 요청을 나무 스택에 저장하고 록을 기록하여 언두 또는 리두 기능 등을 구현할 수 있다.
-
커맨드 패턴은 명령을 저장하고 꺼내 사용함으로써 재사용성과 확장성이 높아진다.
-
명령을 쏘는 주체와 받는 주체 간의 결합도를 낮춰 코드 구조를 유연하고 재사용 가능하게 만든다.
-
이 데모는 이북과 함께 제공되며, 다운로드 링크는 두 번째, 세 번째 페이지에 위치해 있다.
-
사용자가 이전 행동을 언두하거나 리두할 수 있으며, 이는 멀티미디어 작업 및 문서 작업 도구에서 유용하다.
-
커멘드 패턴을 이용하여 각 행동을 큐에 담아 놓고, 필요에 따라 호출하거나 꺼낼 수 있다.
-
게임에서도 시간 여행 캐릭터와 같은 요소로 리플레이 기능을 활용할 수 있어 다양한 확장 가능성이 있다.
-
데모에서 보여지는 동작은 신기한 느낌을 주며, 사용자에게 흥미로움을 제공한다.
-
커맨드 패턴을 사용하지 않으면 일반적으로 인풋 매니저가 플레이어에게 직접 명령을 전달하는 방식으로 설계된다.
-
게임 개발 시, 플레이어의 동작을 호출하기 위해 다양한 플레이어 무버와 명령 모듈이 사용된다고 주장된다.
-
커맨드 패턴은 여러 단계를 거쳐서 호출하는 구조로, 커맨드 임보를 이용하여 명령을 전달하는 방식을 채택한다.
-
일반적인 방식에서는 인풋 매니저가 플레이어의 움직임을 직접 호출하는 반면, 커맨드 패턴에서는 인풋 매니저가 명령을 게임의 객체인 플레이어로 전달한다.
-
명령 생성 시 필요한 것은 수행할 명령과 그 명령을 수행할 객체를 지정하는 것이라고 설명된다.
-
커맨드 인터페이스는 익스큐트와 언두 두 가지 기능으로 구성되어 있다.
-
무브 커맨드는 구체적인 구현 클래스이며, 다양한 커맨드를 생성할 수 있다.
-
플레이어 무브 관련 서브 클래스가 있으며, 이는 참조 용도로 사용된다.
-
이동의 단순성과 더불어, 벡터의 마이너스 연산을 통해 위치를 변경하는 방식이 사용된다.
-
언두와 리두 스택을 통해 커맨드를 관리하고, 새로운 커맨드가 호출되면 언두 스택에 저장된다.
-
커맨드 인보커는 명령을 관리하며, 언두 스택과 리드 스택을 사용해 명령을 호출하고 이전 상태를 복원하는 기능을 제공한다.
-
여러 가지 버튼이 주어진 데모에서, 애드 리스너는 옵저버 패턴을 이용하여 기능을 간단하게 설정할 수 있도록 한다.
-
게임 내에서 커맨드 패턴은 플레이어의 움직임을 처리하고, 버튼 입력에 따라 행동을 결정하는데 중요한 역할을 한다.
-
커맨드 패턴은 스택이나 큐로 구현할 수 있으며, 각각의 방식에 따라 다른 장점을 제공한다. 특히 큐를 사용할 경우 입력 순서에 따른 다양한 조작을 가능하게 한다.
-
격투 게임 개발에 있어 커맨드 패턴은 입력을 효과적으로 처리하여 원하는 기술을 발동시키는 데 유용하다. 그래서 이 패턴이 활용될 수 있는 방법은 다양하다.
-
커맨드 패턴은 각 요청을 객체 형태로 캡슐화하여 명령을 내리는 객체와 받는 객체를 분리하는 방식이다.
-
이 패턴은 단일 책임 원칙과 개방 폐쇄 원칙을 준수하여, 새로운 명령을 추가할 때 기존 코드를 수정할 필요 없이 클래스를 구체화하여 추가할 수 있다.
-
커맨드 패턴을 활용하면 명령을 큐에 저장하거나 로그에 기록해 다양한 방식으로 활용할 수 있으며, 코드의 유연성과 재사용성을 높이는 데 기여한다.
-
그러나 커맨드 패턴은 클래스 수의 증가와 커맨드 관리의 복잡성을 초래할 수 있으며, 전체적인 코드의 복잡성이 증가하는 단점이 있다.
-
오버헤드가 발생할 수 있지만, 이는 설계에 따라 조절이 가능하며 크게 문제가 되지 않을 것으로 판단된다.
5. 📚 프로그래밍 디자인 패턴 요약
-
오늘 다룬 패턴은 상태 패턴, 옵저버 패턴, 그리고 커맨드 패턴이다.
-
각 패턴은 난이도가 달라, 오늘의 패턴은 설명하기 어려운 부분이 있었던 것으로 추정된다.
-
옵저버 패턴은 유니티에서 흔히 사용되며, 커맨드 패턴은 특히 격투 게임과 같은 툴에서 필수적으로 사용된다.
-
신입 개발자는 주로 UI 툴을 만들며, 이 과정에서 커맨드 패턴을 익히는 것이 중요하다.
-
다음 달에는 모델-뷰-컨트롤러(MVC), 모델-뷰-컨트롤러-프레젠터(MVP)와 같은 추가 패턴들을 다룰 예정이다.