소소한 개발 공부

[Unity] 게임의 Undo 작성하기 본문

개발/Unity

[Unity] 게임의 Undo 작성하기

이내내 2021. 3. 27. 18:07

3줄 요약

1. 자료구조 중 Stack( 스택 ) 을 이용하여 Undo 와 Redo를 작성할 수 있다. 
2. Undo로 되돌리고 싶은 상태를 구조체나 클래스, 변수 등에 저장해서 스택에 넣고 빼서 사용한다.
3. Redo는 Undo한 것을 스택에 넣어 Undo와 비슷하게 동작하게 하면 된다.

Undo 방법

좌표를 이용하는 게임을 개발하다가 Undo(이전 실행으로 돌아가기), Redo(Undo 취소) 기능을 추가하기로 했다. 근데 어떻게 만들어야하는지 구글링을 하다보니 포인트는 "스택"임을 알 수 있었다.

방법은 다음과 같다. (더 있을 수 있다.)

 

  1. Undo 스택-클래스를 만들어서 관리하기
  2. 유니티에서 제공하는 Undo 함수 사용하기(이것 또한 구조는 Stack)
  3. Undo 스택을 만들어서 함수로 관리하기 ( 사실상 1번과 유사하다.)

1번과 2번의 경우 밑의 참고의 블로그에서 더 자세히 설명해주셨기 때문에 나는 3번의 내가 직접 겪은 경우를 설명해보고자 한다.

 

내 방법

내 게임의 설정은

1. 좌표의 타입을 검사해 좌표 이동 2. 좌표의 타입 저장 및 변경 등

이 있었는데 해당 좌표의 "타입"이 변경되었다가 Undo로 인해 타입이 되돌아가야 할 경우를 대비해 그 타입 값을 기억하고 있어야 한다.

그래서 그 값을 어느 변수에 넣고 Undo 용 스택에 넣는 것이다.

 

  1. 변경되는 값 저장( Undo 시 되돌아가는데 필요한 값)
  2. 스택에 넣기
  3. Undo 클릭 시 저장했던 값 사용
  4. 스택에서 제거
// 스택 선언 (내 경우 구조체를 스택에 넣었다)
Stack<stateInfo> undoStates = new Stack<stateInfo>();

// 값을 저장(값이 변경되는 함수에서 사용/ Update 같은..)
// 구조체를 사용하면 스택에 넣을 구조체 선언 후 넣기
stateInfo state = new stateInfo(/*여기에 저장할 값을 넣기*/);

// 스택에 넣기
undoStates.Push(state);

// Undo 함수
public void Undo()
{
    stateInfo state;
    if (undoStates.Count <= 0)
        return ;

    state = undoStates.Pop();
    /* 
        Undo로 되돌릴 값 작성
    */
}

Undo 스택이 비어있을 때 Undo 를 실행하게 되면 Null로 인한 오류가 나기 때문에 undoStates.Count가 0 이하일 때(= 스택이 비어있을 때)의 예외처리를 해준다.


Undo 함수에서 state를 임시로 사용할 변수로 넣고 거기에 스택에서 Pop으로 뺀 값을 넣는다.

 

이 방법은 스택에 들어갈 상태를 직접 작성해줘야 하기 때문에 실수가 일어날 수 있다는 단점이 있으나 또 직접 작성할 수 있어 디테일하게 값을 저장할 수 있다는 장점이 있다.

 

 

Redo 는 이와 반대로 Undo 함수에서 Pop한 값을 스택에 넣어 Undo 함수와 비슷하게 작성하면 된다.

public void Undo()
{
    state = undoStates.Pop();

    /*
        Undo 내용
    */

       redoStates.Push(state);
}

public void Redo()
{
    stateInfo state;
    if (redoStates.Count <= 0)
        return ;

    state = redoStates.Pop();
    /*
        redo 내용 작성
    */

    undoState.Push(state);
}

물론 Redo 한 것을 다시 Undo 하고 싶다면 Redo 함수의 마지막에 Undo 스택에 상태를 넣는다는 문장이 있어야 한다. (위의 코드는 스택의 선언 등을 생략하고 Redo에 대한 방식만 작성한 코드)

 

📝참고
  1. C# Undo Redo 기능 구현하기 [출처] [동구의 블로그]
  2. [에디터 확장 입문] 번역 12장 Undo에 대해서
    [출처] [에디터 확장 입문] 번역 12장 Undo에 대해서|작성자 해머임팩트