낑깡의 게임 프로그래밍 도전기

Unity 특정 시점으로 돌아가는 기능 : 타임 리와인드, 타임트래블 본문

Unity C#

Unity 특정 시점으로 돌아가는 기능 : 타임 리와인드, 타임트래블

낑깡겜플밍 2024. 5. 20. 09:31
반응형

유니티에서 코드가 실행되다가 특정 시점으로 돌아가는 기능을 구현하려면 "타임 리와인드" 혹은 "타임 트래블" 메커니즘을 사용해야 합니다. 이는 게임 내 객체의 상태를 일정 주기로 저장하고, 필요 시 그 상태로 되돌리는 방식으로 구현할 수 있습니다. 이를 위해서는 여러 가지 접근 방식이 있으며, 대표적으로 다음과 같은 방법을 사용할 수 있습니다:

 

1. 상태 저장 및 복구

이 방법은 주기적으로 객체의 상태(위치, 회전, 애니메이션 상태 등)를 저장하고, 특정 조건이 만족될 때 저장된 상태로 복구하는 방식입니다.

예시 코드:

using System.Collections.Generic;
using UnityEngine;

public class TimeRewind : MonoBehaviour
{
    private List<TransformData> transformHistory;
    public bool isRewinding = false;
    public float recordTime = 5f; // 얼마나 오래 기록할지 (초 단위)

    void Start()
    {
        transformHistory = new List<TransformData>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.R)) // R 키를 누르면 되감기 시작
        {
            StartRewind();
        }
        if (Input.GetKeyUp(KeyCode.R)) // R 키를 떼면 되감기 중지
        {
            StopRewind();
        }

        if (isRewinding)
        {
            Rewind();
        }
        else
        {
            Record();
        }
    }

    void Record()
    {
        if (transformHistory.Count > Mathf.Round(recordTime / Time.fixedDeltaTime))
        {
            transformHistory.RemoveAt(transformHistory.Count - 1);
        }
        transformHistory.Insert(0, new TransformData(transform));
    }

    void Rewind()
    {
        if (transformHistory.Count > 0)
        {
            TransformData data = transformHistory[0];
            transform.position = data.position;
            transform.rotation = data.rotation;
            transformHistory.RemoveAt(0);
        }
        else
        {
            StopRewind();
        }
    }

    void StartRewind()
    {
        isRewinding = true;
    }

    void StopRewind()
    {
        isRewinding = false;
    }
}

public class TransformData
{
    public Vector3 position;
    public Quaternion rotation;

    public TransformData(Transform transform)
    {
        position = transform.position;
        rotation = transform.rotation;
    }
}
반응형

2. 커맨드 패턴 사용

커맨드 패턴을 사용하여 객체의 상태 변화를 명령 객체로 캡처하고, 이러한 명령들을 실행하거나 되돌리는 방식입니다.

예시 코드:

using System.Collections.Generic;
using UnityEngine;

public class CommandManager : MonoBehaviour
{
    private Stack<ICommand> commandHistory = new Stack<ICommand>();

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Z) && commandHistory.Count > 0)
        {
            ICommand lastCommand = commandHistory.Pop();
            lastCommand.Undo();
        }

        if (Input.GetMouseButtonDown(0))
        {
            MoveCommand command = new MoveCommand(transform, new Vector3(1, 0, 0));
            command.Execute();
            commandHistory.Push(command);
        }
    }
}

public interface ICommand
{
    void Execute();
    void Undo();
}

public class MoveCommand : ICommand
{
    private Transform transform;
    private Vector3 direction;
    private Vector3 previousPosition;

    public MoveCommand(Transform transform, Vector3 direction)
    {
        this.transform = transform;
        this.direction = direction;
    }

    public void Execute()
    {
        previousPosition = transform.position;
        transform.position += direction;
    }

    public void Undo()
    {
        transform.position = previousPosition;
    }
}

이와 같이 유니티에서 특정 시점으로 돌아가는 기능을 구현하기 위해서는 객체의 상태를 주기적으로 저장하고 필요할 때 이를 복구하는 방식으로 구현할 수 있습니다.

반응형