AudiencePath.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class AudiencePath : WalkPath
  5. {
  6. public enum Angle
  7. {
  8. zero,
  9. minus90,
  10. plus90
  11. };
  12. [Tooltip("Type of rotation / Вариант поворота")] [SerializeField] private Angle angle = Angle.plus90;
  13. [Range(-180, 180)]
  14. [Tooltip("Rotation of people / Поворот человека")] [SerializeField] private float peopleRotation;
  15. [Tooltip("Look for target / Слежение за таргетом")] [HideInInspector] [SerializeField] private bool looking;
  16. [Tooltip("Target / Цель")] [HideInInspector] [SerializeField] private Transform target;
  17. [Tooltip("Speed rotation (smooth) / Скорость поворота (смягчение)")] [HideInInspector] [SerializeField] private float damping = 5;
  18. public override void DrawCurved(bool withDraw)
  19. {
  20. if (numberOfWays < 1) numberOfWays = 1;
  21. if (lineSpacing < 0.6f) lineSpacing = 0.6f;
  22. _forward = new bool[numberOfWays];
  23. for (int w = 0; w < numberOfWays; w++)
  24. {
  25. _forward[w] = true;
  26. }
  27. if (pathPoint.Count < 2) return;
  28. points = new Vector3[numberOfWays, pathPoint.Count + 2];
  29. pointLength[0] = pathPoint.Count + 2;
  30. for (int i = 0; i < pathPointTransform.Count; i++)
  31. {
  32. Vector3 vectorStart;
  33. Vector3 vectorEnd;
  34. if (i == 0)
  35. {
  36. if (loopPath)
  37. {
  38. vectorStart = pathPointTransform[pathPointTransform.Count - 1].transform.position - pathPointTransform[i].transform.position;
  39. }
  40. else
  41. {
  42. vectorStart = Vector3.zero;
  43. }
  44. vectorEnd = pathPointTransform[i].transform.position - pathPointTransform[i + 1].transform.position;
  45. }
  46. else if (i == pathPointTransform.Count - 1)
  47. {
  48. vectorStart = pathPointTransform[i - 1].transform.position - pathPointTransform[i].transform.position;
  49. if (loopPath)
  50. {
  51. vectorEnd = pathPointTransform[i].transform.position - pathPointTransform[0].transform.position;
  52. }
  53. else
  54. {
  55. vectorEnd = Vector3.zero;
  56. }
  57. }
  58. else
  59. {
  60. vectorStart = pathPointTransform[i - 1].transform.position - pathPointTransform[i].transform.position;
  61. vectorEnd = pathPointTransform[i].transform.position - pathPointTransform[i + 1].transform.position;
  62. }
  63. //
  64. Vector3 vectorShift = Vector3.Normalize((Quaternion.Euler(0, 90, 0) * (vectorStart + vectorEnd)));
  65. //
  66. points[0, i + 1] = numberOfWays % 2 == 1 ? pathPointTransform[i].transform.position : pathPointTransform[i].transform.position + vectorShift * lineSpacing / 2;
  67. if (numberOfWays > 1) points[1, i + 1] = points[0, i + 1] - vectorShift * lineSpacing;
  68. for (int w = 1; w < numberOfWays; w++)
  69. {
  70. points[w, i + 1] = points[0, i + 1] + vectorShift * lineSpacing * (float)(System.Math.Pow(-1, w)) * ((w + 1) / 2);
  71. }
  72. }
  73. for (int w = 0; w < numberOfWays; w++)
  74. {
  75. points[w, 0] = points[w, 1];
  76. points[w, pointLength[0] - 1] = points[w, pointLength[0] - 2];
  77. }
  78. if (withDraw)
  79. {
  80. for (int w = 0; w < numberOfWays; w++)
  81. {
  82. if (loopPath)
  83. {
  84. Gizmos.color = (_forward[w] ? Color.green : Color.red);
  85. Gizmos.DrawLine(points[w, 0], points[w, pathPoint.Count]);
  86. }
  87. for (int i = 1; i < pathPoint.Count; i++)
  88. {
  89. Gizmos.color = (_forward[w] ? Color.green : Color.red);
  90. Gizmos.DrawLine(points[w, i + 1], points[w, i]);
  91. }
  92. }
  93. }
  94. }
  95. public override void SpawnPeople()
  96. {
  97. List<GameObject> pfb = new List<GameObject>(peoplePrefabs);
  98. for (int i = pfb.Count - 1; i >= 0; i--)
  99. {
  100. if (pfb[i] == null)
  101. {
  102. pfb.RemoveAt(i);
  103. }
  104. }
  105. peoplePrefabs = pfb.ToArray();
  106. if (points == null) DrawCurved(false);
  107. if (par == null)
  108. {
  109. par = new GameObject();
  110. par.transform.parent = gameObject.transform;
  111. par.name = "walkingObjects";
  112. }
  113. int pathPointCount;
  114. if (!loopPath)
  115. {
  116. pathPointCount = pointLength[0] - 2;
  117. }
  118. else
  119. {
  120. pathPointCount = pointLength[0] - 1;
  121. }
  122. if (pathPointCount < 2) return;
  123. var pCount = loopPath ? pointLength[0] - 1 : pointLength[0] - 2;
  124. for (int wayIndex = 0; wayIndex < numberOfWays; wayIndex++)
  125. {
  126. _distances = new float[pCount];
  127. float pathLength = 0f;
  128. for (int i = 1; i < pCount; i++)
  129. {
  130. Vector3 vector;
  131. if (loopPath && i == pCount - 1)
  132. {
  133. vector = points[wayIndex, 1] - points[wayIndex, pCount];
  134. }
  135. else
  136. {
  137. vector = points[wayIndex, i + 1] - points[wayIndex, i];
  138. }
  139. pathLength += vector.magnitude;
  140. _distances[i] = pathLength;
  141. }
  142. int peopleCount = Mathf.FloorToInt((Density * pathLength) / _minimalObjectLength);
  143. float segmentLen = _minimalObjectLength + (pathLength - (peopleCount * _minimalObjectLength)) / peopleCount;
  144. int[] pickList = CommonUtils.GetRandomPrefabIndexes(peopleCount, ref peoplePrefabs);
  145. Vector3[] pointArray = new Vector3[_distances.Length];
  146. for (int i = 1; i < _distances.Length; i++)
  147. {
  148. pointArray[i - 1] = points[wayIndex, i];
  149. }
  150. pointArray[_distances.Length - 1] = loopPath ? points[wayIndex, 1] : points[wayIndex, _distances.Length];
  151. for (int peopleIndex = 0; peopleIndex < peopleCount; peopleIndex++)
  152. {
  153. var people = gameObject;
  154. var randomShift = Random.Range(-segmentLen / 3f, segmentLen / 3f) + (wayIndex * segmentLen);
  155. var finalRandomDistance = (peopleIndex + 1) * segmentLen + randomShift;
  156. Vector3 routePosition = GetRoutePosition(pointArray, finalRandomDistance, pCount, loopPath);
  157. routePosition = new Vector3(routePosition.x, routePosition.y, routePosition.z);
  158. Vector3 or;
  159. RaycastHit hit;
  160. if (Physics.Raycast(new Vector3(routePosition.x, routePosition.y + highToSpawn, routePosition.z), Vector3.down, out hit, Mathf.Infinity))
  161. {
  162. routePosition.y = hit.point.y;
  163. }
  164. else
  165. {
  166. continue;
  167. }
  168. people = Instantiate(peoplePrefabs[pickList[peopleIndex]], routePosition, Quaternion.identity) as GameObject;
  169. people.transform.parent = par.transform;
  170. PeopleController pc = people.AddComponent<PeopleController>();
  171. pc.animNames = new string[4] { "idle1", "idle2", "cheer", "claphands" };
  172. if (looking)
  173. {
  174. pc.target = target;
  175. pc.damping = damping;
  176. }
  177. var movePath = people.AddComponent<MovePath>();
  178. movePath.walkPath = gameObject;
  179. movePath.MyStart(wayIndex, GetRoutePoint((peopleIndex + 1) * segmentLen + randomShift, wayIndex, pCount, true, loopPath), "", loopPath, true, 0, 0);
  180. Vector3 targetPos = new Vector3(movePath.finishPos.x, people.transform.position.y, movePath.finishPos.z);
  181. DestroyImmediate(movePath);
  182. people.transform.LookAt(targetPos);
  183. if (angle == Angle.zero)
  184. {
  185. people.transform.eulerAngles = new Vector3(people.transform.eulerAngles.x, people.transform.eulerAngles.y + peopleRotation, people.transform.eulerAngles.z);
  186. }
  187. else
  188. {
  189. people.transform.eulerAngles = new Vector3(people.transform.eulerAngles.x, people.transform.eulerAngles.y + ((angle == Angle.plus90) ? 90 : -90) + peopleRotation, people.transform.eulerAngles.z);
  190. }
  191. people.transform.position += people.transform.forward * Random.Range(-randZPos, randZPos);
  192. people.transform.position += people.transform.right * Random.Range(-randXPos, randXPos);
  193. if(Physics.Raycast(new Vector3(people.transform.position.x, people.transform.position.y + highToSpawn, people.transform.position.z), Vector3.down, out hit, Mathf.Infinity))
  194. {
  195. people.transform.position = new Vector3(people.transform.position.x, hit.point.y, people.transform.position.z);
  196. }
  197. }
  198. }
  199. }
  200. }