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.

227 lines
7.8 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. checkForward();
  46. }
  47. void chooseNextSection()
  48. {
  49. //First, we determine which sections are valid
  50. List<MapSection> validSections = new List<MapSection>();
  51. foreach (MapSection section in sections)
  52. {
  53. if (checkSegments(section))
  54. {
  55. validSections.Add(section); //If a segment is a valid continuation of the current most-recent segment, add it to the list
  56. }
  57. }
  58. //Having generated our list, we choose a random segment from it
  59. /*foreach (MapSection section in validSections)
  60. {
  61. Debug.Log("Valid section: " + section.name);
  62. }*/
  63. Debug.Log("Choosing section");
  64. MapSection nextSection = validSections[(int)Random.Range(0.0f, (float)validSections.Count)];
  65. Debug.Log("Chosen section: " + nextSection.name);
  66. addSection(nextSection);
  67. }
  68. void addSection(MapSection section)
  69. {
  70. //Instantiate new section at x = endX
  71. Vector3 pos = new Vector3(endX, 0.0f, 0.0f);
  72. GameObject newSection = (GameObject)Instantiate(section.gameObject, pos, Quaternion.identity);
  73. //GameObject.Instantiate(section.gameObject, pos, Quaternion.identity);
  74. MapSection newSectionScript = newSection.GetComponent<MapSection>();
  75. newSectionScript.InitSection(activeSections.Count);
  76. newSection.name = newSectionScript.name;
  77. activeSections.Add(newSectionScript);
  78. lastSection = newSectionScript;
  79. endX += newSectionScript.length;
  80. }
  81. bool checkSegments(MapSection second)
  82. {
  83. return checkSegments(this.lastSection, second);
  84. }
  85. bool checkSegments(MapSection first, MapSection second)
  86. {
  87. int connections = 0;
  88. //Debug.Log("Checking sections: first = " + first.name + ", second = " + second.name);
  89. foreach (GameObject exit in first.exits)
  90. {
  91. foreach (GameObject entry in second.entrances)
  92. {
  93. /*Debug.Log("Checking connections: exit = " + exit.transform.localPosition.z + ", " + exit.transform.localPosition.x
  94. + ", entry = " + entry.transform.localPosition.z + ", " + entry.transform.localPosition.x);*/
  95. if (checkConnection(exit, entry))
  96. {
  97. connections++;
  98. }
  99. }
  100. }
  101. //Debug.Log("Connections = " + connections);
  102. if (connections >= minConns)
  103. {
  104. //Debug.Log("Valid section!");
  105. }
  106. else
  107. {
  108. //Debug.Log("Invalid section!");
  109. }
  110. return (connections >= minConns);
  111. }
  112. bool checkConnection(GameObject exit, GameObject entry)
  113. {
  114. /*Debug.Log("Checking connections: exit = " + exit.transform.localPosition.z + ", " + exit.transform.localPosition.x
  115. + ", entry = " + entry.transform.localPosition.z + ", " + entry.transform.localPosition.x);*/
  116. //If the squares being checked don't line up, the connection is invalid
  117. if (exit.transform.localPosition.z != entry.transform.localPosition.z)
  118. {
  119. //Debug.Log(exit.transform.localPosition.z + " != " + entry.transform.localPosition.z);
  120. return false;
  121. }
  122. //Debug.Log("Exit.is_Walkable = " + exit.GetComponent<Block>().is_Walkable + ", Entry.is_Walkable = " + entry.GetComponent<Block>().is_Walkable);
  123. //Since we currently don't let people jump over walls, if either block is a wall, the connection is invalid
  124. if (!(exit.GetComponent<Block>().is_Walkable) || !(entry.GetComponent<Block>().is_Walkable))
  125. {
  126. //Debug.Log("Invalid connection - not walkable");
  127. return false;
  128. }
  129. //Debug.Log("Exit.isWater = " + exit.GetComponent<Block>().isWater + ", Entry.isWater = " + entry.GetComponent<Block>().isWater);
  130. //If both components are water, moving through this connection is technically possible, but we don't count it as valid
  131. if ((exit.GetComponent<Block>().isWater) && (entry.GetComponent<Block>().isWater))
  132. {
  133. //Debug.Log("Invalid connection - both water");
  134. return false;
  135. }
  136. //Debug.Log("Valid connection!");
  137. //If we've passed all these tests, the connection is valid!
  138. return true;
  139. }
  140. //Check whether it's time to extend the track forward
  141. void checkForward()
  142. {
  143. //We check if the end of the last section of track is in sight
  144. Vector3 trackEnd = new Vector3(endX, 0.0f); //Get the middle of the end of the last track section
  145. //If it is, then we add a new section
  146. if (checkView(trackEnd))
  147. {
  148. chooseNextSection();
  149. checkForward();
  150. }
  151. }
  152. //Check whether it's time to delete the oldest section of active track
  153. void checkBack()
  154. {
  155. //We check if the end of the first section of track is still in sight
  156. Vector3 firstSectionEnd = new Vector3(startX + activeSections[0].length, 0.0f); //Get the middle of the end of the first track section
  157. //If it's not, then we remove it
  158. if (!(checkView(firstSectionEnd)))
  159. {
  160. startX += activeSections[0].length;
  161. activeSections[0].destroySection();
  162. activeSections.RemoveAt(0);
  163. }
  164. }
  165. //Check whether a point is in sight or not
  166. bool checkView(Vector3 point)
  167. {
  168. Vector3 screenPoint = Camera.main.WorldToViewportPoint(point); //Map it into viewport space
  169. //The camera's field of view is represented by 0 > (x, y) < 1, with z being the distance from the camera
  170. return (screenPoint.z > 0 && screenPoint.x > 0 && screenPoint.x < 1 && screenPoint.y > 0 && screenPoint.y < 1);
  171. }
  172. //Checks in both directions for sections needing to be added or removed
  173. public void checkTrack()
  174. {
  175. checkForward();
  176. checkBack();
  177. }
  178. // Update is called once per frame
  179. void Update()
  180. {
  181. //checkTrack();
  182. }
  183. }