Skip to content

Commit 0879fba

Browse files
committed
- minor internal refactor (renaming)
- added support for recorders to filter out unsupported platforms. - added about box and version reporting
1 parent c0c92f1 commit 0879fba

23 files changed

+257
-41
lines changed

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Frame Recorder
1+
# Unity Recorder
22
### Brief
3-
The *Frame Recorder* is a project that facilitates recording of Unity artifacts from Unity. The framework does not define what can be recorded, but defines a standard way of how to implement and setup a recorder and takes care of aspects common to all recorders (time managenent, Timeline integration, record windows, etc).
3+
The *Recorder* is a project that facilitates recording of Unity artifacts from Unity. The framework does not define what can be recorded, but defines a standard way of how to implement and setup a recorder and takes care of aspects common to all recorders (time managenent, Timeline integration, record windows, etc).
44

55
Extensibility is a prim concideration and since not all use cases can be thought of in advance, whenever relevant, the framework's base classes strive to offer an easy way to override the default beahviour of the system.
66

@@ -10,6 +10,9 @@ A key consideration is providing a uniform UX. By defining a standard pattern an
1010

1111
Code reusability and easy of use for developers is also a prime consideration. As much as possible, modularization in a Lego mentality is promoted so that work done for one specific recorder, say MP4 recording, can be reused by an other type of recorder, say PNG or WAV recorders.
1212

