private void UpdateProceduralUnitList() { if (unitCount == creepDB.creepList.Count) { return; } unitCount = creepDB.creepList.Count; List <ProceduralUnitSetting> unitSettingList = instance.waveGenerator.unitSettingList; List <ProceduralUnitSetting> newSettingList = new List <ProceduralUnitSetting>(); for (int i = 0; i < creepDB.creepList.Count; i++) { bool match = false; for (int n = 0; n < unitSettingList.Count; n++) { if (unitSettingList[n].unit == creepDB.creepList[i].gameObject) { newSettingList.Add(unitSettingList[n]); match = true; break; } } if (!match) { ProceduralUnitSetting unitSetting = new ProceduralUnitSetting(); unitSetting.unit = creepDB.creepList[i].gameObject; unitSetting.unitC = creepDB.creepList[i].gameObject.GetComponent <UnitCreep>(); newSettingList.Add(unitSetting); } } instance.waveGenerator.unitSettingList = newSettingList; }
Vector2 DrawProceduralUnitSetting(float startX, float startY, ProceduralUnitSetting unitSetting) { if (unitSetting.enabled) { GUI.Box(new Rect(startX, startY, 185 * 4, 32 + 5 * 17 + 12), ""); } else { GUI.Box(new Rect(startX, startY, 185 * 4, 32 + 10), ""); } startX += 5; startY += 5; Vector2 v2 = default(Vector2); float cachedX = startX; int unitID = -1; for (int n = 0; n < creepList.Count; n++) { if (unitSetting.unit == creepList[n].gameObject) { unitID = n; } } EditorUtilities.DrawSprite(new Rect(startX, startY, 30, 30), creepList[unitID].iconSprite); EditorGUI.LabelField(new Rect(startX + 32, startY += -2, width, height), creepList[unitID].unitName); cont = new GUIContent("enabled: ", "Check to enable unit in the procedural generation otherwise unit will not be considered at all"); EditorGUI.LabelField(new Rect(startX + 32, startY += spaceY - 5, width, height), cont); unitSetting.enabled = EditorGUI.Toggle(new Rect(startX + 32 + 60, startY, width, height), unitSetting.enabled); if (!unitSetting.enabled) { return(new Vector2(cachedX, startY)); } cont = new GUIContent("Min Wave:", "The minimum wave in which the creep will start appear in"); EditorGUI.LabelField(new Rect(startX += 185, startY - 8, width, height), cont); unitSetting.minWave = EditorGUI.IntField(new Rect(startX + 70, startY - 8, 40, height), unitSetting.minWave); EditorGUI.LabelField(new Rect(cachedX, startY + 7, 185 * 4 - 10, height), "______________________________________________________________________________________________________________________"); startY += spaceY; startX = cachedX; cont = new GUIContent("HitPoint (HP):"); v2 = DrawProceduralVariable(startX, startY, unitSetting.HP, cont); startX += v2.x + 20; cont = new GUIContent("Move Speed:"); v2 = DrawProceduralVariable(startX, startY, unitSetting.speed, cont); startX += v2.x + 20; cont = new GUIContent("Spawn Interval:"); v2 = DrawProceduralVariable(startX, startY, unitSetting.interval, cont); startX += v2.x + 20; return(v2); }
private float DrawProceduralUnitSetting(float startX, float startY, ProceduralUnitSetting unitSetting) { if (unitSetting.enabled) { GUI.Box(new Rect(startX, startY, 185 * 4, proUnitItemHeightShow), ""); } else { GUI.Box(new Rect(startX, startY, 185 * 4, proUnitItemHeightHide), ""); } startX += 5; startY += 5; float cachedX = startX; float cachedY = startY; unitSetting.unitC = unitSetting.unit.GetComponent <UnitCreep>(); TDEditor.DrawSprite(new Rect(startX, startY, 30, 30), unitSetting.unitC.iconSprite); EditorGUI.LabelField(new Rect(startX + 32, startY, width, height), unitSetting.unitC.unitName); cont = new GUIContent("enabled: ", "Check to enable unit in the procedural generation otherwise unit will not be considered at all"); EditorGUI.LabelField(new Rect(startX + 32, startY + spaceY - 3, width, height), cont); unitSetting.enabled = EditorGUI.Toggle(new Rect(startX + 32 + 60, startY + spaceY - 3, width, height), unitSetting.enabled); if (!unitSetting.enabled) { proUnitItemHeightHide = startY + 40 - cachedY; return(startY + 35); } cont = new GUIContent("Min Wave:", "The minimum wave in which the creep will start appear in"); EditorGUI.LabelField(new Rect(startX += 185, startY + 5, width, height), cont); unitSetting.minWave = EditorGUI.IntField(new Rect(startX + 70, startY + 5, 40, height), unitSetting.minWave); EditorGUI.LabelField(new Rect(cachedX, startY += 24, 185 * 4 - 10, height), "______________________________________________________________________________________________________________________"); startY += spaceY; startX = cachedX; cont = new GUIContent("HitPoint (HP):"); DrawProceduralVariable(startX, startY, unitSetting.HP, cont); cont = new GUIContent("Shield:"); DrawProceduralVariable(startX += proceduralVariableWidth + 20, startY, unitSetting.shield, cont); cont = new GUIContent("Move Speed:"); DrawProceduralVariable(startX += proceduralVariableWidth + 20, startY, unitSetting.speed, cont); cont = new GUIContent("Spawn Interval:"); startY = DrawProceduralVariable(startX += proceduralVariableWidth + 20, startY, unitSetting.interval, cont); proUnitItemWidth = startX + proceduralVariableWidth + 20; proUnitItemHeightShow = (startY + spaceY + 8) - cachedY; return(startY + spaceY); }
private static void GetSpawnManager() { instance = (SpawnManager)FindObjectOfType(typeof(SpawnManager)); if (instance != null) { window.waveFoldList = new List <bool>(); for (int i = 0; i < instance.waveList.Count; i++) { window.waveFoldList.Add(true); } //if path is empty, get a path if (instance.defaultPath == null) { instance.defaultPath = (PathTD)FindObjectOfType(typeof(PathTD)); } //verify and setup the procedural wave generation unit list List <ProceduralUnitSetting> unitSettingList = instance.waveGenerator.unitSettingList; List <ProceduralUnitSetting> newSettingList = new List <ProceduralUnitSetting>(); for (int i = 0; i < creepList.Count; i++) { bool match = false; for (int n = 0; n < unitSettingList.Count; n++) { if (unitSettingList[n].unit == creepList[i].gameObject) { newSettingList.Add(unitSettingList[n]); match = true; break; } } if (!match) { ProceduralUnitSetting unitSetting = new ProceduralUnitSetting(); unitSetting.unit = creepList[i].gameObject; newSettingList.Add(unitSetting); } } instance.waveGenerator.unitSettingList = newSettingList; instance.waveGenerator.CheckPathList(); if (instance.defaultPath != null && instance.waveGenerator.pathList.Count == 0) { instance.waveGenerator.pathList.Add(instance.defaultPath); } EditorUtility.SetDirty(instance); } }
SubWave GenerateSubWave(int waveID, int subWaveID, List <ProceduralUnitSetting> availableUnitList) { 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)); subWave.delay = subWaveID * Random.Range(1f, 3f); return(subWave); }
private static void GetSpawnManager(){ instance=(SpawnManager)FindObjectOfType(typeof(SpawnManager)); if(instance!=null){ window.waveFoldList=new List<bool>(); for(int i=0; i<instance.waveList.Count; i++) window.waveFoldList.Add(true); //if path is empty, get a path if(instance.defaultPath==null) instance.defaultPath=(PathTD)FindObjectOfType(typeof(PathTD)); //verify and setup the procedural wave generation unit list List<ProceduralUnitSetting> unitSettingList=instance.waveGenerator.unitSettingList; List<ProceduralUnitSetting> newSettingList=new List<ProceduralUnitSetting>(); for(int i=0; i<creepList.Count; i++){ bool match=false; for(int n=0; n<unitSettingList.Count; n++){ if(unitSettingList[n].unit==creepList[i].gameObject){ newSettingList.Add(unitSettingList[n]); match=true; break; } } if(!match){ ProceduralUnitSetting unitSetting=new ProceduralUnitSetting(); unitSetting.unit=creepList[i].gameObject; newSettingList.Add(unitSetting); } } instance.waveGenerator.unitSettingList=newSettingList; instance.waveGenerator.CheckPathList(); if(instance.defaultPath!=null && instance.waveGenerator.pathList.Count==0) instance.waveGenerator.pathList.Add(instance.defaultPath); List<ProceduralVariable> rscSettingList=instance.waveGenerator.rscSettingList; while(rscList.Count>rscSettingList.Count) rscSettingList.Add(new ProceduralVariable(10, 500)); while(rscList.Count<rscSettingList.Count) rscSettingList.RemoveAt(rscSettingList.Count-1); EditorUtility.SetDirty(instance); } }
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].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 WaveGeneratorSetting(float startX, float startY) { float cachedX = startX; WaveGenerator waveGen = instance.waveGenerator; Vector2 v2; cont = new GUIContent("Sub Wave Count:"); v2 = DrawProceduralVariable(startX, startY, waveGen.subWaveCount, cont); startX += v2.x + 20; cont = new GUIContent("Total Creep Count:"); v2 = DrawProceduralVariable(startX, startY, waveGen.unitCount, cont); startX += v2.x + 20; //startY=v2.y; startX += 140; showProceduralPathList = EditorGUI.Foldout(new Rect(startX, startY, 60, height), showProceduralPathList, "Path List " + (showProceduralPathList ? "" : "(" + waveGen.pathList.Count + ")")); if (showProceduralPathList) { int count = waveGen.pathList.Count; count = EditorGUI.IntField(new Rect(startX + spaceX, startY, 40, height - 2), count); while (count < waveGen.pathList.Count) { waveGen.pathList.RemoveAt(waveGen.pathList.Count - 1); } while (count > waveGen.pathList.Count) { waveGen.pathList.Add(null); } for (int i = 0; i < waveGen.pathList.Count; i++) { EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), " - Element " + (i + 1)); waveGen.pathList[i] = (PathTD)EditorGUI.ObjectField(new Rect(startX + spaceX, startY, width, 15), waveGen.pathList[i], typeof(PathTD), true); } } if (startY < v2.y) { startY = v2.y; } startX = cachedX; startY += spaceY + 15; for (int i = 0; i < waveGen.rscSettingList.Count; i++) { EditorUtilities.DrawSprite(new Rect(startX, startY - 5, 22, 22), rscList[i].icon); cont = new GUIContent(" " + rscList[i].name + ":"); v2 = DrawProceduralVariable(startX, startY, waveGen.rscSettingList[i], cont); startX += v2.x + 20; //startY=v2.y; } startX = cachedX; startY = v2.y + spaceY + 15; for (int i = 0; i < waveGen.unitSettingList.Count; i++) { ProceduralUnitSetting unitSetting = waveGen.unitSettingList[i]; v2 = DrawProceduralUnitSetting(startX, startY, unitSetting); startY = v2.y + spaceY + 15; } contentWidth = 185 * 4 + 25; return(new Vector2(185 * 4, startY)); }
private float DrawProceduralSetting(float startX, float startY) { WaveGenerator waveGen = instance.waveGenerator; float cachedY = startY; float cachedX = startX; cont = new GUIContent("Sub Wave Count:"); startY = DrawProceduralVariable(startX, cachedY, waveGen.subWaveCount, cont); cont = new GUIContent("Total Creep Count:"); startY = DrawProceduralVariable(startX += proceduralVariableWidth + 20, cachedY, waveGen.unitCount, cont); float alignY = startY += spaceY; startY = cachedY; startX += proceduralVariableWidth + 40; cont = new GUIContent("SimilarSubwave:", "Check to have identical subwave for each wave"); EditorGUI.LabelField(new Rect(startX, startY, width, height), cont); waveGen.similarSubWave = EditorGUI.Toggle(new Rect(startX + spaceX, startY, widthS, height), waveGen.similarSubWave); startY += 5; cont = new GUIContent("Utilise All Path:", "Check to have the generator to use all the path when possible, by assigning different path to each subwave (when there's more path than subwave)"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); waveGen.utiliseAllPath = EditorGUI.Toggle(new Rect(startX + spaceX, startY, widthS, height), waveGen.utiliseAllPath); showProceduralPathList = EditorGUI.Foldout(new Rect(startX, startY += spaceY, widthS, height), showProceduralPathList, "Path List " + (showProceduralPathList ? "" : "(" + waveGen.pathList.Count + ")")); if (showProceduralPathList) { int count = waveGen.pathList.Count; count = EditorGUI.IntField(new Rect(startX + spaceX, startY, widthS, height), count); while (count < waveGen.pathList.Count) { waveGen.pathList.RemoveAt(waveGen.pathList.Count - 1); } while (count > waveGen.pathList.Count) { waveGen.pathList.Add(null); } for (int i = 0; i < waveGen.pathList.Count; i++) { EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), " - Element " + (i + 1)); waveGen.pathList[i] = (PathTD)EditorGUI.ObjectField(new Rect(startX + spaceX, startY, width, height), waveGen.pathList[i], typeof(PathTD), true); } startY += spaceY; } startX = cachedX; cachedY = rscDB.rscList.Count > 2 ? Mathf.Max(startY, alignY) : alignY; while (waveGen.rscSettingList.Count < rscDB.rscList.Count) { waveGen.rscSettingList.Add(new ProceduralVariable(0, 0)); } while (waveGen.rscSettingList.Count > rscDB.rscList.Count) { waveGen.rscSettingList.RemoveAt(waveGen.rscSettingList.Count - 1); } for (int i = 0; i < rscDB.rscList.Count; i++) { startY = cachedY + 10; TDEditor.DrawSprite(new Rect(startX, startY - 2, 20, 20), rscDB.rscList[i].icon); cont = new GUIContent(" " + rscDB.rscList[i].name + ":"); startY = DrawProceduralVariable(startX, startY, waveGen.rscSettingList[i], cont); startX += proceduralVariableWidth + 20; } startX = cachedX; startY += spaceY; for (int i = 0; i < waveGen.unitSettingList.Count; i++) { ProceduralUnitSetting unitSetting = waveGen.unitSettingList[i]; startY = DrawProceduralUnitSetting(startX, startY + 12, unitSetting); } return(startY); }
Vector2 DrawProceduralUnitSetting(float startX, float startY, ProceduralUnitSetting unitSetting){ if(unitSetting.enabled) GUI.Box(new Rect(startX, startY, 185*4, 32+5*17+12), ""); else GUI.Box(new Rect(startX, startY, 185*4, 32+10), ""); startX+=5; startY+=5; Vector2 v2=default(Vector2); float cachedX=startX; int unitID=-1; for(int n=0; n<creepList.Count; n++){ if(unitSetting.unit==creepList[n].gameObject) unitID=n; } EditorUtilities.DrawSprite(new Rect(startX, startY, 30, 30), creepList[unitID].iconSprite); EditorGUI.LabelField(new Rect(startX+32, startY+=-2, width, height), creepList[unitID].unitName); cont=new GUIContent("enabled: ", "Check to enable unit in the procedural generation otherwise unit will not be considered at all"); EditorGUI.LabelField(new Rect(startX+32, startY+=spaceY-5, width, height), cont); unitSetting.enabled=EditorGUI.Toggle(new Rect(startX+32+60, startY, width, height), unitSetting.enabled); if(!unitSetting.enabled) return new Vector2(cachedX, startY); cont=new GUIContent("Min Wave:", "The minimum wave in which the creep will start appear in"); EditorGUI.LabelField(new Rect(startX+=185, startY-8, width, height), cont); unitSetting.minWave=EditorGUI.IntField(new Rect(startX+70, startY-8, 40, height), unitSetting.minWave); EditorGUI.LabelField(new Rect(cachedX, startY+7, 185*4-10, height), "______________________________________________________________________________________________________________________"); startY+=spaceY; startX=cachedX; cont=new GUIContent("HitPoint (HP):"); v2=DrawProceduralVariable(startX, startY, unitSetting.HP, cont); startX+=v2.x+20; cont=new GUIContent("Shield:"); v2=DrawProceduralVariable(startX, startY, unitSetting.shield, cont); startX+=v2.x+20; cont=new GUIContent("Move Speed:"); v2=DrawProceduralVariable(startX, startY, unitSetting.speed, cont); startX+=v2.x+20; cont=new GUIContent("Spawn Interval:"); v2=DrawProceduralVariable(startX, startY, unitSetting.interval, cont); startX+=v2.x+20; return v2; }