//Coroutine to spawn the galaxy, coroutine needed otherwise performance is awful. IEnumerator CreateGalaxyCoroutine() { for (int k = 0; k < numberOfTimesToGenerate; k++) { //Resetting loading bars positionLoading = 0.0f; collisionLoading = 0.0f; resourceLoading = 0.0f; connectLoading = 0.0f; totalLoading = 0.0f; numberOfSystemsGenerated = 0; startTime = Time.time; //If random generation if (randomGeneration == true) { systemDensity = Random.Range(0.10f, 0.12f); systemCenterRadius = Random.Range(0.0f, 25.0f); systemRingCount = Random.Range(4, 7); systemRingWidth = Random.Range(3.5f, 4.5f); } //Calculating other variables using randomly generated or selected values systemRadius = systemRingCount * ringIntervalMultiplier; generationCost = systemRingCount * systemRingWidth * systemDensity; //Generation cost warnings if (generationCost > 6.0f) { Debug.LogWarning("High generation cost"); } else if (generationCost > 4.0f) { Debug.LogWarning("Medium generation cost"); } else { Debug.Log("Low generation cost"); } //Array assignments densities[k] = systemDensity; centerRadii[k] = systemCenterRadius; ringCounts[k] = systemRingCount; ringWidths[k] = systemRingWidth; collisionDistances[k] = systemCollisionDistance; radii[k] = systemRadius; ringIntervals[k] = ringIntervalMultiplier; generationCosts[k] = generationCost; //For each system ring for (int i = 0; i < systemRingCount; i++) { //Calculate segment size and ring radius float segmentSize = (systemRadius - systemCenterRadius) / systemRingCount; float ringRadius = segmentSize * (i + 1); //Calculate ring radius min/max float minRingRadius = ringRadius - systemRingWidth; float maxRingRadius = ringRadius + systemRingWidth; //Calculate ring area float upperArea = maxRingRadius * maxRingRadius * Mathf.PI; float lowerArea = minRingRadius * minRingRadius * Mathf.PI; float ringArea = upperArea - lowerArea; //Calculate number of systems for each ring using formula: mass (number of systems) = density * volume (area). int numberOfSystemsForRing = Mathf.FloorToInt(systemDensity * ringArea); //Instantiate ring object for ring image, give gameobject ring name GameObject galaxyRing = Instantiate(ringPrefab, new Vector2(0, 0), Quaternion.identity, transform); galaxyRing.name = "GalaxyRing " + (i + 1); for (int j = 0; j < numberOfSystemsForRing; j++) { //Spawn systems randomly float angle = Random.Range(0.0f, 1.0f) * Mathf.PI * 2f; Vector2 newPos = new Vector2(Mathf.Cos(angle) * (ringRadius + systemCenterRadius) + Random.Range(-systemRingCount, systemRingWidth), Mathf.Sin(angle) * (ringRadius + systemCenterRadius) + Random.Range(-systemRingWidth, systemRingWidth)); //Calculate position GameObject node = Instantiate(systemPrefab, newPos, Quaternion.identity, transform.GetChild(i)); node.GetComponent <GalaxyNode>().currentRing = i + 1; if (j % coroutineGenerateYieldIntervals == 0) { yield return(null); } } //Loading calculation positionLoading = Mathf.Clamp01((float)i / (float)systemRingCount); } positionLoading = 1.0f; //Get all current systems within scene systems = GetAllGalaxySystems(); if (systemCollisions == true) { //Remove colliding systems (check if they are valid) for (int i = 0; i < systems.Length; i++) { //Get all systems within range of systems[i] GameObject[] systemsToDestroy = CheckRangeOfSystems(systems[i], systems, systemCollisionDistance, true); //Destroy those systems for (int j = 0; j < systemsToDestroy.Length; j++) { DestroyImmediate(systemsToDestroy[j]); } //Coroutine yield interval if (i % coroutineCollisionYieldIntervals == 0) { yield return(null); } //Loading calculation collisionLoading = Mathf.Clamp01((float)i / (float)systems.Length); } //Get all current systems within scene after some have been removed systems = GetAllGalaxySystems(); } collisionLoading = 1.0f; //Calculate number of systems numberOfSystemsGenerated = systems.Length; numberOfSystems[k] = numberOfSystemsGenerated; //If resources are enabled if (systemResources == true) { //For every resource in galaxy gen data for (int i = 0; i < systemResourcesData.Length; i++) { //Generating resource data systemResourcesData[i].currentNodeCount = Mathf.FloorToInt(systemResourcesData[i].resourcePercentage / 100 * systems.Length); GenerateResourceNodes(systemResourcesData[i], i); } } resourceLoading = 1.0f; //For every system SaveData.current.galaxyNodes = new List <GalaxyNode>(); for (int i = 0; i < systems.Length; i++) { if (systems[i] != null) { //Get node GalaxyNode node = systems[i].GetComponent <GalaxyNode>(); if (systemConnections) { //Generate connecting nodes for every node, used in AI pathfinding GameObject[] systemsToConnect = CheckRangeOfSystems(systems[i], systems, systemConnectRange, false); //Connect these nodes for (int j = 0; j < systemsToConnect.Length; j++) { //Add to connecting node list GalaxyNode currentConnectNode = systemsToConnect[j].GetComponent <GalaxyNode>(); node.AddConnectingNode(currentConnectNode); //Coroutine yield interval if (i % coroutineCollisionYieldIntervals == 0) { yield return(null); } } //Loading calculation connectLoading = Mathf.Clamp01((float)i / (float)systems.Length); } //Node setup node.name = "Node " + i; node.nodeID = i; node.CreateNodeUI(nodeUIPrefab, nodeResourceInfoUI); node.UpdateGalaxyNodeData(node.currentRing, node.nodeID, node.features, node.ships); //coroutine yield check if (i % coroutineResourceYieldIntervals == 0) { yield return(null); } SaveData.current.galaxyNodes.Add(node); } } connectLoading = 1.0f; //If factions are enabled. if (systemFactions == true) { //Create faction starting systems. factions = Factions.CreateFactions(numberOfFactions, systems); SaveData.current.factions = factions; float x = factions[0].homeSystem.transform.position.x; float y = factions[0].homeSystem.transform.position.y; playerCamera.GetComponent <CameraMovement>().InitializeCameraSettings(new Vector3(x, y, -10), systemRadius, 15.0f, systemRadius); } //Calculate time taken timings[k] = Time.time - startTime; if (debugMode == true) { RunDebugging(k); currentGeneration++; } } }
//Coroutine to load the galaxy map IEnumerator LoadGalaxyCoroutine(List <GalaxyNode> nodeData) { //Reset loading bars positionLoading = 0.0f; collisionLoading = 0.0f; resourceLoading = 0.0f; connectLoading = 0.0f; totalLoading = 0.0f; yield return(new WaitForSeconds(0.1f)); //Calculate number of rings int numberOfRings = 0; for (int i = 0; i < nodeData.Count; i++) { numberOfRings = nodeData[i].currentRing; } //Instantiate those rings for (int i = 0; i < numberOfRings; i++) { GameObject ring = Instantiate(ringPrefab, new Vector3(0, 0), Quaternion.identity, transform); ring.name = "GalaxyRing " + (i + 1); } //For every node to be created for (int i = 0; i < nodeData.Count; i++) { //Instantiate to a position int currentIteration = i; GameObject node = Instantiate(systemPrefab, nodeData[i].position, Quaternion.identity, transform.GetChild(nodeData[i].currentRing - 1)); node.name = "Node " + currentIteration; GalaxyNode galaxyNode = node.GetComponent <GalaxyNode>(); galaxyNode.UpdateGalaxyNodeData(nodeData[i].currentRing, nodeData[i].nodeID, nodeData[i].features, nodeData[i].ships); if (i % coroutineGenerateYieldIntervals == 0) { yield return(null); } positionLoading = Mathf.Clamp01((float)i / (float)systemRingCount); } positionLoading = 1.0f; collisionLoading = 1.0f; //Array creation GameObject[] nodeObjects = GetAllGalaxySystems(); for (int i = 0; i < nodeObjects.Length; i++) { GalaxyNode galaxyNode = nodeObjects[i].GetComponent <GalaxyNode>(); galaxyNode.resources = nodeData[i].resources; resourceLoading = Mathf.Clamp01((float)i / (float)nodeObjects.Length); } resourceLoading = 1.0f; for (int i = 0; i < nodeObjects.Length; i++) { if (nodeObjects[i] != null) { //Get node GalaxyNode node = nodeObjects[i].GetComponent <GalaxyNode>(); if (systemConnections) { //Generate connecting nodes for every node, used in AI pathfinding GameObject[] systemsToConnect = CheckRangeOfSystems(nodeObjects[i], nodeObjects, systemConnectRange, false); //Connect these nodes for (int j = 0; j < systemsToConnect.Length; j++) { //Add to connecting node list GalaxyNode currentConnectNode = systemsToConnect[j].GetComponent <GalaxyNode>();; node.AddConnectingNode(currentConnectNode); //Coroutine yield interval if (i % coroutineCollisionYieldIntervals == 0) { yield return(null); } } //Loading calculation connectLoading = Mathf.Clamp01((float)i / (float)nodeObjects.Length); } node.CreateNodeUI(nodeUIPrefab, nodeResourceInfoUI); //coroutine yield check if (i % coroutineResourceYieldIntervals == 0) { yield return(null); } } } connectLoading = 1.0f; factions = Factions.LoadFactions(SaveData.current.factions); }