13+
###
14+
Found a bug? Let us know and [post an issue](https://github.com/Unity-Technologies/GenericFrameRecorder/issues).
15+
1316
### Current limitations
1417
* Recorders are Player standalone friendly, but not the editors.
1518
* Framerate is set at the Recorder level which makes for potential conflict when multiple recorders are active simultaneously.
@@ -32,8 +35,8 @@ Note that this can be done from edit mode and from game mode...
3235

3336
### From a timeline track
3437
1. Create a timeline asset and add it to the scene.
35-
2. Add a "Frame Recorder track" to the timeline.
36-
3. Add a "Frame Recorder clip" to the track.
38+
2. Add a "Recorder track" to the timeline.
39+
3. Add a "Recorder clip" to the track.
3740
4. Select the newly added slip
3841
![](docs/images/TimelineTrack.png)
3942

issue_template.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
##### What happened?
2+
3+
##### Is it reproduceable?
4+
5+
##### Released package version / tag?
6+
7+
##### Unity version, operating system, target platform (standalone windows, mac, iOS, PS4...)?
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using UnityEngine;
2+
3+
namespace UnityEditor.FrameRecorder
4+
{
5+
public class AboutBox : EditorWindow
6+
{
7+
[MenuItem("Tools/Recorder/About...")]
8+
public static void ShowAboutBox()
9+
{
10+
EditorWindow.GetWindowWithRect<AboutBox>(new Rect(100, 100, 550, 310), true, "About Recorder");
11+
}
12+
13+
GUIContent s_Header;
14+
15+
void OnEnable()
16+
{
17+
s_Header = EditorGUIUtility.IconContent("AboutWindow.MainHeader");
18+
}
19+
20+
public void OnGUI()
21+
{
22+
GUILayout.Space(10);
23+
GUILayout.BeginHorizontal();
24+
GUILayout.Space(5);
25+
GUILayout.BeginVertical();
26+
GUILayout.Label(s_Header, GUIStyle.none);
27+
28+
GUILayout.BeginHorizontal();
29+
GUILayout.Space(52f);
30+
GUILayout.Label("Recorder " + RecorderVersion.Stage, EditorStyles.boldLabel);
31+
GUILayout.EndHorizontal();
32+
33+
GUILayout.BeginHorizontal();
34+
GUILayout.Space(52f);
35+
GUILayout.Label(string.Format("Version {0}", RecorderVersion.Version));
36+
GUILayout.EndHorizontal();
37+
GUILayout.Space(4);
38+
GUILayout.EndVertical();
39+
GUILayout.EndHorizontal();
40+
41+
var text = "The Unity Recorder package is a collection of Recorders that allow in-game capturing of data and saving it. For example; generate an mp4 file from a game session.\r\n\r\nIn support to the recorders, it provides a graphical interface that is used to manually trigger recording sessions, which take care of: entering play mode, recording requested data and exiting play mode when done. It also supports triggering recording sessions from user scripts and timeline tracks.\r\n\r\nThe Recorder is aimed at extensibility and is implemented as a plugin system, where anyone can create new recorders and have them seamlessly integrate into the Unity Recorder ecosystem, while maximizing code reuse.";
42+
43+
float textWidth = position.width - 10;
44+
float textHeight = EditorStyles.wordWrappedLabel.CalcHeight(new GUIContent(text), textWidth);
45+
Rect creditsNamesRect = new Rect(5, 120, textWidth, textHeight);
46+
GUI.Label(creditsNamesRect, text, EditorStyles.wordWrappedLabel);
47+
GUILayout.Space(25);
48+
GUILayout.Space(textHeight);
49+
GUILayout.BeginHorizontal();
50+
if (GUILayout.Button("View user manual"))
51+
{
52+
var file = FRPackagerPaths.GetFrameRecorderPath() + "/Recorder_install.pdf";
53+
Debug.Log(file);
54+
Application.OpenURL(file);
55+
this.Close();
56+
}
57+
GUILayout.Space(25);
58+
if (GUILayout.Button("Want to write a recorder?"))
59+
{
60+
Application.OpenURL("https://github.com/Unity-Technologies/GenericFrameRecorder/blob/master/README.md");
61+
this.Close();
62+
}
63+
GUILayout.EndHorizontal();
64+
65+
}
66+
}
67+
}

source/FrameRecorder/Core/Editor/AboutBox.cs.meta

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

source/FrameRecorder/Core/Editor/RecorderEditor.cs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ protected virtual void OnEnable()
7171
m_FrameRateLabels = EnumHelper.MaskOutEnumNames<EFrameRate>(0xFFFF, (x) => FrameRateHelper.ToLable( (EFrameRate)x) );
7272

7373
var pf = new PropertyFinder<RecorderSettings>(serializedObject);
74-
m_Inputs = pf.Find(x => x.m_SourceSettings);
74+
m_Inputs = pf.Find(x => x.m_InputsSettings);
7575
m_Verbose = pf.Find(x => x.m_Verbose);
7676
m_FrameRateMode = pf.Find(x => x.m_FrameRateMode);
7777
m_FrameRate = pf.Find(x => x.m_FrameRate);
@@ -86,7 +86,7 @@ protected virtual void OnEnable()
8686
m_DestinationPath = pf.Find(w => w.m_DestinationPath);
8787
m_BaseFileName = pf.Find(w => w.m_BaseFileName);
8888

89-
foreach (var input in (target as RecorderSettings).m_SourceSettings)
89+
foreach (var input in (target as RecorderSettings).m_InputsSettings)
9090
{
9191
m_InputEditors.Add( new InputEditorState(GetFieldDisplayState, input) { visible = true} );
9292
}
@@ -99,7 +99,7 @@ protected virtual void Awake() {}
9999

100100
public bool isValid
101101
{
102-
get { return (target as RecorderSettings).isValid; }
102+
get { return (target as RecorderSettings).isValid && (target as RecorderSettings).isPlatformSupported; }
103103
}
104104

105105
public bool showBounds { get; set; }
@@ -120,7 +120,7 @@ public override void OnInspectorGUI()
120120
OnInputGroupGui();
121121
OnOutputGroupGui();
122122
OnEncodingGroupGui();
123-
OnTimeGroupGui();
123+
OnFrameRateGroupGui();
124124
OnBoundsGroupGui();
125125
OnExtraGroupsGui();
126126

@@ -134,6 +134,11 @@ public override void OnInspectorGUI()
134134
{
135135
EditorGUILayout.HelpBox("Incomplete/Invalid settings", MessageType.Warning);
136136
}
137+
138+
if (!(target as RecorderSettings).isPlatformSupported)
139+
{
140+
EditorGUILayout.HelpBox("Current platform is not supported", MessageType.Warning);
141+
}
137142
}
138143

139144
protected void AddInputSettings(RecorderInputSetting inputSettings)
@@ -202,10 +207,10 @@ protected virtual void OnEncodingGui()
202207
// place holder
203208
}
204209

