You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

279 lines
9.6 KiB

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. //public class MapManager : MonoBehaviour
  5. [CreateAssetMenu(menuName = "Major Project/Map Manager")]
  6. public class MapManager : ScriptableObject
  7. {
  8. public GameObject spawn4; //The section to use as a spawn-point for games with 2-5 players
  9. public GameObject spawn8; //The section to use a spawn-point for games with 5-8 players
  10. //In 5-player games, we choose between them at random
  11. public List<MapSection> sections; //The list of sections to choose from after starting
  12. public int minConns = 2; //The minimum number of valid connections between two map sections for them to be allowed to link up
  13. public float xForward = 28.0f; //How far ahead of the camera's current position do we want to extend the track?
  14. public float xBack = -4.0f; //And how far behind the camera's position does a section need to fall before being deleted?
  15. public List<MapSection> activeSections; //The list of sections that have been placed on the map (and not removed)
  16. MapSection lastSection; //Which map-section was most recently added?
  17. float startX = -16.0f; //The x-position of the current start of the track
  18. float endX = -16.0f; //The x-position of the current end of the track
  19. // Start is called before the first frame update
  20. void Start()
  21. {
  22. }
  23. public void init(int players)
  24. {
  25. activeSections = new List<MapSection>();
  26. if (players < 5)
  27. {
  28. addSection(spawn4.GetComponent<MapSection>());
  29. }
  30. else if (players > 5)
  31. {
  32. addSection(spawn8.GetComponent<MapSection>());
  33. }
  34. else
  35. {
  36. if (Random.Range(0.0f, 1.0f) < 0.5f)
  37. {
  38. addSection(spawn4.GetComponent<MapSection>());
  39. }
  40. else
  41. {
  42. addSection(spawn8.GetComponent<MapSection>());
  43. }
  44. }
  45. switch (players)
  46. {
  47. case 2:
  48. foreach (GameObject spawnBlock in lastSection.spawns2)
  49. {
  50. spawnBlock.GetComponent<Block>().isSpawnable = true;
  51. }
  52. break;
  53. case 3:
  54. foreach (GameObject spawnBlock in lastSection.spawns3)
  55. {
  56. spawnBlock.GetComponent<Block>().isSpawnable = true;
  57. }
  58. break;
  59. case 4:
  60. foreach (GameObject spawnBlock in lastSection.spawns4)
  61. {
  62. spawnBlock.GetComponent<Block>().isSpawnable = true;
  63. }
  64. break;
  65. case 5:
  66. foreach (GameObject spawnBlock in lastSection.spawns5)
  67. {
  68. spawnBlock.GetComponent<Block>().isSpawnable = true;
  69. }
  70. break;
  71. case 6:
  72. foreach (GameObject spawnBlock in lastSection.spawns6)
  73. {
  74. spawnBlock.GetComponent<Block>().isSpawnable = true;
  75. }
  76. break;
  77. case 7:
  78. foreach (GameObject spawnBlock in lastSection.spawns7)
  79. {
  80. spawnBlock.GetComponent<Block>().isSpawnable = true;
  81. }
  82. break;
  83. case 8:
  84. foreach (GameObject spawnBlock in lastSection.spawns8)
  85. {
  86. spawnBlock.GetComponent<Block>().isSpawnable = true;
  87. }
  88. break;
  89. default:
  90. foreach (GameObject spawnBlock in lastSection.spawns1)
  91. {
  92. spawnBlock.GetComponent<Block>().isSpawnable = true;
  93. }
  94. break;
  95. }
  96. checkForward();
  97. }
  98. void chooseNextSection()
  99. {
  100. //First, we determine which sections are valid
  101. List<MapSection> validSections = new List<MapSection>();
  102. foreach (MapSection section in sections)
  103. {
  104. if (checkSegments(section))
  105. {
  106. validSections.Add(section); //If a segment is a valid continuation of the current most-recent segment, add it to the list
  107. }
  108. }
  109. //Having generated our list, we choose a random segment from it
  110. /*foreach (MapSection section in validSections)
  111. {
  112. Debug.Log("Valid section: " + section.name);
  113. }*/
  114. Debug.Log("Choosing section");
  115. MapSection nextSection = validSections[(int)Random.Range(0.0f, (float)validSections.Count)];
  116. Debug.Log("Chosen section: " + nextSection.name);
  117. addSection(nextSection);
  118. }
  119. void addSection(MapSection section)
  120. {
  121. //Instantiate new section at x = endX
  122. Vector3 pos = new Vector3(endX, 0.0f, 0.0f);
  123. GameObject newSection = (GameObject)Instantiate(section.gameObject, pos, Quaternion.identity);
  124. //GameObject.Instantiate(section.gameObject, pos, Quaternion.identity);
  125. MapSection newSectionScript = newSection.GetComponent<MapSection>();
  126. newSectionScript.InitSection(activeSections.Count);
  127. newSection.name = newSectionScript.name;
  128. activeSections.Add(newSectionScript);
  129. lastSection = newSectionScript;
  130. endX += newSectionScript.length;
  131. }
  132. bool checkSegments(MapSection second)
  133. {
  134. return checkSegments(this.lastSection, second);
  135. }
  136. bool checkSegments(MapSection first, MapSection second)
  137. {
  138. int connections = 0;
  139. //Debug.Log("Checking sections: first = " + first.name + ", second = " + second.name);
  140. foreach (GameObject exit in first.exits)
  141. {
  142. foreach (GameObject entry in second.entrances)
  143. {
  144. /*Debug.Log("Checking connections: exit = " + exit.transform.localPosition.z + ", " + exit.transform.localPosition.x
  145. + ", entry = " + entry.transform.localPosition.z + ", " + entry.transform.localPosition.x);*/
  146. if (checkConnection(exit, entry))
  147. {
  148. connections++;
  149. }
  150. }
  151. }
  152. //Debug.Log("Connections = " + connections);
  153. if (connections >= minConns)
  154. {
  155. //Debug.Log("Valid section!");
  156. }
  157. else
  158. {
  159. //Debug.Log("Invalid section!");
  160. }
  161. return (connections >= minConns);
  162. }
  163. bool checkConnection(GameObject exit, GameObject entry)
  164. {
  165. /*Debug.Log("Checking connections: exit = " + exit.transform.localPosition.z + ", " + exit.transform.localPosition.x
  166. + ", entry = " + entry.transform.localPosition.z + ", " + entry.transform.localPosition.x);*/
  167. //If the squares being checked don't line up, the connection is invalid
  168. if (exit.transform.localPosition.z != entry.transform.localPosition.z)
  169. {
  170. //Debug.Log(exit.transform.localPosition.z + " != " + entry.transform.localPosition.z);
  171. return false;
  172. }
  173. //Debug.Log("Exit.is_Walkable = " + exit.GetComponent<Block>().is_Walkable + ", Entry.is_Walkable = " + entry.GetComponent<Block>().is_Walkable);
  174. //Since we currently don't let people jump over walls, if either block is a wall, the connection is invalid
  175. if (!(exit.GetComponent<Block>().is_Walkable) || !(entry.GetComponent<Block>().is_Walkable))
  176. {
  177. //Debug.Log("Invalid connection - not walkable");
  178. return false;
  179. }
  180. //Debug.Log("Exit.isWater = " + exit.GetComponent<Block>().isWater + ", Entry.isWater = " + entry.GetComponent<Block>().isWater);
  181. //If both components are water, moving through this connection is technically possible, but we don't count it as valid
  182. if ((exit.GetComponent<Block>().isWater) && (entry.GetComponent<Block>().isWater))
  183. {
  184. //Debug.Log("Invalid connection - both water");
  185. return false;
  186. }
  187. //Debug.Log("Valid connection!");
  188. //If we've passed all these tests, the connection is valid!
  189. return true;
  190. }
  191. //Check whether it's time to extend the track forward
  192. void checkForward()
  193. {
  194. //We check if the end of the last section of track is in sight
  195. Vector3 trackEnd = new Vector3(endX, 0.0f); //Get the middle of the end of the last track section
  196. //If it is, then we add a new section
  197. if (checkView(trackEnd))
  198. {
  199. chooseNextSection();
  200. checkForward();
  201. }
  202. }
  203. //Check whether it's time to delete the oldest section of active track
  204. void checkBack()
  205. {
  206. //We check if the end of the first section of track is still in sight
  207. Vector3 firstSectionEnd = new Vector3(startX + activeSections[0].length, 0.0f); //Get the middle of the end of the first track section
  208. //If it's not, then we remove it
  209. if (!(checkView(firstSectionEnd)))
  210. {
  211. startX += activeSections[0].length;
  212. activeSections[0].destroySection();
  213. activeSections.RemoveAt(0);
  214. }
  215. }
  216. //Check whether a point is in sight or not
  217. bool checkView(Vector3 point)
  218. {
  219. Vector3 screenPoint = Camera.main.WorldToViewportPoint(point); //Map it into viewport space
  220. //The camera's field of view is represented by 0 > (x, y) < 1, with z being the distance from the camera
  221. return (screenPoint.z > 0 && screenPoint.x > 0 && screenPoint.x < 1 && screenPoint.y > 0 && screenPoint.y < 1);
  222. }
  223. //Checks in both directions for sections needing to be added or removed
  224. public void checkTrack()
  225. {
  226. checkForward();
  227. checkBack();
  228. }
  229. // Update is called once per frame
  230. void Update()
  231. {
  232. //checkTrack();
  233. }
  234. }