Skip to content

Commit 523378b

Browse files
committed
Merge branch 'develop'
2 parents cebbaf9 + a1cb18c commit 523378b

6 files changed

Lines changed: 145 additions & 69 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [1.1.3]
8+
9+
### Added
10+
- Rotation statistic recording
11+
- Option to flatten multipart statistics (e.g. XYZ) into a single line during CSV export
12+
13+
### Changed
14+
- Playback file checks are more aggressive to ensure file changes are accounted for
15+
716
## [1.1.2] - 11/07/23
817

918
### Added

Core/Editor/Scripts/PlaybackManagerEditor.cs

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public class PlaybackManagerEditor : Editor
3030
private SerializedProperty _timeCounter;
3131
private SerializedProperty _ignoreFile;
3232

33+
private bool _awaitingRefreshVal = false;
34+
3335
private string _componentFilter = "";
3436

3537
private GUIContent _recordFoldoutGUI = new GUIContent("", "You can drag files onto this header to add them to the files list.");
@@ -53,6 +55,14 @@ private void Awake()
5355
}
5456
}
5557

58+
private void OnDestroy()
59+
{
60+
if (_awaitingRefreshVal)
61+
{
62+
Debug.LogWarning("Playback Manager needs to Update Files before you can enter play mode.", serializedObject.targetObject);
63+
}
64+
}
65+
5666
public override bool RequiresConstantRepaint()
5767
{
5868
return false;
@@ -65,6 +75,7 @@ private void SetProperties()
6575
_binders = serializedObject.FindProperty("_binders");
6676
_currentFile = serializedObject.FindProperty("_currentFile");
6777
_awaitingRefresh = serializedObject.FindProperty("_awaitingFileRefresh");
78+
_awaitingRefreshVal = _awaitingRefresh.boolValue;
6879
_oldFileIndex = serializedObject.FindProperty("_oldFileIndex");
6980
_playing = serializedObject.FindProperty("_playing");
7081
_changingFiles = serializedObject.FindProperty("_changingFiles");
@@ -248,19 +259,15 @@ private void RecordedFilesList()
248259
if (_recordedFiles.isExpanded)
249260
{
250261
_fileScrollPos = EditorGUILayout.BeginScrollView(_fileScrollPos, GUILayout.Height(Sizes.Playback.heightFileScroll));
262+
EditorGUI.BeginChangeCheck();
251263
for (int i = 0; i < _recordedFiles.arraySize; i++)
252264
{
253-
if (!(_fileScrollPos.y - ((Sizes.heightLine + Sizes.padding)*2) <= ((Sizes.heightLine+Sizes.padding) * (i - 1)) && _fileScrollPos.y + Sizes.Playback.heightFileScroll > ((Sizes.heightLine + Sizes.padding) * i)))
265+
if (!(_fileScrollPos.y - ((Sizes.heightLine + Sizes.padding) * 2) <= ((Sizes.heightLine + Sizes.padding) * (i - 1)) && _fileScrollPos.y + Sizes.Playback.heightFileScroll > ((Sizes.heightLine + Sizes.padding) * i)))
254266
{
255267
EditorGUILayout.LabelField("");
256268
continue;
257269
}
258270

259-
if (_recordedFiles.GetArrayElementAtIndex(i).objectReferenceValue == null)
260-
{
261-
_awaitingRefresh.boolValue = true;
262-
}
263-
264271
EditorGUILayout.BeginHorizontal();
265272

266273
EditorGUI.BeginDisabledGroup(_awaitingRefresh.boolValue);
@@ -283,7 +290,6 @@ private void RecordedFilesList()
283290
{
284291
_recordedFiles.GetArrayElementAtIndex(i).objectReferenceValue = null;
285292
_recordedFiles.DeleteArrayElementAtIndex(i);
286-
_awaitingRefresh.boolValue = true;
287293
if (_currentFile.intValue >= _recordedFiles.arraySize)
288294
{
289295
_currentFile.intValue = _recordedFiles.arraySize - 1;
@@ -294,6 +300,10 @@ private void RecordedFilesList()
294300

295301
EditorGUILayout.EndHorizontal();
296302
}
303+
if (EditorGUI.EndChangeCheck())
304+
{
305+
_awaitingRefresh.boolValue = true;
306+
}
297307
EditorGUILayout.EndScrollView();
298308
}
299309
}
@@ -324,13 +334,13 @@ private void Playlists()
324334
for (int i = 0; i < _recordedFiles.arraySize; i++)
325335
{
326336
TextAsset t = (TextAsset)_recordedFiles.GetArrayElementAtIndex(i).objectReferenceValue;
327-
if(t == null)
337+
if (t == null)
328338
{
329339
continue;
330340
}
331341
string guid = "";
332342
long local = 0;
333-
if(AssetDatabase.TryGetGUIDAndLocalFileIdentifier(t, out guid, out local))
343+
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(t, out guid, out local))
334344
{
335345
playlist.Add(new PlaylistItem(t.name, AssetDatabase.GUIDToAssetPath(guid), guid));
336346
}
@@ -343,10 +353,10 @@ private void Playlists()
343353

344354
EditorGUI.EndDisabledGroup();
345355

346-
if (GUILayout.Button(new GUIContent("Load Playlist","Loading a playlist will overwrite your current set of loaded files. Playlist order is determined on how files are found, not the order they are present within the file.")))
356+
if (GUILayout.Button(new GUIContent("Load Playlist", "Loading a playlist will overwrite your current set of loaded files. Playlist order is determined on how files are found, not the order they are present within the file.")))
347357
{
348358
var path = EditorUtility.OpenFilePanel("Load Playlist", "", "json");
349-
if(path.Length != 0)
359+
if (path.Length != 0)
350360
{
351361
try
352362
{
@@ -357,7 +367,7 @@ private void Playlists()
357367
for (int i = 0; i < playlist.Count; i++)
358368
{
359369
temp = AssetDatabase.GUIDToAssetPath(playlist[i].guid.ToString());
360-
if(temp.Contains(playlist[i].name + ".bytes"))
370+
if (temp.Contains(playlist[i].name + ".bytes"))
361371
{
362372
textAssets.Add(AssetDatabase.LoadAssetAtPath<TextAsset>(temp));
363373
playlist.RemoveAt(i);
@@ -370,19 +380,19 @@ private void Playlists()
370380
for (int i = 0; i < assets.Length; i++)
371381
{
372382
temp = AssetDatabase.GUIDToAssetPath(assets[i]);
373-
if(temp.EndsWith("bytes"))
383+
if (temp.EndsWith("bytes"))
374384
{
375385
for (int j = 0; j < playlist.Count; j++)
376386
{
377-
if(temp.Contains(playlist[j].name))
387+
if (temp.Contains(playlist[j].name))
378388
{
379389
textAssets.Add(AssetDatabase.LoadAssetAtPath<TextAsset>(temp));
380390
playlist.RemoveAt(j);
381391
break;
382392
}
383393
}
384394
}
385-
if(playlist.Count == 0)
395+
if (playlist.Count == 0)
386396
{
387397
break;
388398
}
@@ -433,7 +443,7 @@ private void RecordComponents()
433443
}
434444
}
435445

436-
GUIContent recordComponents = new GUIContent("Recorded Items (" + _binders.arraySize+")", EditorMessages.playbackRecordItemInfo);
446+
GUIContent recordComponents = new GUIContent("Recorded Items (" + _binders.arraySize + ")", EditorMessages.playbackRecordItemInfo);
437447

438448
EditorGUILayout.BeginHorizontal();
439449

@@ -444,19 +454,19 @@ private void RecordComponents()
444454
GUIContent redLabel = new GUIContent(EditorGUIUtility.IconContent("redLight"));
445455
redLabel.tooltip = EditorMessages.playbackRecordItemInfo;
446456

447-
_binders.isExpanded = EditorGUI.Foldout(foldoutRect,_binders.isExpanded, recordComponents, true, Styles.foldoutBold);
457+
_binders.isExpanded = EditorGUI.Foldout(foldoutRect, _binders.isExpanded, recordComponents, true, Styles.foldoutBold);
448458

449-
EditorGUILayout.LabelField(greenLabel,Styles.textIconBold,GUILayout.Width(Sizes.widthIcon));
459+
EditorGUILayout.LabelField(greenLabel, Styles.textIconBold, GUILayout.Width(Sizes.widthIcon));
450460

451461
GUIContent gcLabel = new GUIContent(assignedCount.ToString(), EditorMessages.playbackRecordItemInfo);
452462

453-
EditorGUILayout.LabelField(gcLabel,Styles.textBold, GUILayout.Width(Styles.textBold.CalcSize(gcLabel).x));
463+
EditorGUILayout.LabelField(gcLabel, Styles.textBold, GUILayout.Width(Styles.textBold.CalcSize(gcLabel).x));
454464

455-
EditorGUILayout.LabelField(redLabel,Styles.textIconBold, GUILayout.Width(Sizes.widthIcon));
465+
EditorGUILayout.LabelField(redLabel, Styles.textIconBold, GUILayout.Width(Sizes.widthIcon));
456466

457467
GUIContent rcLabel = new GUIContent(unassignedCount.ToString(), EditorMessages.playbackRecordItemInfo);
458468

459-
EditorGUILayout.LabelField(rcLabel, Styles.textBold,GUILayout.Width(Styles.textBold.CalcSize(rcLabel).x));
469+
EditorGUILayout.LabelField(rcLabel, Styles.textBold, GUILayout.Width(Styles.textBold.CalcSize(rcLabel).x));
460470

461471
EditorGUILayout.EndHorizontal();
462472

@@ -507,7 +517,7 @@ private void PlaybackIgnoreItems()
507517
EditorGUILayout.LabelField(new GUIContent("Playback Ignore File", "This file controls which components on a RecordComponent's object are NOT disabled when playback begins. If no file is assigned then the default values for each RecordComponent will be used."), Styles.textBold);
508518
_ignoreFile.objectReferenceValue = EditorGUILayout.ObjectField(_ignoreFile.objectReferenceValue, typeof(PlaybackIgnoreComponentsObject), false);
509519
EditorGUILayout.EndHorizontal();
510-
if(_ignoreFile.objectReferenceValue == null)
520+
if (_ignoreFile.objectReferenceValue == null)
511521
{
512522
EditorGUILayout.HelpBox("To create an Ignore File, go to your project assets, right click -> Create -> PlayRecorder -> Playback Ignore Asset. If no file is selected, default values are used.", MessageType.Info);
513523
}
@@ -569,8 +579,5 @@ private void PlaybackControls()
569579

570580
EditorGUI.EndDisabledGroup();
571581
}
572-
573-
574582
}
575-
576583
}

Core/Editor/Scripts/Statistics/StatisticCSVPopup.cs

Lines changed: 71 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using UnityEngine;
55
using UnityEditor;
66
using PlayRecorder.Tools;
7+
using System.Reflection;
78

89
namespace PlayRecorder.Statistics
910
{
@@ -17,37 +18,43 @@ public class StatisticCSVPopup : PopupWindowContent
1718

1819
private string _exampleText = "";
1920

20-
private bool _keepFileNumbers = true, _keepFileNames = true;
21+
private bool _keepFileNumbers = true, _keepFileNames = true, _flattenMultiStats = false;
2122

2223
private int _totalRows = 0;
2324

24-
private const string _keepNumbersKey = "PlayRecorder_CSV_Numbers", _keepNamesKey = "PlayRecorder_CSV_Names";
25+
private const string _keepNumbersKey = "PlayRecorder_CSV_Numbers", _keepNamesKey = "PlayRecorder_CSV_Names", _flattenNamesKey = "PlayRecorder_CSV_Flatten";
2526

2627
private Vector2 _scrollPos = Vector2.zero;
2728

2829
public StatisticCSVPopup(List<StatisticWindow.StatCache> statsCache, float width)
2930
{
3031
_statsCache = statsCache;
3132
_width = width;
32-
for (int i = 0; i < _statsCache.Count; i++)
33-
{
34-
_totalRows += _statsCache[i].values.Length * _statsCache[i].statFields.Length;
35-
}
3633

37-
if(EditorPrefs.HasKey(_keepNumbersKey))
34+
if (EditorPrefs.HasKey(_keepNumbersKey))
3835
{
3936
_keepFileNumbers = EditorPrefs.GetBool(_keepNumbersKey);
4037
}
41-
if(EditorPrefs.HasKey(_keepNamesKey))
38+
if (EditorPrefs.HasKey(_keepNamesKey))
4239
{
4340
_keepFileNames = EditorPrefs.GetBool(_keepNamesKey);
4441
}
45-
_exampleText = GetCSVLines(_statsCache[0]).TrimEnd();
42+
if (EditorPrefs.HasKey(_flattenNamesKey))
43+
{
44+
_flattenMultiStats = EditorPrefs.GetBool(_flattenNamesKey);
45+
}
46+
47+
for (int i = 0; i < _statsCache.Count; i++)
48+
{
49+
_totalRows += _statsCache[i].values.Length * (_flattenMultiStats ? 1 : _statsCache[i].statFields.Length);
50+
}
51+
52+
_exampleText = GetCSVLines(_statsCache[0], 12).TrimEnd();
4653
}
4754

4855
public override Vector2 GetWindowSize()
4956
{
50-
return new Vector2(_width-(Sizes.padding*3), ((Sizes.heightLine+Sizes.padding) * 9));
57+
return new Vector2(_width - (Sizes.padding * 3), ((Sizes.heightLine + Sizes.padding) * 10));
5158
}
5259

5360
public override void OnGUI(Rect rect)
@@ -58,7 +65,7 @@ public override void OnGUI(Rect rect)
5865

5966
GUIContent closeButton = new GUIContent(EditorGUIUtility.IconContent("winbtn_win_close"));
6067

61-
if(GUILayout.Button(closeButton,GUILayout.Width(Sizes.Timeline.widthFileButton)))
68+
if (GUILayout.Button(closeButton, GUILayout.Width(Sizes.Timeline.widthFileButton)))
6269
{
6370
editorWindow.Close();
6471
}
@@ -70,28 +77,44 @@ public override void OnGUI(Rect rect)
7077
bool oldNumbers = _keepFileNumbers;
7178
_keepFileNumbers = EditorGUILayout.Toggle(new GUIContent("Keep File Number", "Adds a column with the current file number as shown in the statistics window for this statistic."), _keepFileNumbers);
7279

73-
if(oldNumbers != _keepFileNumbers)
80+
if (oldNumbers != _keepFileNumbers)
7481
{
7582
EditorPrefs.SetBool(_keepNumbersKey, _keepFileNumbers);
76-
_exampleText = GetCSVLines(_statsCache[0]).TrimEnd();
83+
_exampleText = GetCSVLines(_statsCache[0], 12).TrimEnd();
7784
}
7885

7986
bool oldNames = _keepFileNames;
8087
_keepFileNames = EditorGUILayout.Toggle(new GUIContent("Keep Recording Name", "Adds a column with the current recording name for this statistic."), _keepFileNames);
8188

82-
if(oldNames != _keepFileNames)
89+
if (oldNames != _keepFileNames)
8390
{
8491
EditorPrefs.SetBool(_keepNamesKey, _keepFileNames);
85-
_exampleText = GetCSVLines(_statsCache[0]).TrimEnd();
92+
_exampleText = GetCSVLines(_statsCache[0], 12).TrimEnd();
93+
}
94+
95+
bool oldFlatten = _flattenMultiStats;
96+
_flattenMultiStats = EditorGUILayout.Toggle(new GUIContent("Flatten Stat Components", "By default, statistics with multiple parts will be stored as single row per element. (e.g. Vector3 XYZ -> Vector3_X Vector3_Y Vector3_Z)" +
97+
"This changes it to store it as a single row (e.g. Vector3 XYZ -> (X,Y,Z)"), _flattenMultiStats);
98+
99+
if (oldFlatten != _flattenMultiStats)
100+
{
101+
EditorPrefs.SetBool(_flattenNamesKey, _flattenMultiStats);
102+
_exampleText = GetCSVLines(_statsCache[0], 12).TrimEnd();
103+
104+
_totalRows = 0;
105+
for (int i = 0; i < _statsCache.Count; i++)
106+
{
107+
_totalRows += _statsCache[i].values.Length * (_flattenMultiStats ? 1 : _statsCache[i].statFields.Length);
108+
}
86109
}
87110

88111
EditorGUILayout.EndHorizontal();
89112

90113
EditorGUILayout.LabelField("Example Headers and Rows", Styles.textBold);
91114

92-
_scrollPos = EditorGUILayout.BeginScrollView(_scrollPos, GUILayout.Height((Sizes.heightLine * 4) - Sizes.padding));
115+
_scrollPos = EditorGUILayout.BeginScrollView(_scrollPos, GUILayout.Height((Sizes.heightLine * 5) - Sizes.padding));
93116

94-
EditorGUILayout.TextArea((_keepFileNumbers ? "FileNumber," : "") + (_keepFileNames ? "RecordingName," : "") + _columnsString +
117+
EditorGUILayout.TextArea((_keepFileNumbers ? "FileNumber," : "") + (_keepFileNames ? "RecordingName," : "") + _columnsString +
95118
_exampleText, GUILayout.ExpandHeight(true));
96119

97120
EditorGUILayout.EndScrollView();
@@ -100,23 +123,31 @@ public override void OnGUI(Rect rect)
100123
EditorGUILayout.LabelField($"Columns: {_columnsPreCount + (_keepFileNumbers ? 1 : 0) + (_keepFileNames ? 1 : 0)}");
101124
EditorGUILayout.LabelField($"Rows: {_totalRows}");
102125
EditorGUILayout.EndHorizontal();
103-
if(GUILayout.Button("Export CSV"))
126+
if (GUILayout.Button("Export CSV"))
104127
{
105128
string name = System.DateTime.Now.ToString("yyyyMMddHHmmss") + " " + Application.productName.Replace(".", string.Empty) + " " + UnityEngine.SceneManagement.SceneManager.GetActiveScene().name + " Stats";
106129
string s = EditorUtility.SaveFilePanel("Export CSV", null, name, "csv");
107-
if(s.Length != 0)
130+
if (s.Length != 0)
108131
{
109132
File.WriteAllText(s, GenerateCSV());
110133
}
111134
}
112135
}
113136

114-
private string GetCSVLines(StatisticWindow.StatCache cache)
137+
private string GetCSVLines(StatisticWindow.StatCache cache, int trimLines = 0)
115138
{
116139
string line = "";
117-
for (int i = 0; i < cache.values.Length; i++)
140+
141+
int length = cache.values.Length;
142+
143+
if (trimLines > 0 && cache.values.Length > trimLines)
144+
{
145+
length = trimLines;
146+
}
147+
148+
for (int i = 0; i < length; i++)
118149
{
119-
if (cache.statFields.Length > 1)
150+
if (cache.statFields.Length > 1 && !_flattenMultiStats)
120151
{
121152
for (int y = 0; y < cache.statFields.Length; y++)
122153
{
@@ -133,7 +164,14 @@ private string GetCSVLines(StatisticWindow.StatCache cache)
133164
line += cache.statName.ToCSVCell() + ",";
134165
line += i.ToString() + ",";
135166
line += cache.statTimes[i].ToString() + ",";
136-
line += cache.values[i].ToString().ToCSVCell() + "\n";
167+
if (cache.statFields.Length > 1 && _flattenMultiStats)
168+
{
169+
line += MultiStatSingleLine(cache.statFields, cache.values[i]).ToCSVCell() + "\n";
170+
}
171+
else
172+
{
173+
line += cache.values[i].ToString().ToCSVCell() + "\n";
174+
}
137175
}
138176
}
139177
return line;
@@ -154,6 +192,16 @@ private string AddFileInfo(StatisticWindow.StatCache cache)
154192
return s;
155193
}
156194

195+
private string MultiStatSingleLine(FieldInfo[] fields, object parentObject)
196+
{
197+
string output = "(";
198+
for (int i = 0; i < fields.Length; i++)
199+
{
200+
output += fields[i].GetValue(parentObject).ToString() + (i < fields.Length - 1 ? "," : "");
201+
}
202+
return output + ")";
203+
}
204+
157205
private string GenerateCSV()
158206
{
159207
string output = "";

0 commit comments

Comments
 (0)