205-
protected virtual void OnTimeGui()
210+
protected virtual void OnFrameRateGui()
206211
{
207212

208-
AddProperty( m_FrameRateMode, () => EditorGUILayout.PropertyField(m_FrameRateMode, new GUIContent("Frame rate mode")));
213+
AddProperty( m_FrameRateMode, () => EditorGUILayout.PropertyField(m_FrameRateMode, new GUIContent("Constraint Type")));
209214

210215
AddProperty( m_FrameRateExact, () =>
211216
{
@@ -241,9 +246,9 @@ protected virtual void OnTimeGui()
241246
});
242247
}
243248

244-
protected virtual void OnBounds()
249+
protected virtual void OnBoundsGui()
245250
{
246-
EditorGUILayout.PropertyField(m_DurationMode, new GUIContent("Recording Duration"));
251+
EditorGUILayout.PropertyField(m_DurationMode, new GUIContent("Mode"));
247252

248253
++EditorGUI.indentLevel;
249254
switch ((DurationMode)m_DurationMode.intValue)
@@ -310,13 +315,13 @@ protected virtual void OnEncodingGroupGui()
310315
}
311316
}
312317

313-
protected virtual void OnTimeGroupGui()
318+
protected virtual void OnFrameRateGroupGui()
314319
{
315-
m_FoldoutTime = EditorGUILayout.Foldout(m_FoldoutTime, "Time");
320+
m_FoldoutTime = EditorGUILayout.Foldout(m_FoldoutTime, "Frame rate");
316321
if (m_FoldoutTime)
317322
{
318323
++EditorGUI.indentLevel;
319-
OnTimeGui();
324+
OnFrameRateGui();
320325
--EditorGUI.indentLevel;
321326
}
322327
}
@@ -329,7 +334,7 @@ protected virtual void OnBoundsGroupGui()
329334
if (m_FoldoutBounds)
330335
{
331336
++EditorGUI.indentLevel;
332-
OnBounds();
337+
OnBoundsGui();
333338
--EditorGUI.indentLevel;
334339
}
335340
}

