Skip to content

Commit 9ff2f47

Browse files
committed
Merge branch 'mwarb-improved-trackers' into master
2 parents a542376 + d1e0f8f commit 9ff2f47

12 files changed

+258
-19
lines changed

Assets/UXF/Examples/4_CorsiBlock/CorsiBlockExample.unity

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,6 +2348,11 @@ PrefabInstance:
23482348
propertyPath: settingsToLog.Array.size
23492349
value: 1
23502350
objectReference: {fileID: 0}
2351+
- target: {fileID: 114916036141644208, guid: 0a3b6392f04558844bd340e68ced1ff9,
2352+
type: 3}
2353+
propertyPath: trackedObjects.Array.size
2354+
value: 1
2355+
objectReference: {fileID: 0}
23512356
- target: {fileID: 114916036141644208, guid: 0a3b6392f04558844bd340e68ced1ff9,
23522357
type: 3}
23532358
propertyPath: onSessionBegin.m_PersistentCalls.m_Calls.Array.data[0].m_Mode
@@ -2593,6 +2598,11 @@ PrefabInstance:
25932598
propertyPath: storeSessionSettings
25942599
value: 0
25952600
objectReference: {fileID: 0}
2601+
- target: {fileID: 114916036141644208, guid: 0a3b6392f04558844bd340e68ced1ff9,
2602+
type: 3}
2603+
propertyPath: trackedObjects.Array.data[0]
2604+
value:
2605+
objectReference: {fileID: 0}
25962606
- target: {fileID: 203569540471596912, guid: 0a3b6392f04558844bd340e68ced1ff9,
25972607
type: 3}
25982608
propertyPath: m_Value
@@ -2856,7 +2866,7 @@ PrefabInstance:
28562866
- target: {fileID: 2834388984357925155, guid: 0a3b6392f04558844bd340e68ced1ff9,
28572867
type: 3}
28582868
propertyPath: m_AnchoredPosition.y
2859-
value: 2080
2869+
value: 4225
28602870
objectReference: {fileID: 0}
28612871
- target: {fileID: 2896031059644693069, guid: 0a3b6392f04558844bd340e68ced1ff9,
28622872
type: 3}
@@ -2946,7 +2956,7 @@ PrefabInstance:
29462956
- target: {fileID: 4267567203292169432, guid: 0a3b6392f04558844bd340e68ced1ff9,
29472957
type: 3}
29482958
propertyPath: m_AnchoredPosition.y
2949-
value: 3840
2959+
value: 7800
29502960
objectReference: {fileID: 0}
29512961
- target: {fileID: 4298776666381973480, guid: 0a3b6392f04558844bd340e68ced1ff9,
29522962
type: 3}
@@ -4836,6 +4846,7 @@ GameObject:
48364846
m_Component:
48374847
- component: {fileID: 1513556399}
48384848
- component: {fileID: 1513556400}
4849+
- component: {fileID: 1513556401}
48394850
m_Layer: 0
48404851
m_Name: CorsiBlockTask
48414852
m_TagString: Untagged
@@ -4898,6 +4909,27 @@ MonoBehaviour:
48984909
- {fileID: 1622668012}
48994910
randomOffsetMax: {x: 0.5, y: 0.5}
49004911
feedback: {fileID: 448119297}
4912+
--- !u!114 &1513556401
4913+
MonoBehaviour:
4914+
m_ObjectHideFlags: 0
4915+
m_CorrespondingSourceObject: {fileID: 0}
4916+
m_PrefabInstance: {fileID: 0}
4917+
m_PrefabAsset: {fileID: 0}
4918+
m_GameObject: {fileID: 1513556398}
4919+
m_Enabled: 1
4920+
m_EditorHideFlags: 0
4921+
m_Script: {fileID: 11500000, guid: 7e116bc94825b784182983179cfbb420, type: 3}
4922+
m_Name:
4923+
m_EditorClassIdentifier:
4924+
objectName: corsiblocktask
4925+
measurementDescriptor: mouse_position
4926+
customHeader:
4927+
- pos_x
4928+
- pos_y
4929+
- pos_z
4930+
updateType: 0
4931+
distanceFromCamera: 25
4932+
mainCamera: {fileID: 33142922}
49014933
--- !u!1 &1574932393
49024934
GameObject:
49034935
m_ObjectHideFlags: 0

