using Assets.StreetLight.Scripts; using System; using System.Collections.Concurrent; using System.Globalization; using System.IO; using System.Linq; using System.Threading.Tasks; using UnityEngine; namespace Assets { public class CalibrationRecorderBehavior : MonoBehaviour { PersonManager PersonManager => personManagerLazy.Value; Lazy personManagerLazy; string calibrationFileName; private void Awake() { personManagerLazy = new Lazy(FindObjectOfType); } BlockingCollection taskQueue; GameObject marker; void Start() { taskQueue = new BlockingCollection(); calibrationFileName = Path.Combine(@".\CalibrationRecordings", $"CalibrationRecording{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.csv"); InitializeCalibrationFile(); enabled = false; PersonManager.DetectionReady += PersonManager_DetectionReady; marker = GameObject.Find("CalibrationMarker"); var markerBehavior = FindObjectOfType(); markerBehavior.PathFinished += MarkerBehavior_PathFinished; } private void InitializeCalibrationFile() { var directoryPath = Path.GetDirectoryName(calibrationFileName); if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } if (!File.Exists(calibrationFileName)) { File.WriteAllText(calibrationFileName, string.Empty); } } private void AppendNewCalibrationPoint(float worldX, float worldY, float unityX, float unityY) { var valuesToWrite = new float[] { worldX, worldY, unityX, unityY }.Select(f => f.ToString("0." + new string('#', 50), CultureInfo.InvariantCulture)); var line = string.Join(" ", valuesToWrite); taskQueue.Add(() => File.AppendAllLines(calibrationFileName, new string[] { line })); Task.Run(() => taskQueue.Take().Invoke()); } private void MarkerBehavior_PathFinished(object sender, EventArgs e) { enabled = false; taskQueue.Add(() => Application.Quit()); Task.Run(() => taskQueue.Take().Invoke()); } private void PersonManager_DetectionReady(object sender, EventArgs e) { enabled = true; } void Update() { if (PersonManager.Persons.Count == 1) { var person = PersonManager.Persons.Single(); var personPosition = person.WorldPosition; var markerPosition = marker.transform.position; AppendNewCalibrationPoint(personPosition.x, personPosition.z, markerPosition.x, markerPosition.z); } } } }