c# – Trying to implement a rewind feature


I’m creating a level in Unity. I want to remember object positions. When objects are moved, if you hold down “R” the objects should move back to their original position. This should only work on objects that have the rewind script attached to them.

I’m trying to get it to work on any object in a scene, and if there are multiple objects moved, you have to left click on the one you want to move then when you hold down the “R” key it returns to it’s original position.

I can only get this to work on the last object clicked, if I go to a previously moved object, it will not return. Is what I am trying to do possible? Scripts are as follows:

    // TimeRewind.cs

using System.Collections.Generic;
using UnityEngine;

public class TimeRewind : MonoBehaviour
{
    public float recordTime = 1.5f;

    private List<PointInTime> pointsInTime;
    private Rigidbody rb;
    private bool isRewinding = false;

    void Start()
    {
        pointsInTime = new List<PointInTime>();
        rb = GetComponent<Rigidbody>();
    }
    void FixedUpdate()
    {
        if (isRewinding)
        {
            Rewind();
        }
        else
        {
            Record();
        }
    }
    void Record()
    {
        if (pointsInTime.Count > Mathf.Round(recordTime / Time.fixedDeltaTime))
        {
            pointsInTime.RemoveAt(pointsInTime.Count - 1);
        }

        pointsInTime.Insert(0, new PointInTime(transform.position, transform.rotation));

        if (pointsInTime.Count % 10 == 0)
            Debug.Log(gameObject.name + " recording points: " + pointsInTime.Count);
    }
    void Rewind()
    {
        if (pointsInTime.Count > 0)
        {
            PointInTime point = pointsInTime[0];
            transform.position = point.position;
            transform.rotation = point.rotation;
            pointsInTime.RemoveAt(0);
        }
    }
    public void StartRewind()
    {
        isRewinding = true;
        rb.isKinematic = true;
    }
    public void StopRewind()
    {
        isRewinding = false;
        rb.isKinematic = false;
    }
}
    //TTimeManager.cs

using UnityEngine;

public class TimeManager : MonoBehaviour
{
    private TimeRewind selectedRewind;

    void Update()
    {
        // LEFT CLICK - Select object
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit))
            {
                TimeRewind rewindScript = hit.collider.GetComponent<TimeRewind>();

                if (rewindScript != null)
                {
                    selectedRewind = rewindScript;
                    Debug.Log("Selected object: " + selectedRewind.gameObject.name);
                }
                else
                {
                    Debug.Log("Clicked object does not have TimeRewind. Keeping previous selection.");
                }
            }

        }

        // R key - Start rewind
        if (Input.GetKeyDown(KeyCode.R))
        {
            if (selectedRewind != null)
            {
                selectedRewind.StartRewind();
                Debug.Log("R key pressed. Calling StartRewind.");
            }
        }

        // R key up - Stop rewind
        if (Input.GetKeyUp(KeyCode.R))
        {
            if (selectedRewind != null)
            {
                selectedRewind.StopRewind();
                Debug.Log("R key released. Calling StopRewind.");
            }
        }
    }
}
    // PointInTime.cs

using UnityEngine;

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

    public PointInTime(Vector3 pos, Quaternion rot)
    {
        position = pos;
        rotation = rot;
    }
}

Appreciate any help with this issue.

Leave a Reply

Your email address will not be published. Required fields are marked *