DataManager.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. //***********************************************************
  2. // Filename: DataManager.cs
  3. // Author: Niclas
  4. // Last changes: 08 August 2018
  5. // Content: The DataManager which collects, formats and exports experiment data
  6. //***********************************************************
  7. using System;
  8. using System.Collections;
  9. using System.IO;
  10. using UnityEngine;
  11. //TODO: rewrite class to complement the new StudyDataParser
  12. /// <summary>
  13. /// This class collects data from Events, formats them and exports them into a .csv file
  14. /// </summary>
  15. public class DataManager : MonoBehaviour {
  16. // Holds all data collected thus far
  17. private readonly ArrayList expData = new ArrayList();
  18. // Number of teleports while a specific target is active
  19. private int currentTeleports = 0;
  20. // Holds a reference to the GameManager for future use
  21. private GameManager gManager;
  22. // Id of the currently active target, doubles as target count, starts with 0
  23. private int currentTargetId;
  24. // Coordinates of the currently active target
  25. private Vector3 currentTargetPos;
  26. // Rotation of the currently active target
  27. private Vector3 currentTargetRot;
  28. // Distance between the current target and the one before
  29. private float currentTargetDist = 0;
  30. // Unique user id in case none gets set
  31. private string userId = Guid.NewGuid().ToString();
  32. // Delimiter between items, used to format to .csv
  33. private const string Del = ",";
  34. // Use this for initialization
  35. void Start() {
  36. gManager = GetComponentInParent<GameManager>();
  37. // Register listerners to their event
  38. TargetSpawnedEvent.RegisterListener(OnTargetSpawned);
  39. TargetReachedEvent.RegisterListener(OnTargetReached);
  40. TeleportEvent.RegisterListener(OnTeleport);
  41. ExperimentEndEvent.RegisterListener(OnExperimentEnd);
  42. }
  43. private void OnDestroy() {
  44. // Unregister listeners from their event
  45. TargetSpawnedEvent.UnregisterListener(OnTargetSpawned);
  46. TargetReachedEvent.UnregisterListener(OnTargetReached);
  47. TeleportEvent.UnregisterListener(OnTeleport);
  48. ExperimentEndEvent.UnregisterListener(OnExperimentEnd);
  49. }
  50. /// <summary>
  51. /// Listener for TargetSpawnedEvent, extracts information about the current target to variables
  52. /// </summary>
  53. /// <param name="tse">The Event, contains its information</param>
  54. private void OnTargetSpawned(TargetSpawnedEvent tse) {
  55. currentTargetId = tse.targetId;
  56. // Distance to spawned target, 0 if startTarget
  57. currentTargetDist = Vector3.Distance(currentTargetPos, tse.targetTransform.position);
  58. currentTargetPos = tse.targetTransform.position;
  59. currentTargetRot = tse.targetTransform.rotation.eulerAngles;
  60. }
  61. /// <summary>
  62. /// Listener for TeleportEvent, adds a row with data about the teleport in expData
  63. /// </summary>
  64. /// <param name="te">The Event, contains its information</param>
  65. private void OnTeleport(TeleportEvent te) {
  66. if (currentTargetId == 0)
  67. return;
  68. currentTeleports++;
  69. string row = currentTargetId + Del +
  70. currentTeleports + Del +
  71. currentTargetPos.x + Del +
  72. currentTargetPos.z + Del +
  73. currentTargetRot.y + Del +
  74. te.startUserPosition.x + Del +
  75. te.startUserPosition.z + Del +
  76. te.startUserRotation.y + Del +
  77. te.startTeleportTime + Del +
  78. te.endUserPosition.x + Del +
  79. te.endUserPosition.z + Del +
  80. te.endUserRotation.y + Del +
  81. te.endTeleportTime + Del +
  82. (te.endTeleportTime - te.startTeleportTime) + Del +
  83. 0 + Del +
  84. Mathf.Sqrt(Mathf.Pow(te.endUserPosition.x - currentTargetPos.x, 2) + Mathf.Pow(te.endUserPosition.z - currentTargetPos.z, 2)) + Del +
  85. (te.endUserRotation.y - currentTargetRot.y + 180) % 360 + Del +
  86. currentTargetDist;
  87. expData.Add(row);
  88. }
  89. /// <summary>
  90. /// Listener for TargetReachedEvent, adds row to expData with data about the reached target and player, ends a teleport chain
  91. /// </summary>
  92. /// <param name="tre">The Event, contains its information</param>
  93. private void OnTargetReached(TargetReachedEvent tre) {
  94. Debug.Log("Received Target information, id: " + tre.targetId + " time: " + tre.time);
  95. string row = tre.targetId + Del +
  96. (-1) + Del +
  97. tre.targetTransform.position.x + Del +
  98. tre.targetTransform.position.z + Del +
  99. tre.targetTransform.rotation.eulerAngles.y + Del +
  100. 0 + Del +
  101. 0 + Del +
  102. 0 + Del +
  103. 0 + Del +
  104. tre.playerTransform.position.x + Del +
  105. tre.playerTransform.position.z + Del +
  106. tre.playerTransform.rotation.eulerAngles.y + Del +
  107. 0 + Del +
  108. 0 + Del +
  109. 0 + Del +
  110. tre.time + Del +
  111. Mathf.Sqrt(Mathf.Pow(tre.playerTransform.position.x - tre.targetTransform.position.x, 2) + Mathf.Pow(tre.playerTransform.position.z - tre.targetTransform.position.z, 2)) + Del +
  112. (tre.targetTransform.rotation.eulerAngles.y - tre.playerTransform.rotation.eulerAngles.y - 180) % 360 + Del +
  113. currentTargetDist;
  114. expData.Add(row);
  115. currentTeleports = 0;
  116. }
  117. /// <summary>
  118. /// Listener for ExperimentEndEvent, sets userID and invokes WriteToFile() to write the .csv file.
  119. /// Invokes with one second delay to give the last Events time to finish processing
  120. /// </summary>
  121. /// <param name="e">The Event, contains its information, however none is required at the moment</param>
  122. private void OnExperimentEnd(ExperimentEndEvent e) {
  123. if (gManager.testSubjectId != "") {
  124. userId = gManager.testSubjectId;
  125. }
  126. // Waiting for last TargetReachedEvent to process
  127. Invoke("WriteToFile", 1);
  128. }
  129. /// <summary>
  130. /// Creates a new .csv file with userID, movement method and date as name.
  131. /// Writes first row with names of the columns, afterwards each string in expData as new row
  132. /// </summary>
  133. private void WriteToFile() {
  134. string filepath = string.Format(@"{0}-{1}-{2:yyyy-MM-dd_HH-mm-ss}.csv", GetComponentInParent<GameManager>().movementMethod, userId, DateTime.Now);
  135. using (StreamWriter writer = new StreamWriter(new FileStream(filepath, FileMode.Create, FileAccess.Write))) {
  136. writer.WriteLine("TargetID, TeleportID, TargetPositionX, TargetPositionZ, TargetRotation, PlayerLastPosX, PlayerLastPosZ, PlayerLastRot, TelStartTime, PlayerPosX, PlayerPosZ, PlayerRotation, TelEndTime, TelDistance, TelTime, TimeNeeded, OffsetPos, OffsetRot, DistTargetToTarget");
  137. foreach (string row in expData) {
  138. writer.WriteLine(row);
  139. }
  140. }
  141. Debug.Log("Data written");
  142. }
  143. }