How To: Make replays like Evolve
If you've played Evolve you'll know exactly how these replays work, if not, take a look. At the end of each game you see a top down view of the map with a sped up play-through of the game you just finished. In this replay you can also see key events, mainly when characters used their abilities. It's a great way to see how well the hunters were tracking the monster and what tricks the monster used to get away.
The first thing you need to do is make a list of each thing you want to keep track of. There are two types of recording you want to do which are interval and instance based. All recording I do is in its own replay script and you should do the same.
A good place to start is tracking the position of any players. This is interval based as you will want to know where the player is at all times. For interval based tracking you'll need to decide on how often to record each piece of data, which you'll probably decide based on how long your games last, but more importantly how accurate you want to be. I used a record rate of once every 0.1 seconds but this can always be tweaked later.
Interval based recording is actually very simple. The easiest way is to use the InvokeRepeating() function as soon as your gameplay starts with the method invoked simply adding the position of the thing you want to track to a List of Vector3s.
List<Vector3> playerPositions; playerPositions.Add(VRPlayer.Instance.transform.position);
If you watch the video I uploaded you'll see the camera is automatically changing during the replay. These changes are recorded from the game and played back in order and in time during the replay so that players can see if the security guard player was close to seeing the thief during the game.
For player positions we just need a list of the positions because the time interval between recordings is always the same. For camera changes I need to record which camera was changed, but also when it happened, so I use a List of Tuples of Cameras and floats. The time is calculated by creating a simple timer which is updated every update.
List<Tuple<Camera, float>> cameraChanges; cameraChanges.Add(new Tuple<Camera, float>(cam, timeSinceEnabled));
Adding to this list is done in a public method which can be accessed by the script where the camera changes are handled by the game.
You may also want to record more data for example rotations so you know which direction the player was facing. For a top down replay like in Evolve this isn't important though.
When the game ends and I want to stop recording new data I use the CancelInvoke() function to stop all interval based recordings. Instance based recording I don't have to worry about as that is only done when it's called in the game which has now ended. From here you can create a new scene with the same environment or delete all your player objects from the scene, and then you'll want to Instantiate() new characters which can't be controlled for the players to watch.
To play back interval data I use the same InvokeRepeating() function as to record the data using the same repeat rate as the recording rate. Inside the method I invoke I simply need to step through the list of player positions and assign that position to a character in the scene. This can be done by creating a dedicated field for our current position in the list and incrementing that value inside the method.
For this I used StartCoroutine() to start a new coroutine for each camera change in the list I recorded. Passed to the playback camera changes method is the camera and time values saved in the list. Because the method is a coroutine I can use the time as a wait time using the WaitForSeconds() function built into Unity. After this I handle the camera information as needed and that will only be executed after the wait time has been reached.
If you want to speed up the replay simply create a new variable called something like playback rate and divide all the playback values by this rate (the repeat rate for the interval playback and the wait time for the instance playback).
To make it easier to see the characters I used a simple Trail Renderer attached to the replay character I instantiate. Here you can easily set values about the length, size and colour in the inspector.
It's as simple as that! Is anything unclear or do you need assistance implementing something like this in your own game? Just leave a comment below and I'll get back to you!
You can help!
Testing so far has been done by just a few participants, and my access to the company Gear VR is limited as I don't own one myself. If anyone out there has a Gear VR and wants to test builds of my game don't hesitate to get in touch with me. I potentially will also be look for an artist / modeler to create assets for the final game, so, again, get in touch.