상태를 보관해놨다가 롤백할 때 사용. 커맨드 패턴과 섞어서 자주 사용한다.
(커맨드 패턴이 안쓰면 잘 쓸일이 없다....)
메멘토 : 단순하게 내 상태를 저장할 수 있는 커맨드 패턴과 매우 유사하다.
변한 변수를 넣어놨다가 필요할 때 되돌리기
데이터를 변환한 다음에 변환된 상태를 저장해놓고, 예전으로 돌아가고싶을 때 초기상태로 다시 돌아간다.
스택의 Peek은 스택 맨 위에 있는 데이터를 말한다.
using UnityEngine;
using System.Collections.Generic;
// Memento 클래스: 플레이어의 상태를 저장
public class Player_1Memento
{
public Vector3 Position { get; private set; }
public int Health { get; private set; }
public int Score { get; private set; }
public Player_1Memento(Vector3 position, int health, int score)
{
Position = position;
Health = health;
Score = score;
}
}
// Originator 클래스: 플레이어
public class Player_1 : MonoBehaviour
{
public Vector3 Position { get; set; }
public int Health { get; set; }
public int Score { get; set; }
// 현재 상태를 Memento에 저장
public Player_1Memento SaveState()
{
return new Player_1Memento(Position, Health, Score);
}
// Memento로부터 상태를 복원
public void RestoreState(Player_1Memento memento)
{
Position = memento.Position;
Health = memento.Health;
Score = memento.Score;
// Unity Transform 업데이트
transform.position = Position;
Debug.Log($"State restored - Position: {Position}, Health: {Health}, Score: {Score}");
}
// 플레이어 상태 변경 (예시용)
public void ChangeState(Vector3 newPosition, int healthChange, int scoreChange)
{
Position = newPosition;
Health += healthChange;
Score += scoreChange;
// Unity Transform 업데이트
transform.position = Position;
Debug.Log($"State changed - Position: {Position}, Health: {Health}, Score: {Score}");
}
}
// Caretaker 클래스: 메멘토 관리
public class GameManager_2 : MonoBehaviour
{
public Player_1 Player_1;
private Stack<Player_1Memento> mementos = new Stack<Player_1Memento>();
void Start()
{
Player_1 = GetComponent<Player_1>();
SavePlayer_1State(); // 초기 상태 저장
}
public void SavePlayer_1State()
{
mementos.Push(Player_1.SaveState());
Debug.Log("Player_1 state saved.");
}
public void UndoPlayer_1State()
{
if (mementos.Count > 1) // 항상 하나의 상태는 남겨둠
{
mementos.Pop(); // 현재 상태 제거
Player_1.RestoreState(mementos.Peek());
}
else
{
Debug.Log("Can't undo: No more saved states.");
}
}
// 테스트용 메서드들
public void MovePlayer_1Randomly()
{
Vector3 randomPosition = Random.insideUnitSphere * 5f;
randomPosition.y = 0; // y축은 0으로 유지
int healthChange = Random.Range(-10, 11);
int scoreChange = Random.Range(0, 101);
Player_1.ChangeState(randomPosition, healthChange, scoreChange);
SavePlayer_1State();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.S))
{
MovePlayer_1Randomly();
}
if (Input.GetKeyDown(KeyCode.U))
{
UndoPlayer_1State();
}
}
}
'STUDY > 디자인패턴' 카테고리의 다른 글
Iterator 이터레이터 패턴 (0) | 2024.07.19 |
---|---|
Mediator 메디에이터 패턴 (0) | 2024.07.19 |
Strategy 전략 패턴 (0) | 2024.07.19 |
Observer 옵저버 패턴 ★★★ (0) | 2024.07.19 |
FSM(Finite-State-Machine) ★★★ (0) | 2024.07.17 |