123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- //***********************************************************
- // Filename: DataManager.cs
- // Author: Niclas
- // Last changes: 08 August 2018
- // Content: The DataManager which collects, formats and exports experiment data
- //***********************************************************
- using System;
- using System.Collections;
- using System.IO;
- using UnityEngine;
- //TODO: rewrite class to complement the new StudyDataParser
- /// <summary>
- /// This class collects data from Events, formats them and exports them into a .csv file
- /// </summary>
- public class DataManager : MonoBehaviour {
- // Holds all data collected thus far
- private readonly ArrayList expData = new ArrayList();
- // Number of teleports while a specific target is active
- private int currentTeleports = 0;
- // Holds a reference to the GameManager for future use
- private GameManager gManager;
- // Id of the currently active target, doubles as target count, starts with 0
- private int currentTargetId;
- // Coordinates of the currently active target
- private Vector3 currentTargetPos;
- // Rotation of the currently active target
- private Vector3 currentTargetRot;
- // Distance between the current target and the one before
- private float currentTargetDist = 0;
- // Unique user id in case none gets set
- private string userId = Guid.NewGuid().ToString();
- // Delimiter between items, used to format to .csv
- private const string Del = ",";
- // Use this for initialization
- void Start() {
- gManager = GetComponentInParent<GameManager>();
- // Register listerners to their event
- TargetSpawnedEvent.RegisterListener(OnTargetSpawned);
- TargetReachedEvent.RegisterListener(OnTargetReached);
- TeleportEvent.RegisterListener(OnTeleport);
- ExperimentEndEvent.RegisterListener(OnExperimentEnd);
- }
- private void OnDestroy() {
- // Unregister listeners from their event
- TargetSpawnedEvent.UnregisterListener(OnTargetSpawned);
- TargetReachedEvent.UnregisterListener(OnTargetReached);
- TeleportEvent.UnregisterListener(OnTeleport);
- ExperimentEndEvent.UnregisterListener(OnExperimentEnd);
- }
- /// <summary>
- /// Listener for TargetSpawnedEvent, extracts information about the current target to variables
- /// </summary>
- /// <param name="tse">The Event, contains its information</param>
- private void OnTargetSpawned(TargetSpawnedEvent tse) {
- currentTargetId = tse.targetId;
- // Distance to spawned target, 0 if startTarget
- currentTargetDist = Vector3.Distance(currentTargetPos, tse.targetTransform.position);
- currentTargetPos = tse.targetTransform.position;
- currentTargetRot = tse.targetTransform.rotation.eulerAngles;
- }
- /// <summary>
- /// Listener for TeleportEvent, adds a row with data about the teleport in expData
- /// </summary>
- /// <param name="te">The Event, contains its information</param>
- private void OnTeleport(TeleportEvent te) {
- if (currentTargetId == 0)
- return;
- currentTeleports++;
- string row = currentTargetId + Del +
- currentTeleports + Del +
- currentTargetPos.x + Del +
- currentTargetPos.z + Del +
- currentTargetRot.y + Del +
- te.startUserPosition.x + Del +
- te.startUserPosition.z + Del +
- te.startUserRotation.y + Del +
- te.startTeleportTime + Del +
- te.endUserPosition.x + Del +
- te.endUserPosition.z + Del +
- te.endUserRotation.y + Del +
- te.endTeleportTime + Del +
- (te.endTeleportTime - te.startTeleportTime) + Del +
- 0 + Del +
- Mathf.Sqrt(Mathf.Pow(te.endUserPosition.x - currentTargetPos.x, 2) + Mathf.Pow(te.endUserPosition.z - currentTargetPos.z, 2)) + Del +
- (te.endUserRotation.y - currentTargetRot.y + 180) % 360 + Del +
- currentTargetDist;
- expData.Add(row);
- }
- /// <summary>
- /// Listener for TargetReachedEvent, adds row to expData with data about the reached target and player, ends a teleport chain
- /// </summary>
- /// <param name="tre">The Event, contains its information</param>
- private void OnTargetReached(TargetReachedEvent tre) {
- Debug.Log("Received Target information, id: " + tre.targetId + " time: " + tre.time);
- string row = tre.targetId + Del +
- (-1) + Del +
- tre.targetTransform.position.x + Del +
- tre.targetTransform.position.z + Del +
- tre.targetTransform.rotation.eulerAngles.y + Del +
- 0 + Del +
- 0 + Del +
- 0 + Del +
- 0 + Del +
- tre.playerTransform.position.x + Del +
- tre.playerTransform.position.z + Del +
- tre.playerTransform.rotation.eulerAngles.y + Del +
- 0 + Del +
- 0 + Del +
- 0 + Del +
- tre.time + Del +
- 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 +
- (tre.targetTransform.rotation.eulerAngles.y - tre.playerTransform.rotation.eulerAngles.y - 180) % 360 + Del +
- currentTargetDist;
- expData.Add(row);
- currentTeleports = 0;
- }
- /// <summary>
- /// Listener for ExperimentEndEvent, sets userID and invokes WriteToFile() to write the .csv file.
- /// Invokes with one second delay to give the last Events time to finish processing
- /// </summary>
- /// <param name="e">The Event, contains its information, however none is required at the moment</param>
- private void OnExperimentEnd(ExperimentEndEvent e) {
- if (gManager.testSubjectId != "") {
- userId = gManager.testSubjectId;
- }
- // Waiting for last TargetReachedEvent to process
- Invoke("WriteToFile", 1);
- }
- /// <summary>
- /// Creates a new .csv file with userID, movement method and date as name.
- /// Writes first row with names of the columns, afterwards each string in expData as new row
- /// </summary>
- private void WriteToFile() {
- string filepath = string.Format(@"{0}-{1}-{2:yyyy-MM-dd_HH-mm-ss}.csv", GetComponentInParent<GameManager>().movementMethod, userId, DateTime.Now);
- using (StreamWriter writer = new StreamWriter(new FileStream(filepath, FileMode.Create, FileAccess.Write))) {
- writer.WriteLine("TargetID, TeleportID, TargetPositionX, TargetPositionZ, TargetRotation, PlayerLastPosX, PlayerLastPosZ, PlayerLastRot, TelStartTime, PlayerPosX, PlayerPosZ, PlayerRotation, TelEndTime, TelDistance, TelTime, TimeNeeded, OffsetPos, OffsetRot, DistTargetToTarget");
- foreach (string row in expData) {
- writer.WriteLine(row);
- }
- }
- Debug.Log("Data written");
- }
- }
|