Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
rorygames committed Jul 20, 2023
2 parents cebbaf9 + a1cb18c commit 523378b
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 69 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.1.3]

### Added
- Rotation statistic recording
- Option to flatten multipart statistics (e.g. XYZ) into a single line during CSV export

### Changed
- Playback file checks are more aggressive to ensure file changes are accounted for

## [1.1.2] - 11/07/23

### Added
Expand Down
57 changes: 32 additions & 25 deletions Core/Editor/Scripts/PlaybackManagerEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public class PlaybackManagerEditor : Editor
private SerializedProperty _timeCounter;
private SerializedProperty _ignoreFile;

private bool _awaitingRefreshVal = false;

private string _componentFilter = "";

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

private void OnDestroy()
{
if (_awaitingRefreshVal)
{
Debug.LogWarning("Playback Manager needs to Update Files before you can enter play mode.", serializedObject.targetObject);
}
}

public override bool RequiresConstantRepaint()
{
return false;
Expand All @@ -65,6 +75,7 @@ private void SetProperties()
_binders = serializedObject.FindProperty("_binders");
_currentFile = serializedObject.FindProperty("_currentFile");
_awaitingRefresh = serializedObject.FindProperty("_awaitingFileRefresh");
_awaitingRefreshVal = _awaitingRefresh.boolValue;
_oldFileIndex = serializedObject.FindProperty("_oldFileIndex");
_playing = serializedObject.FindProperty("_playing");
_changingFiles = serializedObject.FindProperty("_changingFiles");
Expand Down Expand Up @@ -248,19 +259,15 @@ private void RecordedFilesList()
if (_recordedFiles.isExpanded)
{
_fileScrollPos = EditorGUILayout.BeginScrollView(_fileScrollPos, GUILayout.Height(Sizes.Playback.heightFileScroll));
EditorGUI.BeginChangeCheck();
for (int i = 0; i < _recordedFiles.arraySize; i++)
{
if (!(_fileScrollPos.y - ((Sizes.heightLine + Sizes.padding)*2) <= ((Sizes.heightLine+Sizes.padding) * (i - 1)) && _fileScrollPos.y + Sizes.Playback.heightFileScroll > ((Sizes.heightLine + Sizes.padding) * i)))
if (!(_fileScrollPos.y - ((Sizes.heightLine + Sizes.padding) * 2) <= ((Sizes.heightLine + Sizes.padding) * (i - 1)) && _fileScrollPos.y + Sizes.Playback.heightFileScroll > ((Sizes.heightLine + Sizes.padding) * i)))
{
EditorGUILayout.LabelField("");
continue;
}

if (_recordedFiles.GetArrayElementAtIndex(i).objectReferenceValue == null)
{
_awaitingRefresh.boolValue = true;
}

EditorGUILayout.BeginHorizontal();

EditorGUI.BeginDisabledGroup(_awaitingRefresh.boolValue);
Expand All @@ -283,7 +290,6 @@ private void RecordedFilesList()
{
_recordedFiles.GetArrayElementAtIndex(i).objectReferenceValue = null;
_recordedFiles.DeleteArrayElementAtIndex(i);
_awaitingRefresh.boolValue = true;
if (_currentFile.intValue >= _recordedFiles.arraySize)
{
_currentFile.intValue = _recordedFiles.arraySize - 1;
Expand All @@ -294,6 +300,10 @@ private void RecordedFilesList()

EditorGUILayout.EndHorizontal();
}
if (EditorGUI.EndChangeCheck())
{
_awaitingRefresh.boolValue = true;
}
EditorGUILayout.EndScrollView();
}
}
Expand Down Expand Up @@ -324,13 +334,13 @@ private void Playlists()
for (int i = 0; i < _recordedFiles.arraySize; i++)
{
TextAsset t = (TextAsset)_recordedFiles.GetArrayElementAtIndex(i).objectReferenceValue;
if(t == null)
if (t == null)
{
continue;
}
string guid = "";
long local = 0;
if(AssetDatabase.TryGetGUIDAndLocalFileIdentifier(t, out guid, out local))
if (AssetDatabase.TryGetGUIDAndLocalFileIdentifier(t, out guid, out local))
{
playlist.Add(new PlaylistItem(t.name, AssetDatabase.GUIDToAssetPath(guid), guid));
}
Expand All @@ -343,10 +353,10 @@ private void Playlists()

EditorGUI.EndDisabledGroup();

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.")))
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.")))
{
var path = EditorUtility.OpenFilePanel("Load Playlist", "", "json");
if(path.Length != 0)
if (path.Length != 0)
{
try
{
Expand All @@ -357,7 +367,7 @@ private void Playlists()
for (int i = 0; i < playlist.Count; i++)
{
temp = AssetDatabase.GUIDToAssetPath(playlist[i].guid.ToString());
if(temp.Contains(playlist[i].name + ".bytes"))
if (temp.Contains(playlist[i].name + ".bytes"))
{
textAssets.Add(AssetDatabase.LoadAssetAtPath<TextAsset>(temp));
playlist.RemoveAt(i);
Expand All @@ -370,19 +380,19 @@ private void Playlists()
for (int i = 0; i < assets.Length; i++)
{
temp = AssetDatabase.GUIDToAssetPath(assets[i]);
if(temp.EndsWith("bytes"))
if (temp.EndsWith("bytes"))
{
for (int j = 0; j < playlist.Count; j++)
{
if(temp.Contains(playlist[j].name))
if (temp.Contains(playlist[j].name))
{
textAssets.Add(AssetDatabase.LoadAssetAtPath<TextAsset>(temp));
playlist.RemoveAt(j);
break;
}
}
}
if(playlist.Count == 0)
if (playlist.Count == 0)
{
break;
}
Expand Down Expand Up @@ -433,7 +443,7 @@ private void RecordComponents()
}
}

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

EditorGUILayout.BeginHorizontal();

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

_binders.isExpanded = EditorGUI.Foldout(foldoutRect,_binders.isExpanded, recordComponents, true, Styles.foldoutBold);
_binders.isExpanded = EditorGUI.Foldout(foldoutRect, _binders.isExpanded, recordComponents, true, Styles.foldoutBold);

EditorGUILayout.LabelField(greenLabel,Styles.textIconBold,GUILayout.Width(Sizes.widthIcon));
EditorGUILayout.LabelField(greenLabel, Styles.textIconBold, GUILayout.Width(Sizes.widthIcon));

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

EditorGUILayout.LabelField(gcLabel,Styles.textBold, GUILayout.Width(Styles.textBold.CalcSize(gcLabel).x));
EditorGUILayout.LabelField(gcLabel, Styles.textBold, GUILayout.Width(Styles.textBold.CalcSize(gcLabel).x));

EditorGUILayout.LabelField(redLabel,Styles.textIconBold, GUILayout.Width(Sizes.widthIcon));
EditorGUILayout.LabelField(redLabel, Styles.textIconBold, GUILayout.Width(Sizes.widthIcon));

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

EditorGUILayout.LabelField(rcLabel, Styles.textBold,GUILayout.Width(Styles.textBold.CalcSize(rcLabel).x));
EditorGUILayout.LabelField(rcLabel, Styles.textBold, GUILayout.Width(Styles.textBold.CalcSize(rcLabel).x));

EditorGUILayout.EndHorizontal();

Expand Down Expand Up @@ -507,7 +517,7 @@ private void PlaybackIgnoreItems()
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);
_ignoreFile.objectReferenceValue = EditorGUILayout.ObjectField(_ignoreFile.objectReferenceValue, typeof(PlaybackIgnoreComponentsObject), false);
EditorGUILayout.EndHorizontal();
if(_ignoreFile.objectReferenceValue == null)
if (_ignoreFile.objectReferenceValue == null)
{
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);
}
Expand Down Expand Up @@ -569,8 +579,5 @@ private void PlaybackControls()

EditorGUI.EndDisabledGroup();
}


}

}
94 changes: 71 additions & 23 deletions Core/Editor/Scripts/Statistics/StatisticCSVPopup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using UnityEngine;
using UnityEditor;
using PlayRecorder.Tools;
using System.Reflection;

namespace PlayRecorder.Statistics
{
Expand All @@ -17,37 +18,43 @@ public class StatisticCSVPopup : PopupWindowContent

private string _exampleText = "";

private bool _keepFileNumbers = true, _keepFileNames = true;
private bool _keepFileNumbers = true, _keepFileNames = true, _flattenMultiStats = false;

private int _totalRows = 0;

private const string _keepNumbersKey = "PlayRecorder_CSV_Numbers", _keepNamesKey = "PlayRecorder_CSV_Names";
private const string _keepNumbersKey = "PlayRecorder_CSV_Numbers", _keepNamesKey = "PlayRecorder_CSV_Names", _flattenNamesKey = "PlayRecorder_CSV_Flatten";

private Vector2 _scrollPos = Vector2.zero;

public StatisticCSVPopup(List<StatisticWindow.StatCache> statsCache, float width)
{
_statsCache = statsCache;
_width = width;
for (int i = 0; i < _statsCache.Count; i++)
{
_totalRows += _statsCache[i].values.Length * _statsCache[i].statFields.Length;
}

if(EditorPrefs.HasKey(_keepNumbersKey))
if (EditorPrefs.HasKey(_keepNumbersKey))
{
_keepFileNumbers = EditorPrefs.GetBool(_keepNumbersKey);
}
if(EditorPrefs.HasKey(_keepNamesKey))
if (EditorPrefs.HasKey(_keepNamesKey))
{
_keepFileNames = EditorPrefs.GetBool(_keepNamesKey);
}
_exampleText = GetCSVLines(_statsCache[0]).TrimEnd();
if (EditorPrefs.HasKey(_flattenNamesKey))
{
_flattenMultiStats = EditorPrefs.GetBool(_flattenNamesKey);
}

for (int i = 0; i < _statsCache.Count; i++)
{
_totalRows += _statsCache[i].values.Length * (_flattenMultiStats ? 1 : _statsCache[i].statFields.Length);
}

_exampleText = GetCSVLines(_statsCache[0], 12).TrimEnd();
}

public override Vector2 GetWindowSize()
{
return new Vector2(_width-(Sizes.padding*3), ((Sizes.heightLine+Sizes.padding) * 9));
return new Vector2(_width - (Sizes.padding * 3), ((Sizes.heightLine + Sizes.padding) * 10));
}

public override void OnGUI(Rect rect)
Expand All @@ -58,7 +65,7 @@ public override void OnGUI(Rect rect)

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

if(GUILayout.Button(closeButton,GUILayout.Width(Sizes.Timeline.widthFileButton)))
if (GUILayout.Button(closeButton, GUILayout.Width(Sizes.Timeline.widthFileButton)))
{
editorWindow.Close();
}
Expand All @@ -70,28 +77,44 @@ public override void OnGUI(Rect rect)
bool oldNumbers = _keepFileNumbers;
_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);

if(oldNumbers != _keepFileNumbers)
if (oldNumbers != _keepFileNumbers)
{
EditorPrefs.SetBool(_keepNumbersKey, _keepFileNumbers);
_exampleText = GetCSVLines(_statsCache[0]).TrimEnd();
_exampleText = GetCSVLines(_statsCache[0], 12).TrimEnd();
}

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

if(oldNames != _keepFileNames)
if (oldNames != _keepFileNames)
{
EditorPrefs.SetBool(_keepNamesKey, _keepFileNames);
_exampleText = GetCSVLines(_statsCache[0]).TrimEnd();
_exampleText = GetCSVLines(_statsCache[0], 12).TrimEnd();
}

bool oldFlatten = _flattenMultiStats;
_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)" +
"This changes it to store it as a single row (e.g. Vector3 XYZ -> (X,Y,Z)"), _flattenMultiStats);