Assets/UXF/Scripts/Etc/Tracker.cs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public string dataName
4141

4242
private bool recording;
4343

44+
public bool Recording { get { return recording; } }
45+
4446
public UXFDataTable data { get; private set; } = new UXFDataTable();
4547

4648
/// <summary>
@@ -56,7 +58,13 @@ public string[] header
5658
customHeader.CopyTo(newHeader, 1);
5759
return newHeader;
5860
}
59-
}
61+
}
62+
63+
/// <summary>
64+
/// When the tracker should take measurements.
65+
/// </summary>
66+
[Tooltip("When the measurements should be taken.\n\nManual should only be selected if the user is calling the RecordRow method either from another script or a custom Tracker class.")]
67+
public TrackerUpdateType updateType = TrackerUpdateType.LateUpdate;
6068

6169
// called when component is added
6270
void Reset()
@@ -68,20 +76,27 @@ void Reset()
6876
// called by unity just before rendering the frame
6977
void LateUpdate()
7078
{
71-
if (recording) RecordRow();
79+
if (recording && updateType == TrackerUpdateType.LateUpdate) RecordRow();
80+
}
81+
82+
// called by unity when physics simulations are run
83+
void FixedUpdate()
84+
{
85+
if (recording && updateType == TrackerUpdateType.FixedUpdate) RecordRow();
7286
}
7387

7488
/// <summary>
7589
/// Records a new row of data at current time.
7690
/// </summary>
7791
public void RecordRow()
7892
{
93+
if (!recording) throw new System.InvalidOperationException("Tracker measurements cannot be taken when not in a trial!");
94+
7995
UXFDataRow newRow = GetCurrentValues();
8096
newRow.Add(("time", Time.time));
8197
data.AddCompleteRow(newRow);
8298
}
8399

84-
85100
/// <summary>
86101
/// Begins recording.
87102
/// </summary>
@@ -91,14 +106,6 @@ public void StartRecording()
91106
recording = true;
92107
}
93108

94-
/// <summary>
95-
/// Pauses recording.
96-
/// </summary>
97-
public void PauseRecording()
98-
{
99-
recording = false;
100-
}
101-
102109
/// <summary>
103110
/// Stops recording.
104111
/// </summary>
@@ -119,4 +126,12 @@ public void StopRecording()
119126
protected abstract void SetupDescriptorAndHeader();
120127

121128
}
129+
130+
/// <summary>
131+
/// When the tracker should collect new measurements. Manual should only be selected if the user is calling the RecordRow method either from another script or a custom Tracker class.
132+
/// </summary>
133+
public enum TrackerUpdateType
134+
{
135+
LateUpdate, FixedUpdate, Manual
136+
}
122137
}

Assets/UXF/Scripts/Etc/Tracker.cs.meta

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/UXF/Scripts/Etc/Trial.cs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,14 @@ public void Begin()
9595

