한동안 방학을 맞아 Reverie 작업을 이것저것 하였는데, 귀찮은 나머지 일지 작성은 거의 못 했었다.
이번에 그래도 새로운 시스템 하나를 추가하게 되어 기념으로 일지를 써 본다.
Undo 시스템
z키를 꾹 누르고 있는 동안 게임을 이전 상태로 되감아 준다.
Baba is you, snakebird 등 턴제 퍼즐 게임에서는 이미 널리 사용되고 있는 시스템이다.
아직 연속적인 퍼즐 게임에서는 본 적은 없는데, 충분히 열심히 찾아보면 어딘가에는 있을지도....?
구현 방식
다행히도 게임 개발 초기여서, 구현을 위해 수정해야 할 내용이 그렇게 많지는 않았다.
1. 각 물체 관련 코드에서 물체의 State 를 결정해주는 값들을 모두 변수로 지정했다.
예: 위치, 색깔, 플레이 중인 애니메이션, 속도 등등... (물론 이미 변수인 것들이 많았다)
2. 이러한 변수를 감싸기 위한 wrapper class 인 RecordedVariable<T> 를 만들고, 변수들을 모두 이 클래스로 감쌌다.
예: bool isJumping; => RecordedVariable<bool> isJumping;
3. RecordedVariable 은 자기 자신의 값이 수정되면 UndoManager 에 자동으로 (자신에 대한 reference, 과거의 변수값)이 두가지를 저장해 준다.
4. z를 누르면 UndoManager은 남아있는 기록 리스트를 뒤에서부터 적용한다. 고쳐야 할 변수에 대한 reference 와, 어떤 값으로 돌려놓아야 하는지가 모두 저장되어 있으므로 이것을 그대로 반영하면 된다.
이때 중요한 점은, RecordedVariable 로 감싸진 변수가 모두 과거 상태가 되면, 그 물체가 그 당시와 완전히 똑같게 동작해야 한다는 것이다. Animator.Play() 등등 유니티 함수의 적용은 변수와 무관하기 때문에, 이를 위해 변수 세팅과 함수 호출을 분리해서 관리해 둘 필요가 있다.
(예를 들어 Animator.Play("jumpAnimation") 이 불린 이후 아무리 RecordedVariable 이 과거로 돌아가도 플레이 중이었던 애니메이션까지 과거로 돌아가진 않는다.
따라서 RecordedVariable<string> curAnimation 을 만들고 대부분의 로직은 이 변수를 수정하게만 하고 Play() 함수를 호출하지는 않게 한다. 대신 FixedUpdate에서 항상 Animator.Play(curAnimation); 과 같이 함수 호출을 모두 한 번에 해 준다.
이런 코드 구조를 갖고 있다면 변수가 과거로 돌아가면 자동으로 올바른 애니메이션이 틀어진다.)
'유니티 게임 개발 일지' 카테고리의 다른 글
| [일지 / 그래픽] 6. 그래픽 인게임 적용 (0) | 2022.02.13 |
|---|---|
| [일지 / 그래픽] 5. 레버리 3번째 컨셉 아트 (도시) (0) | 2022.01.29 |
| [일지 / 그래픽] 3. 레버리 2번째 컨셉 아트 (정글) (0) | 2021.08.27 |
| [일지 / 기획] 2. Reverie 의 작동 원리 (0) | 2021.08.25 |
| [일지 / 공부] 1. 빠른 충돌체크를 찾아서 (0) | 2021.08.17 |