Playback Quick Start
This guide corresponds to the video tutorial located here.
The first step to playback is first having a recording to actually playback. Once you have reference to a recording you can use it to build a PlaybackBehavior instance using it's Build() function.
PlaybackBehavior myPlaybackBehavior = PlaybackBehavior.Build(myRecording);
With a reference to PlaybackBehavior you can call Play, Pause, or Stop to control the recording. You can also change the speed the recording is being played back with SetPlaybackSpeed. We can set the time we are currently at in the playback of the recording using SetTimeThroughPlayback. By default the playback will instantiate cubes as actors to represent the subjects inside the recording. You can set what is used to represent a subject by creating a class to implement the IActorBuilder interface.
using System.Collections;
using UnityEngine;
// Import the playback namespace for access to PlaybackBehavior
using RecordAndPlay.Playback;
public class ActorBuilderExample : IActorBuilder
{
// Creates an actor that uses a sphere to represent itself.
public Actor Build(int subjectId, string subjectName, Dictionary<string, string> metadata)
{
return new Actor(GameObject.CreatePrimitive(PrimitiveType.Sphere));
}
}
You can also choose to add custom functions to be called when a custom event occurs by implementing the IPlaybackCustomEventHandler interface. If the subject passed in is null, then it is a global custom event.
using System.Collections;
using UnityEngine;
// Import the playback namespace for access to PlaybackBehavior
using RecordAndPlay.Playback;
public class CustomEventHandlerExample : IPlaybackCustomEventHandler
{
// This method satisfies the IPlaybackCustomEventHandler interface and
// debugs events.
public void OnCustomEvent(SubjectRecording subject, CustomEventCapture customEvent)
{
if (subject == null)
{
Debug.LogFormat(
"Global Custom Event: {0} - {1}",
customEvent.Name,
customEvent.Contents
);
}
else
{
Debug.LogFormat(
"Custom Event For {0}: {1} - {2}",
subject.SubjectName,
customEvent.Name,
customEvent.Contents
);
}
}
}
You can pass in these implemented interfaces when building the playback behavior like so:
PlaybackBehavior.Build(
recording,
new ActorBuilderExample(),
new CustomEventHandlerExample(),
true
);
If you want to control where in the scene the playback is occuring, you can set the position of the transform that the PlaybackBehavior is attatched to. This applies to rotation and scale as well.
Example
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// Import the record and play namespace for access to the Recording class.
using RecordAndPlay;
// Import the playback namespace for access to PlaybackBehavior
using RecordAndPlay.Playback;
/// <summary>
/// This script is meant for providing playback controls through a gui to any
/// recording passed in. This class also logs custom events as they happen
/// through the playback. This class demonstrates how you can implement the
/// IActorBuilder and IPlaybackCustomEventHandler for building custom playback.
/// </summary>
public class PlaybackExample : MonoBehaviour, IActorBuilder, IPlaybackCustomEventHandler
{
// The recording we are going to be playing back. Marked SerializeField
// so it ican be assigned in the editor.
[SerializeField]
Recording recording;
// A class scoped reference to PlaybackBehavior that is in control of
// animating the playback of the recording.
PlaybackBehavior playbackBehavior;
void Start()
{
// Create an instance of the playback behavior which will be
// responsible for animating the recording we pass in. We also
// tell it to use this class for both creating the actors that
// will represent the subjects recorded, and to use this class
// for responding to custom events in the recording.
playbackBehavior = PlaybackBehavior.Build(recording, this, this, true);
}
// This method satisfies the IActorBuilder interface. The function takes
// the unique id for the subject, the name of the subject, and any
// assigned metadata. With that it should return a reference to a GameObject that
// exists in the current scene to act as a representation for the
// subject. There is an alternative to building the actor which
// includes an optional argument that is the handler for custom events
// that occurred to the subject.
public Actor Build(int subjectId, string subjectName, Dictionary<string, string> metadata)
{
return new Actor(GameObject.CreatePrimitive(PrimitiveType.Sphere), this);
}
// This method satisfies the IPlaybackCustomEventHandler interface. This
// function will be called as the current time in the playback
// progresses over the timestamp of the custom event. If the custom
// event belongs to a specific subject then details of the subject will
// be passed in. Else the subject will be null and all you will be left
// with is the custom event itself.
public void OnCustomEvent(SubjectRecording subject, CustomEventCapture customEvent)
{
if (subject == null)
{
Debug.LogFormat(
"Global Custom Event: {0} - {1}",
customEvent.Name,
customEvent.Contents
);
}
else
{
Debug.LogFormat(
"Custom Event For {0}: {1} - {2}",
subject.SubjectName,
customEvent.Name,
customEvent.Contents
);
}
}
private void OnGUI()
{
if (playbackBehavior.CurrentlyStopped())
{
if (GUILayout.Button("Play"))
{
playbackBehavior.Play();
}
}
else if (playbackBehavior.CurrentlyPlaying())
{
if (GUILayout.Button("Pause"))
{
playbackBehavior.Pause();
}
if (GUILayout.Button("Stop"))
{
playbackBehavior.Stop();
}
}
else if (playbackBehavior.CurrentlyPaused())
{
if (GUILayout.Button("Play"))
{
playbackBehavior.Play();
}
if (GUILayout.Button("Stop"))
{
playbackBehavior.Stop();
}
}
}
}