[Unity] 타워 배치·합성 되돌리기 — 커맨드 구조

muchan
muchan
∙∙조회 10
[Unity] 타워 배치·합성 되돌리기 — 커맨드 구조

이번에 넣은 되돌리기 기능은 IReversibleCommand 인터페이스 하나를 중심으로 돌아간다. 이 인터페이스는 Execute, Confirm, Commit, Undo 네 메서드와 IsConfirmed 프로퍼티를 가지고 있고, 타워 배치를 감싸는 TowerPlaceCommand와 타워 합성을 감싸는 TowerMergeCommand가 이를 구현한다.

CommandHistory

커맨드를 담아두는 곳은 CommandHistory static 클래스다. 내부에 List 스택을 두고 LIFO로 쌓는다.

  • Push — 커맨드의 Confirm을 부른 뒤 스택에 넣고, 스택 깊이가 20을 넘으면 가장 오래된 것부터 Commit해서 정리한다.
  • Undo — 스택 맨 위 하나를 꺼내 그 커맨드의 Undo를 호출한다.
  • CommitAll — 스택 전체를 쌓인 순서대로 Commit한 뒤 비운다. DayNightManager.OnDayToNight 이벤트에 구독되어 있어 밤이 되면 자동으로 불린다.

스택이 바뀔 때마다 OnChanged 이벤트를 쏴서 UI가 반응할 수 있게 한다.

TowerPlaceCommand

배치된 GameObject, 실제로 지불한 비용, ManagementController 참조, 타일 크기를 들고 있다. 내부 상태는 Pending → Executed → Confirmed → Committed로 흐르거나 중간에 Undone으로 빠진다.

Undo가 호출되면 소멸 연출을 재생하고, TowerFootprint의 점유를 풀고, 오브젝트를 파괴한 뒤 지불했던 비용을 ManagementController.Grant로 되돌려준다. PlaysUndoDissolve 플래그를 따로 두어 이 연출 재생 여부를 제어하는데, 합성 결과로 편입된 경우엔 꺼둔다.

TowerMergeCommand

재료 타워들의 리스트와 타일 크기, 그리고 결과 타워의 TowerPlaceCommand를 참조로 들고 있다.

  • Execute — 재료들의 타일 점유를 풀고 비활성화한다.
  • AdoptResult — 결과 배치 커맨드를 자기 안에 편입시킨다. 이때 결과 커맨드의 PlaysUndoDissolve를 꺼서 연출이 겹치지 않게 한다.
  • Commit — 재료를 실제로 파괴하고 결과 커맨드도 함께 Commit한다.
  • Undo — 되감기 연출을 재생하고, 결과 커맨드를 먼저 Undo시켜 회수한 다음, 재료들을 다시 점유·활성화시켜 되살린다.

전체 흐름

배치나 합성이 끝나면 각각의 커맨드가 만들어져 CommandHistory.Push로 등록된다. 합성의 경우엔 결과 배치 커맨드가 AdoptResult로 흡수되어 따로 히스토리에 올라가지 않는다.

UI 쪽에서는 TowerUndoButtonView가 CommandHistory의 OnChanged와 CanUndo를 구독해 버튼 활성 상태를 갱신하고, 클릭하면 CommandHistory.Undo()를 호출한다. 밤이 되면 CommandHistory.CommitAll()이 자동으로 실행되며 그날 쌓인 히스토리가 전부 확정된다.

실행 결과

타워 두개를 설치한다

타워를 선택해 게틀링 타워로 합성한다

위에 되돌리기 버튼을 누르면

기존 합성하기 전으로 돌아간다