if (oldFlatten != _flattenMultiStats)
{
EditorPrefs.SetBool(_flattenNamesKey, _flattenMultiStats);
_exampleText = GetCSVLines(_statsCache[0], 12).TrimEnd();

_totalRows = 0;
for (int i = 0; i < _statsCache.Count; i++)
{
_totalRows += _statsCache[i].values.Length * (_flattenMultiStats ? 1 : _statsCache[i].statFields.Length);
}
}

EditorGUILayout.EndHorizontal();

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

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

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

EditorGUILayout.EndScrollView();
Expand All @@ -100,23 +123,31 @@ public override void OnGUI(Rect rect)
EditorGUILayout.LabelField($"Columns: {_columnsPreCount + (_keepFileNumbers ? 1 : 0) + (_keepFileNames ? 1 : 0)}");
EditorGUILayout.LabelField($"Rows: {_totalRows}");
EditorGUILayout.EndHorizontal();
if(GUILayout.Button("Export CSV"))
if (GUILayout.Button("Export CSV"))
{
string name = System.DateTime.Now.ToString("yyyyMMddHHmmss") + " " + Application.productName.Replace(".", string.Empty) + " " + UnityEngine.SceneManagement.SceneManager.GetActiveScene().name + " Stats";
string s = EditorUtility.SaveFilePanel("Export CSV", null, name, "csv");
if(s.Length != 0)
if (s.Length != 0)
{
File.WriteAllText(s, GenerateCSV());
}
}
}

