SpatialTimeSimulation.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. using UnityEngine.AI;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System;
  7. [DefaultExecutionOrder(61)]
  8. [RequireComponent(typeof(InstantiatePrefab), typeof(WriteInCSV), typeof(ReadFromCSV))]
  9. public class SpatialTimeSimulation : MonoBehaviour
  10. {
  11. // Waypoints and Rotations
  12. public Tuple<List<float>, List<Vector3>, List<Quaternion>, List<float>>[][] timePosRotList;
  13. // Private Journey Settings
  14. private int currentStartPoint;
  15. private float startTime;
  16. // Global GameObjects
  17. private GameObject[][] humansGO;
  18. private NavMeshAgent[][] humansNMA;
  19. private Animator[][] humansA;
  20. // Playback variables
  21. private int[] maxIJ;
  22. private int indexChangeRate;
  23. [HideInInspector]
  24. public bool rewind, pause, play; //PlaybackController
  25. // Slider Settings
  26. public Slider slider;
  27. private float prevSliderValue;
  28. // Thief Settings
  29. //private Vector3 stealHere;
  30. // Spatial time visualization
  31. private List<Vector3>[][] positions;
  32. public float thickness = 0.1f;
  33. public Material material;
  34. public Color color;
  35. private void Start()
  36. {
  37. // Get information from InstatiatePrefab
  38. humansGO = gameObject.GetComponent<InstantiatePrefab>().humanGameObject;
  39. humansA = gameObject.GetComponent<InstantiatePrefab>().humanAnimator;
  40. humansNMA = gameObject.GetComponent<InstantiatePrefab>().humanNavMeshAgent;
  41. positions = new List<Vector3>[humansGO.Length][];
  42. //stealHere = gameObject.GetComponent<ControllingThief>().stealHere;
  43. // Read from CSV file and save time, position, rotation in matrix
  44. int index = gameObject.GetComponent<WriteInCSV>().index;
  45. string dir = Directory.GetCurrentDirectory();
  46. string reference = @"\Assets\Data_position\Walk" + index + ".csv";
  47. timePosRotList = gameObject.GetComponent<ReadFromCSV>().ReadFromCSVFile(dir + reference);
  48. // Add 0.5f + time to y
  49. // Disable components and add LineRenderer
  50. currentStartPoint = 0;
  51. for (int i = 0; i < humansGO.Length; ++i)
  52. {
  53. positions[i] = new List<Vector3>[humansGO[i].Length];
  54. for (int j = 0; j < humansGO[i].Length; ++j)
  55. {
  56. // A shortcut to use the position data immediately for the LineRenderer
  57. positions[i][j] = new List<Vector3>();
  58. foreach (var position in timePosRotList[i][j].Item2)
  59. {
  60. positions[i][j].Add(new Vector3(position.x, 0.5f + timePosRotList[i][j].Item1[currentStartPoint], position.z));
  61. currentStartPoint++;
  62. }
  63. currentStartPoint = 0;
  64. // Every component should be disabled except the humans game object, bc the LineRenderer operates there
  65. humansGO[i][j].SetActive(true);
  66. humansA[i][j].enabled = false;
  67. humansNMA[i][j].enabled = false;
  68. foreach(Transform child in humansGO[i][j].transform)
  69. {
  70. child.gameObject.SetActive(false);
  71. }
  72. // Add the LineRenderer to the gameobject
  73. LineRenderer drawPath = humansGO[i][j].AddComponent<LineRenderer>();
  74. //drawPath.material = new Material(Shader.Find("Sprites/Default"));
  75. //drawPath.material = new Material(Shader.Find("Particles/Standard Unlit"));
  76. //drawPath.material = new Material(Shader.Find("VolumetricLine/LineStrip-TextureAlphaBlended"));
  77. drawPath.material = material;
  78. drawPath.startColor = color;
  79. drawPath.endColor = color;
  80. drawPath.startWidth = thickness;
  81. drawPath.endWidth = thickness;
  82. drawPath.numCapVertices = 90;
  83. drawPath.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
  84. drawPath.receiveShadows = false;
  85. drawPath.positionCount = currentStartPoint + 1;
  86. drawPath.SetPosition(currentStartPoint, positions[i][j][currentStartPoint]);
  87. }
  88. }
  89. // Set the Slider settings
  90. if (slider == null)
  91. {
  92. Debug.Log("No Slider instance attached");
  93. return;
  94. }
  95. maxIJ = GetHumanWithLongestScreenTime();
  96. float maxTime = (float)Math.Round(timePosRotList[maxIJ[0]][maxIJ[1]].Item1[timePosRotList[maxIJ[0]][maxIJ[1]].Item1.Count - 1], 2);
  97. slider.minValue = 0;
  98. slider.maxValue = (maxTime / Time.deltaTime);
  99. slider.wholeNumbers = true;
  100. prevSliderValue = slider.value;
  101. currentStartPoint++;
  102. slider.value = currentStartPoint;
  103. startTime = Time.time;
  104. }
  105. private void FixedUpdate()
  106. {
  107. if (pause)
  108. indexChangeRate = 0;
  109. if (play)
  110. indexChangeRate = 1;
  111. if (rewind)
  112. indexChangeRate = -1;
  113. if (play || rewind)
  114. {
  115. if ((currentStartPoint + indexChangeRate) < timePosRotList[maxIJ[0]][maxIJ[1]].Item2.Count && (currentStartPoint + indexChangeRate) >= 0)
  116. {
  117. if (slider.value - prevSliderValue == -1 || slider.value - prevSliderValue == 0 || slider.value - prevSliderValue == 1) // rewind || play
  118. {
  119. prevSliderValue = slider.value;
  120. currentStartPoint += indexChangeRate;
  121. slider.value = currentStartPoint;
  122. }
  123. else
  124. {
  125. prevSliderValue = slider.value;
  126. currentStartPoint = (int)slider.value;
  127. }
  128. SetTransform(currentStartPoint);
  129. }
  130. else if (slider.value - prevSliderValue != -1 || slider.value - prevSliderValue != 0 || slider.value - prevSliderValue != 1)
  131. {
  132. currentStartPoint = (int)slider.value;
  133. }
  134. }
  135. else
  136. {
  137. currentStartPoint = (int)slider.value;
  138. SetTransform(currentStartPoint);
  139. }
  140. }
  141. private void SetTransform(int currentStartPoint)
  142. {
  143. for (int i = 0; i < humansGO.Length; ++i)
  144. {
  145. for (int j = 0; j < humansGO[i].Length; ++j)
  146. {
  147. LineRenderer drawPath = humansGO[i][j].GetComponent<LineRenderer>();
  148. // if so ArgumentOutOfRangeException
  149. if ((currentStartPoint + indexChangeRate) >= (timePosRotList[i][j].Item2.Count - 1) || (currentStartPoint + indexChangeRate) < 0)
  150. {
  151. if((currentStartPoint + indexChangeRate) >= (timePosRotList[i][j].Item2.Count - 1))
  152. {
  153. drawPath.positionCount = positions[i][j].Count;
  154. drawPath.SetPositions(positions[i][j].ToArray());
  155. }
  156. continue;
  157. }
  158. if (currentStartPoint < timePosRotList[i][j].Item2.Count)
  159. {
  160. // We need to specify the Length of the positionCount variable
  161. drawPath.positionCount = currentStartPoint + 1;
  162. // We copy the positions list and remove every element after the currentStartPoint from the copy
  163. List<Vector3> tmpLst = new List<Vector3>(positions[i][j]);
  164. tmpLst.RemoveRange(currentStartPoint + 1, positions[i][j].Count - currentStartPoint - 1);
  165. drawPath.SetPositions(tmpLst.ToArray());
  166. }
  167. }
  168. }
  169. }
  170. private int[] GetHumanWithLongestScreenTime()
  171. {
  172. int[] maxIJ = new int[2] { 0, 0 };
  173. float currentMaxTime = 0;
  174. for (int i = 0; i < humansGO.Length; ++i)
  175. {
  176. for (int j = 0; j < humansGO[i].Length; ++j)
  177. {
  178. if (currentMaxTime < timePosRotList[i][j].Item1.Count)
  179. {
  180. currentMaxTime = timePosRotList[i][j].Item1.Count;
  181. maxIJ[0] = i;
  182. maxIJ[1] = j;
  183. }
  184. }
  185. }
  186. return maxIJ;
  187. }
  188. }