9696
foreach (Tracker tracker in session.trackedObjects)
9797
{
98-
tracker.StartRecording();
98+
try
99+
{
100+
tracker.StartRecording();
101+
}
102+
catch (NullReferenceException)
103+
{
104+
Debug.LogWarning("An item in the Tracked Objects field of the UXF session if empty (null)!");
105+
}
99106
}
100107
session.onTrialBegin.Invoke(this);
101108
}
@@ -107,12 +114,29 @@ public void End()
107114
{
108115
status = TrialStatus.Done;
109116
endTime = Time.time;
110-
result["end_time"] = endTime;
117+
result["end_time"] = endTime;
118+
119+
// check no duplicate trackers
120+
List<string> duplicateTrackers = session.trackedObjects.Where(tracker => tracker != null)
121+
.GroupBy(tracker => tracker.dataName)
122+
.Where(g => g.Count() > 1)
123+
.Select(y => y.Key)
124+
.ToList();
125+
126+
if (duplicateTrackers.Any()) throw new InvalidOperationException(string.Format("Two or more trackers in the Tracked Objects field in the Session Inspector have the following object name and descriptor pair, please change the object name fields on the trackers to make them unique: {0}", string.Join(",", duplicateTrackers)));
111127

112128
// log tracked objects
113129
foreach (Tracker tracker in session.trackedObjects)
114130
{
115-
SaveDataTable(tracker.data, tracker.dataName, dataType: UXFDataType.Trackers);
131+
try
132+
{
133+
tracker.StopRecording();
134+
SaveDataTable(tracker.data, tracker.dataName, dataType: UXFDataType.Trackers);
135+
}
136+
catch (NullReferenceException)
137+
{
138+
Debug.LogWarning("An item in the Tracked Objects field of the UXF session if empty (null)!");
139+
}
116140
}
117141

118142
// log any settings we need to for this trial

Assets/UXF/Scripts/Trackers.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using UnityEngine;
2+
3+
namespace UXF
4+
{
5+
/// <summary>
6+
/// Attach this component to any gameobject and assign it in the trackedObjects field in an ExperimentSession to automatically record the position of the mouse in screen coordinates.
7+
/// Note (0, 0) is the bottom-left of the window displaying the game.
8+
/// </summary>
9+
public class MouseScreenTracker : Tracker
10+
{
11+
/// <summary>
12+
/// Sets measurementDescriptor and customHeader to appropriate values
13+
/// </summary>
14+
protected override void SetupDescriptorAndHeader()
15+
{
16+
measurementDescriptor = "mouse_screen";
17+
18+
customHeader = new string[]
19+
{
20+
"pix_x",
21+
"pix_y"
22+
};
23+
}
24+
25+
/// <summary>
26+
/// Returns current mouse position in screen coordinates
27+
/// </summary>
28+
/// <returns></returns>
29+
protected override UXFDataRow GetCurrentValues()
30+
{
31+
// get position and rotation
32+
Vector2 p = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
33+
34+
string format = "0";
35+
36+
// return position, rotation (x, y, z) as an array
37+
var values = new UXFDataRow()
38+
{
39+
("pix_x", p.x.ToString(format)),
40+
("pix_y", p.y.ToString(format))
41+
};
42+
43+
return values;
44+
}
45+
}
46+
}

Assets/UXF/Scripts/Trackers/MouseScreenTracker.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using UnityEngine;
2+
3+
namespace UXF
4+
{
5+
/// <summary>
6+
/// Attach this component to any gameobject and assign it in the trackedObjects field in an ExperimentSession to automatically record the position of the mouse in world coordinates.
7+
/// </summary>
8+
public class MouseWorldTracker : Tracker
9+
{
10+
[Tooltip("Distance from the camera plane to convert pixels to world point.\n\nFor perspective cameras this should be the distance from the camera to the plane you're interested in measuring.\n\nFor orthographic cameras this value shouldn't matter.")]
11+
public float distanceFromCamera = 1f;
12+
13+
[Tooltip("Assign the main camera in the scene here.")]
14+
public Camera mainCamera;
15+
16+
/// <summary>
17+
/// Sets measurementDescriptor and customHeader to appropriate values
18+
/// </summary>
19+
protected override void SetupDescriptorAndHeader()
20+
{
21+
measurementDescriptor = "mouse_world";
22+
23+
customHeader = new string[]
24+
{
25+
"pos_x",
26+
"pos_y",
27+
"pos_z",
28+
};
29+
}
30+
31+
/// <summary>
32+
/// Returns current mouse position in world coordinates
33+
/// </summary>
34+
/// <returns></returns>
35+
protected override UXFDataRow GetCurrentValues()
36+
{
37+
// get position and rotation
38+
Vector3 p = mainCamera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, distanceFromCamera));
39+
40+
string format = "0.####";
41+
42+
// return position, rotation (x, y, z) as an array
43+
var values = new UXFDataRow()
44+
{
45+
("pos_x", p.x.ToString(format)),
46+
("pos_y", p.y.ToString(format)),
47+
("pos_z", p.z.ToString(format))
48+
};
49+
50+
return values;
51+
}
52+
}
53+
}

Assets/UXF/Scripts/Trackers/MouseWorldTracker.cs.meta

Lines changed: 11 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)