source/FrameRecorder/Core/Editor/RecorderWindow.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ void RecordButtonOnGui()
147147
{
148148
case EState.Idle:
149149
{
150-
using (new EditorGUI.DisabledScope(!m_Editor.isValid))
150+
using (new EditorGUI.DisabledScope(!m_Editor.isValid ))
151151
{
152152
if (GUILayout.Button("Start Recording"))
153153
StartRecording();

source/FrameRecorder/Core/Editor/SerializableObjHelper.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,31 @@ public static bool TargetsSameField(this SerializedProperty obj, SerializedPrope
5757
}
5858
}
5959

60+
public class StructPropertyFinder<TType> where TType : struct
61+
{
62+
SerializedObject m_Obj;
63+
public StructPropertyFinder(SerializedObject obj)
64+
{
65+
m_Obj = obj;
66+
}
67+
68+
public delegate TResult FuncX<TResult>(TType x);
69+
public SerializedProperty Find( Expression<FuncX<object>> exp)
70+
{
71+
var body = exp.Body as MemberExpression;
72+
if (body == null)
73+
{
74+
var ubody = (UnaryExpression)exp.Body;
75+
body = ubody.Operand as MemberExpression;
76+
}
77+
78+
var name = body.Member.Name;
79+
80+
return m_Obj.FindProperty(name);
81+
}
82+
83+
}
84+
6085
public class PropertyFinder<TType> where TType : class
6186
{
6287
SerializedObject m_Obj;

source/FrameRecorder/Core/Editor/Timeline/RecorderClipEditor.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace UnityEditor.FrameRecorder.Timeline
66
{
7-
[CustomEditor(typeof(FrameRecorderClip), true)]
7+
[CustomEditor(typeof(RecorderClip), true)]
88
public class RecorderClipEditor : Editor
99
{
1010
RecorderEditor m_Editor;
@@ -32,7 +32,7 @@ public override void OnInspectorGUI()
3232
if (m_recorderSelector == null)
3333
{
3434
m_recorderSelector = new RecorderSelector( OnRecorderSelected, false );
35-
m_recorderSelector.Init((target as FrameRecorderClip).m_Settings);
35+
m_recorderSelector.Init((target as RecorderClip).m_Settings);
3636
}
3737

3838
m_recorderSelector.OnGui();
@@ -61,7 +61,7 @@ public override void OnInspectorGUI()
6161

6262
public void OnRecorderSelected()
6363
{
64-
var clip = this.target as FrameRecorderClip;
64+
var clip = this.target as RecorderClip;
6565

6666
if (m_Editor != null)
6767
{

source/FrameRecorder/Core/Engine/Recorder.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ protected virtual void OnDestroy()
4747
{
4848
Time.captureFramerate = 0;
4949
if (settings.m_Verbose)
50-
Debug.Log("Frame recorder resetting 'CaptureFrameRate' to zero");
50+
Debug.Log("Recorder resetting 'CaptureFrameRate' to zero");
5151
}
5252
}
5353
}
@@ -63,7 +63,7 @@ public virtual void SessionCreated(RecordingSession session)
6363
if (fixedRate > 0)
6464
{
6565
if (Time.captureFramerate != 0 && fixedRate != Time.captureFramerate )
66-
Debug.LogError(string.Format("Frame Recorder {0} is set to record at a fixed rate and another component has already set a conflicting value for [Time.captureFramerate], new value being applied : {1}!", GetType().Name, fixedRate));
66+
Debug.LogError(string.Format("Recorder {0} is set to record at a fixed rate and another component has already set a conflicting value for [Time.captureFramerate], new value being applied : {1}!", GetType().Name, fixedRate));
6767
else if( Time.captureFramerate == 0 && settings.m_Verbose )
6868
Debug.Log("Frame recorder set fixed frame rate to " + fixedRate);
6969

@@ -74,7 +74,7 @@ public virtual void SessionCreated(RecordingSession session)
7474
}
7575

7676
m_Inputs = new List<RecorderInput>();
77-
foreach (var inputSettings in settings.m_SourceSettings)
77+
foreach (var inputSettings in settings.m_InputsSettings)
7878
{
7979
var input = Activator.CreateInstance(inputSettings.inputType) as RecorderInput;
8080
input.settings = inputSettings;
@@ -108,7 +108,7 @@ public virtual void EndRecording(RecordingSession ctx)
108108
{
109109
Time.captureFramerate = 0;
110110
if (settings.m_Verbose)
111-
Debug.Log("Frame recorder resetting 'CaptureFrameRate' to zero");
111+
Debug.Log("Recorder resetting 'CaptureFrameRate' to zero");
112112
}
113113
}
114114

source/FrameRecorder/Core/Engine/RecorderSettings.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public abstract class RecorderSettings : ScriptableObject
5252
public FileNameGenerator m_BaseFileName;
5353
public OutputPath m_DestinationPath;
5454

55-
public RecorderInputSetting[] m_SourceSettings = new RecorderInputSetting[0];
55+
public RecorderInputSetting[] m_InputsSettings = new RecorderInputSetting[0];
5656

5757
[SerializeField]
5858
string m_RecorderTypeName;
@@ -86,26 +86,28 @@ public virtual bool isValid
8686
if (m_FrameRate == 0 || m_CaptureEveryNthFrame <= 0)
8787
return false;
8888

89-
if (m_SourceSettings != null)
89+
if (m_InputsSettings != null)
9090
{
91-
var valid = m_SourceSettings.All(x => x.isValid);
91+
var valid = m_InputsSettings.All(x => x.isValid);
9292
return valid;
9393
}
9494

9595
return true;
9696
}
9797
}
9898

99+
public virtual bool isPlatformSupported {get { return true; }}
100+
99101
public virtual void OnEnable()
100102
{
101103

102104
}
103105

104106
public virtual void OnDestroy()
105107
{
106-
if (m_SourceSettings != null)
108+
if (m_InputsSettings != null)
107109
{
108-
foreach( var settings in m_SourceSettings)
110+
foreach( var settings in m_InputsSettings)
109111
UnityHelpers.Destroy(settings, true);
110112
}
111113
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using UnityEngine;
4+
5+
namespace UnityEditor.FrameRecorder
6+
{
7+
public class RecorderVersion : ScriptableObject
8+
{
9+
public const string Version = "0.1.170901-03";
10+
public const string Stage = "(Beta)";
11+
}
12+
}

source/FrameRecorder/Core/Engine/RecorderVersion.cs.meta

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)