public Wave Generate(int waveID) { if (pathList.Count == 0) { Debug.Log("no path at all"); return(null); } Wave wave = new Wave(); wave.waveID = waveID; waveID += 1; int _subWaveCount = Mathf.Max(1, (int)subWaveCount.GetValueAtWave(waveID)); int totalUnitCount = (int)unitCount.GetValueAtWave(waveID); _subWaveCount = Mathf.Min(totalUnitCount, _subWaveCount); //filter thru all the units, only use the one that meets the wave requirement (>minWave) List <ProceduralUnitSetting> availableUnitList = new List <ProceduralUnitSetting>(); int nearestAvailableID = 0; float currentNearestValue = Mathf.Infinity; for (int i = 0; i < unitSettingList.Count; i++) { if (!unitSettingList[i].enabled) { continue; } if (unitSettingList[i].minWave <= waveID) { availableUnitList.Add(unitSettingList[i]); } //while we are at it, check which unit has the lowest wave requirement, just in case if (availableUnitList.Count == 0 && unitSettingList[i].minWave < currentNearestValue) { currentNearestValue = unitSettingList[i].minWave; nearestAvailableID = i; } } //if no unit available, simply uses the one with lowest requirement if (availableUnitList.Count == 0) { availableUnitList.Add(unitSettingList[nearestAvailableID]); } //we are going to just iterate thru the pathlist and assign them to each subwave. //So here we introduce an offset so it doesnt always start from the first path in the list int startingPathID = Random.Range(0, pathList.Count); for (int i = 0; i < _subWaveCount; i++) { SubWave subWave = new SubWave(); int unitID = Random.Range(0, availableUnitList.Count); ProceduralUnitSetting unitSetting = availableUnitList[unitID]; subWave.unit = unitSetting.unit.gameObject; subWave.overrideHP = unitSetting.HP.GetValueAtWave(waveID); subWave.overrideShield = unitSetting.shield.GetValueAtWave(waveID); subWave.overrideMoveSpd = unitSetting.speed.GetValueAtWave(waveID); //limit the minimum interval to 0.25f subWave.interval = Mathf.Max(0.25f, unitSetting.interval.GetValueAtWave(waveID)); //iterate through the path, randomly skip one int pathID = startingPathID + (Random.Range(0f, 1f) > 0.75f ? 1 : 0); while (pathID >= pathList.Count) { pathID -= pathList.Count; } subWave.path = pathList[pathID]; subWave.delay = i * Random.Range(2f, 3f); wave.subWaveList.Add(subWave); } //fill up the unit count int remainingUnitCount = totalUnitCount; while (remainingUnitCount > 0) { for (int i = 0; i < _subWaveCount; i++) { if (wave.subWaveList[i].count == 0) { wave.subWaveList[i].count = 1; remainingUnitCount -= 1; } else { int rand = Random.Range(0, 3); rand = Mathf.Min(rand, remainingUnitCount); wave.subWaveList[i].count += rand; remainingUnitCount -= rand; } } } wave.duration = wave.CalculateSpawnDuration(); //get the slowest moving unit and the longest path so we know which subwave is going to take the longest to finish float longestDuration = 0; for (int i = 0; i < _subWaveCount; i++) { float pathDist = wave.subWaveList[i].path.GetPathDistance(); float moveSpeed = wave.subWaveList[i].overrideMoveSpd; float duration = pathDist / moveSpeed; if (duration > longestDuration) { longestDuration = duration; } } //add the longest to the existing duration wave.duration += longestDuration * Random.Range(0.5f, 0.8f); for (int i = 0; i < rscSettingList.Count; i++) { wave.rscGainList.Add((int)rscSettingList[i].GetValueAtWave(waveID)); } return(wave); }
Vector2 WaveConfigurator(float startX, float startY) { for (int i = 0; i < instance.waveList.Count; i++) { Wave wave = instance.waveList[i]; float foldOffset = 25; if (deleteID == i) { if (GUI.Button(new Rect(startX, startY - 3, 60, 20), "Cancel")) { deleteID = -1; } GUI.color = Color.red; if (GUI.Button(new Rect(startX + 65, startY - 3, 20, 20), "X")) { instance.waveList.RemoveAt(i); i -= 1; deleteID = -1; } GUI.color = Color.white; foldOffset += 65; } else { cont = new GUIContent("X", "Delete wave"); if (GUI.Button(new Rect(startX, startY - 3, 20, 20), cont)) { deleteID = i; } } waveFoldList[i] = EditorGUI.Foldout(new Rect(startX + foldOffset, startY, 60, 15), waveFoldList[i], "wave " + (i + 1).ToString()); if (!waveFoldList[i]) { PreviewSubWave(wave, startX + foldOffset, startY, spaceX, width, spaceY, height); startY += 35; continue; } startX += 20; cont = new GUIContent("SubWave Size: " + wave.subWaveList.Count, "Number of subwave in this wave, each subwave can be made of different creep with different spawn configuration"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, 15), cont); if (GUI.Button(new Rect(startX + spaceX + 10, startY - 1, 40, 15), "-1")) { if (wave.subWaveList.Count > 1) { wave.subWaveList.RemoveAt(wave.subWaveList.Count - 1); } } if (GUI.Button(new Rect(startX + spaceX + 60, startY - 1, 40, 15), "+1")) { wave.subWaveList.Add(wave.subWaveList[wave.subWaveList.Count - 1].Clone()); } if (instance.spawnMode == SpawnManager._SpawnMode.Continous) { cont = new GUIContent("Duration: ", "Time until next wave"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); wave.duration = EditorGUI.FloatField(new Rect(startX + spaceX - 20, startY, 40, 15), wave.duration); float reqDuration = wave.CalculateSpawnDuration(); EditorGUI.LabelField(new Rect(startX + spaceX + 30, startY, 800, height), "(Time required for all units in this wave to be spawned: " + reqDuration.ToString("f1") + "s)"); } float cachedX = startX; startY += 3; Vector2 v2 = SubWaveConfigurator(wave, startX, startY, spaceX, width, spaceY, height); startY = v2.y + 5; startX = cachedX; cont = new GUIContent("Life Gain: ", "The amount of life player will gain when surviving the wave"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); wave.lifeGain = EditorGUI.IntField(new Rect(startX + spaceX - 20, startY, 40, 15), wave.lifeGain); //~ startX+=spaceX+75; cont = new GUIContent("Energy Gain: ", "The amount of energy (for abilities) player will gain when surviving the wave"); EditorGUI.LabelField(new Rect(startX, startY += spaceY - 2, width, height), cont); wave.energyGain = EditorGUI.IntField(new Rect(startX + spaceX - 20, startY, 40, 15), wave.energyGain); //~ startX=cachedX; startY+=3; cont = new GUIContent("Resource Gain:", "The amount of resource player will gain when surviving the wave"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, 300, 15), cont); if (wave.rscGainList.Count < rscList.Count) { wave.rscGainList.Add(0); } if (wave.rscGainList.Count > rscList.Count) { wave.rscGainList.RemoveAt(wave.rscGainList.Count - 1); } cachedX = startX; startX += spaceX; for (int n = 0; n < rscList.Count; n++) { EditorUtilities.DrawSprite(new Rect(startX, startY - 2, 20, 20), rscList[n].icon); wave.rscGainList[n] = EditorGUI.IntField(new Rect(startX + 21, startY, 40, height - 2), wave.rscGainList[n]); startX += 75; } startX = cachedX; startY += 50; startX -= 20; } return(new Vector2(startX, startY)); }