Keeping last 15 seconds captured by a camera

Hi,
I’d like to know if there is a way or what’s the best to keep in memory the last 15 seconds of what a camera saw and to save them on trigger?

Regards,

I don’t know what is your game, but a think the best way do to it, is to store the position / the states / time of yours gameobject in a list and for the replay, clean the scene and move your gameobject in function of the postions / states / time saved in the list.

Not sure it is the best way but this don’t need a lot of spaces like recording the camera view.

Ok it was the answear I was afrait of :), do you know a way to save the all scene state ? Or what a camera as grabbed? As it’s not to restart the current game state but only show what happened it would be nice.

Regards,

using UnityEngine;
using System.Collections;

public class SaveState()
{
          // 750 is 15 seconds of 50fps
          const int NUMBER_STATES = 750;
          Vector3[] positions = new Vector3[NUMBER_STATES];
          Vector3[] rotations = new Vector3[NUMBER_STATES];
          Vector3[] scales = new Vector3[NUMBER_STATES];

          int currentIndex = 0;
      
          void Late_Update()
          {
                    positions[currentIndex] = transform.position;
                    rotations[currentIndex] = transform.rotations;
                    scales[currentIndex] = transform.rotations;
                    currentIndex++;
                    if (currentIndex >= NUMBER_STATES)
                         currentIndex = 0;
           }
}

You just attach this script to any gameObject/ Prefab that will need to be replayed. It keeps a currentIndex and rotates around the array. This way we don’t need to ever copy data. we just overwrite old Data. When you need to replay anything you start at currentIndex+1, go to the end, then loop around from 0->currentIndex to replay all the data.
You can add arrays for any other data that might need to be saved.

Now to replay if you have a specific button that starts a replay you can add that code to the script’s Update()

void Update()
{
          If (Input.GetKeyUp(KeyCode.R)
          {
                 StartCoroutine(Replay());
           }
}

IEnumerator Replay()
{
        int replayIndex = currentIndex+1;
        If (replayIndex >= NUMBER_STATES)
           replayIndex = 0;

        while (replayIndex != currentIndex)
        {
                 transform.position = positions[replayIndex];
                 transform.rotation = rotations[replayIndex];
                 transform.scale = scales[replayIndex];
                 replayIndex++;
                 if (replayIndex >= NUMBER_STATES)
                     replayIndex = 0;
                 yield return null;
            }
}

You can also set up some GameObject that has an Event Handler and all your scripts can just register with this and run the Coroutine when they receive the event. You proabably won’t need to save the current State when you start a replay since its the last X frames so the game state should end up where it began.

You can check out one of my replies on this thread for example code of setting up and consuming an event:

or the MSDN documentation:
https://msdn.microsoft.com/en-us/library/aa645739(v=vs.71).aspx

EDIT: NOTE: 15 seconds of data saved to a texture(the full screen) of 1600x900 is about 1 GIG of Pixels. Which depending on your color depth can be 4-32 gigs of actual data This method is 27k per Object. So its a lot less, even if you add your own custom data. Though I’m sure the full screen save can be brought down a lot with some good compression. I’m not too familiar with video compression though.

I would like to ask something about this too. How would you save the animations and actions that happened in those 15 seconds and call them? Like let’s say, character crouched and fired the gun.

How does your game crouch and fire the gun in the first place? What causes that to happen. If its a button press, you could just save all the buttons that were pressed that frame, and call the same code the actual button press code calls. The Replay coroutine is happening frame by frame. So any any calls to start and stop animations will still work since they will be running side by side with the coroutine

Though it does bring up a point, what happens if your first frame of replay was in the middle of some animation. You’d have have some way of setting the animation in middle of the animation. To be honest i’m not that familiar with Unity’s animation system, so i’m not sure if you can just start an animation up at a certain frame. If an object is always animation, (Idle,walk,run) you can save which state that animator is in , and what frame its on. And restart the animation at that state/animation. Then have the button /keys control it from there just like they did the first time through.

I was thinking about saving button presses too but since I am new at this I don’t really know what I can do and can’t do. So, I was thinking there may be some way to do it like you did with position, rotation and scale. I just wanted to try my luck basically. And I wasn’t even thinking about it being in the middle of an animation. I was just thinking it would pretty pointless without replaying animations and that’s why I asked. Thanks for the answer.

Back up a bit. First questions first. Why do you want to save the data? What are you going to use it for?

Isn’t there a way to bufferize a stream of what a camera can see ? and on trigger save it as a mp4?