private string GetCSVLines(StatisticWindow.StatCache cache)
private string GetCSVLines(StatisticWindow.StatCache cache, int trimLines = 0)
{
string line = "";
for (int i = 0; i < cache.values.Length; i++)

int length = cache.values.Length;

if (trimLines > 0 && cache.values.Length > trimLines)
{
length = trimLines;
}

for (int i = 0; i < length; i++)
{
if (cache.statFields.Length > 1)
if (cache.statFields.Length > 1 && !_flattenMultiStats)
{
for (int y = 0; y < cache.statFields.Length; y++)
{
Expand All @@ -133,7 +164,14 @@ private string GetCSVLines(StatisticWindow.StatCache cache)
line += cache.statName.ToCSVCell() + ",";
line += i.ToString() + ",";
line += cache.statTimes[i].ToString() + ",";
line += cache.values[i].ToString().ToCSVCell() + "\n";
if (cache.statFields.Length > 1 && _flattenMultiStats)
{
line += MultiStatSingleLine(cache.statFields, cache.values[i]).ToCSVCell() + "\n";
}
else
{
line += cache.values[i].ToString().ToCSVCell() + "\n";
}
}
}
return line;
Expand All @@ -154,6 +192,16 @@ private string AddFileInfo(StatisticWindow.StatCache cache)
return s;
}

private string MultiStatSingleLine(FieldInfo[] fields, object parentObject)
{
string output = "(";
for (int i = 0; i < fields.Length; i++)
{
output += fields[i].GetValue(parentObject).ToString() + (i < fields.Length - 1 ? "," : "");
}
return output + ")";
}

private string GenerateCSV()
{
string output = "";
Expand Down
Loading

0 comments on commit 523378b

Please sign in to comment.