//function call to spawn a subwave IEnumerator SpawnSubWave(Wave wave, int subWaveIdx) { SubWave subWave = wave.subWaveList[subWaveIdx]; TDSArea sArea = subWave.spawnArea != null ? subWave.spawnArea : spawnAreaList[0]; //use the default spawn area if nothing has been assigned for the subwave //wait for start delay yield return(new WaitForSeconds(subWave.startDelay)); if (subWave.unitPrefab != null) { for (int i = 0; i < subWave.count; i++) { //wait for the spawn cooldown if (i > 0) { yield return(new WaitForSeconds(subWave.interval)); } Quaternion rot = !randomRotation?sArea.GetRotation() : Quaternion.Euler(0, Random.Range(0, 360), 0); UnitAI unitInstance = SpawnUnit(subWave.unitPrefab.gameObject, sArea.GetPosition(), rot, subWave.unitPrefab.gameObject.name + "_" + spawnCount); unitInstance.SetWaveID(this, wave.waveID); //assign the unit with the waveID so they know they belong to a wave (unit with valid waveID will call UnitCleared() callback) wave.activeUnitCount += 1; } } //increase the subWaveSpawned counter wave.subWaveSpawned += 1; yield return(null); }
void DrawBasicConfigure() { cont = new GUIContent("Spawn Upon Start:", "Check to have the spawner start spawning as soon as the game start"); EditorGUILayout.PropertyField(serializedObject.FindProperty("spawnUponStart"), cont); cont = new GUIContent("Start Delay:", "Delay (in second) before the spawning start"); EditorGUILayout.PropertyField(serializedObject.FindProperty("startDelay"), cont); EditorGUILayout.Space(); if (!serializedObject.isEditingMultipleObjects) { EditorGUILayout.BeginHorizontal(); cont = new GUIContent("Spawn Area:", "The area where the units will be spawned in. Require a TDSArea component"); instance.spawnArea = (TDSArea)EditorGUILayout.ObjectField(cont, instance.spawnArea, typeof(TDSArea), true); if (instance.spawnArea == null) { if (GUILayout.Button("Add")) { TDSArea existingArea = instance.gameObject.GetComponent <TDSArea>(); if (existingArea != null) { instance.spawnArea = existingArea; } else { instance.spawnArea = instance.gameObject.AddComponent <TDSArea>(); } } } EditorGUILayout.EndHorizontal(); } else { cont = new GUIContent("Spawn Area:", "The area where the units will be spawned in. Require a TDSArea component"); EditorGUILayout.LabelField(cont, new GUIContent("Cannot edit multiple instance")); } EditorGUILayout.Space(); cont = new GUIContent("Spawn Cooldown:", "The cooldown between each spawn attempt"); EditorGUILayout.PropertyField(serializedObject.FindProperty("spawnCD"), cont); cont = new GUIContent("Max Item Count:", "The maximum amount of active item in the game allowed by this spawner at any given item"); EditorGUILayout.PropertyField(serializedObject.FindProperty("maxItemCount"), cont); cont = new GUIContent("Spawn Chance:", "The chance to successfully spawn an item during each cooldown cycle. Takes value from 0-1 with 0.3 being 30% to successfully spawn an item"); EditorGUILayout.PropertyField(serializedObject.FindProperty("spawnChance"), cont); cont = new GUIContent("Fail Modifier:", "A modifier to the spawn chance should a spawn attempt fail (to prevent the attempt fail too many time in a row). ie if modifier is set as 0.1, each fail attempt will increase the spawn chance by 10%"); EditorGUILayout.PropertyField(serializedObject.FindProperty("failModifier"), cont); //ConfigureSpawnItemList(); }
public override void OnInspectorGUI() { base.OnInspectorGUI(); if (instance == null) { Awake(); } GUI.changed = false; serializedObject.Update(); Undo.RecordObject(instance, "UnitSpawner"); EditorGUILayout.Space(); cont = new GUIContent("Spawn Upon Start:", "Check to have the spawner start spawning as soon as the game start"); EditorGUILayout.PropertyField(serializedObject.FindProperty("spawnUponStart"), cont); cont = new GUIContent("Start Delay:", "Delay (in second) before the spawning start"); EditorGUILayout.PropertyField(serializedObject.FindProperty("startDelay"), cont); EditorGUILayout.Space(); cont = new GUIContent("Random Rotation:", "Check to have the unit spawned facing random rotation, otherwise the rotation of the spawn area will be used"); EditorGUILayout.PropertyField(serializedObject.FindProperty("randomRotation"), cont); EditorGUILayout.Space(); if (!serializedObject.isEditingMultipleObjects) { if (instance.spawnAreaList.Count == 0) { instance.spawnAreaList.Add(null); } EditorGUILayout.BeginHorizontal(); TDSArea area = instance.spawnAreaList[0]; cont = new GUIContent("Spawn Area:", "The area where the units will be spawned in. Require a TDSArea component"); area = (TDSArea)EditorGUILayout.ObjectField(cont, area, typeof(TDSArea), true); instance.spawnAreaList[0] = area; TDSArea existingArea = instance.gameObject.GetComponent <TDSArea>(); if (instance.spawnAreaList.Count == 0 || instance.spawnAreaList[0] == null) { if (GUILayout.Button("Add")) { if (instance.spawnAreaList.Count == 0) { if (existingArea != null) { instance.spawnAreaList.Add(existingArea); } else { instance.spawnAreaList.Add(instance.gameObject.AddComponent <TDSArea>()); } } else if (instance.spawnAreaList[0] == null) { if (existingArea != null) { instance.spawnAreaList[0] = existingArea; } else { instance.spawnAreaList[0] = instance.gameObject.AddComponent <TDSArea>(); } } } } EditorGUILayout.EndHorizontal(); } else { cont = new GUIContent("Spawn Area:", "The area where the units will be spawned in. Require a TDSArea component"); EditorGUILayout.LabelField(cont, new GUIContent("Cannot edit multiple instance")); } EditorGUILayout.Space(); EditorGUILayout.HelpBox("Editing of spawner's spawn information using Inspector is not recommended\nUse the editor window instead", MessageType.Info); if (GUILayout.Button("Open Editor Window")) { UnitSpawnerEditorWindow.Init(instance.gameObject); } //~ EditorGUILayout.Space(); DefaultInspector(); serializedObject.ApplyModifiedProperties(); if (GUI.changed) { EditorUtility.SetDirty(instance); } }
Vector2 DrawSpawnerConfigurator(float startX, float startY, CollectibleSpawner spawner) { startY += 10; cont = new GUIContent("Spawn Area:", "The area which the unit should be spawn in\nIf unspecified, the unit will simply be spawned at the position of the spawner"); EditorGUI.LabelField(new Rect(startX, startY, width, height), cont); spawner.spawnArea = (TDSArea)EditorGUI.ObjectField(new Rect(startX + spaceX, startY, width, height), spawner.spawnArea, typeof(TDSArea), true); startY += 10; if (GUI.Button(new Rect(startX + spaceX + width + 20, startY, 80, height), "Assign Self")) { TDSArea area = spawner.gameObject.GetComponent <TDSArea>(); if (area == null) { area = spawner.gameObject.AddComponent <TDSArea>(); } spawner.spawnArea = area; } cont = new GUIContent("Spawn Upon Start:", "Check to have the spawner start spawning as soon as the game start"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.spawnUponStart = EditorGUI.Toggle(new Rect(startX + spaceX, startY, width, height), spawner.spawnUponStart); cont = new GUIContent("Start Delay:", "Delay (in second) before the spawning start"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); //if(spawner.spawnUponStart) spawner.startDelay = EditorGUI.DelayedFloatField(new Rect(startX + spaceX, startY, 40, height), spawner.startDelay); //else // EditorGUI.LabelField(new Rect(startX+spaceX, startY, 40, height), "-"); startY += 10; cont = new GUIContent("Spawn Cooldown:", "The cooldown between each spawn attempt"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.spawnCD = EditorGUI.DelayedFloatField(new Rect(startX + spaceX, startY, 40, height), spawner.spawnCD); cont = new GUIContent("Max Item Count:", "The maximum amount of active item in the game allowed by this spawner at any given item"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.maxItemCount = EditorGUI.DelayedIntField(new Rect(startX + spaceX, startY, 40, height), spawner.maxItemCount); cont = new GUIContent("Spawn Chance:", "The chance to successfully spawn an item during each cooldown cycle. Takes value from 0-1 with 0.3 being 30% to successfully spawn an item"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.spawnChance = EditorGUI.DelayedFloatField(new Rect(startX + spaceX, startY, 40, height), spawner.spawnChance); cont = new GUIContent("Fail Modifier:", "A modifier to the spawn chance should a spawn attempt fail (to prevent the attempt fail too many time in a row). ie if modifier is set as 0.1, each fail attempt will increase the spawn chance by 10%"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.failModifier = EditorGUI.DelayedFloatField(new Rect(startX + spaceX, startY, 40, height), spawner.failModifier); startY += 10; cont = new GUIContent("Spawn Item:", "The collectible item available to this spawner"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont, headerStyle); int enabledCount = 0; for (int i = 0; i < collectibleDB.collectibleList.Count; i++) { Collectible colt = collectibleDB.collectibleList[i]; CollectibleSpawnInfo spawnInfo = null; bool enabled = false; for (int n = 0; n < spawner.spawnItemList.Count; n++) { enabled = spawner.spawnItemList[n].item == colt; if (enabled) { spawnInfo = spawner.spawnItemList[n]; break; } } bool enabledCached = enabled; float cachedX = startX; TDSEditorUtility.DrawSprite(new Rect(startX + 10, startY += spaceY, 30, 30), colt.icon, colt.desp); cont = new GUIContent(colt.collectibleName, colt.desp); EditorGUI.LabelField(new Rect(startX + 50, startY += 10, width, height), cont); enabled = EditorGUI.Toggle(new Rect(startX += (width), startY, 20, height), enabled); if (spawnInfo != null) { cont = new GUIContent("Chance:", "Chance to spawn this item.\nThe way it works is a check against the individual item chance.\nA final candidate is then chosen over all item that pass the check.\nTakes value from 0-1 with 0.3 being 30% to pass the check"); EditorGUI.LabelField(new Rect(startX += 35, startY, width, height), cont); spawnInfo.chance = EditorGUI.DelayedFloatField(new Rect(startX + 55, startY, 40, height), spawnInfo.chance); cont = new GUIContent("Cooldown:", "The duration (in second) in which the item will be made unavailable after a successful spawn"); EditorGUI.LabelField(new Rect(startX += 120, startY, width, height), cont); spawnInfo.cooldown = EditorGUI.DelayedFloatField(new Rect(startX + 65, startY, 40, height), spawnInfo.cooldown); } if (enabled != enabledCached) { if (enabled) { spawnInfo = new CollectibleSpawnInfo(); spawnInfo.item = colt; spawner.spawnItemList.Insert(enabledCount, spawnInfo); } else { spawner.spawnItemList.Remove(spawnInfo); } } if (enabled) { enabledCount += 1; } startY += 4; startX = cachedX; } return(new Vector2(startX, startY + (1.5f * spaceY))); }
void Awake() { //if no spawn area has been assigned, create one if(spawnArea==null) spawnArea=gameObject.AddComponent<TDSArea>(); }
Vector2 DrawSpawnerConfigurator(float startX, float startY, UnitSpawner spawner) { int mode = (int)spawner.spawnMode; cont = new GUIContent("Spawn Mode:", "The spawn mode to use"); EditorGUI.LabelField(new Rect(startX, startY, width, height), cont, headerStyle); contL = new GUIContent[spawnModeLabel.Length]; for (int i = 0; i < contL.Length; i++) { contL[i] = new GUIContent(spawnModeLabel[i], spawnModeTooltip[i]); } mode = EditorGUI.Popup(new Rect(startX + spaceX, startY, width, 15), new GUIContent(""), mode, contL); spawner.spawnMode = (_SpawnMode)mode; if (spawner.spawnMode == _SpawnMode.WaveBased) { cont = new GUIContent("- Endless", "Enable to activate endless mode (wave will be generated procedurally)"); EditorGUI.LabelField(new Rect(startX + spaceX + width + 25, startY, width, height), cont, headerStyle); spawner.endlessWave = EditorGUI.Toggle(new Rect(startX + spaceX + width + 10, startY, 40, height), spawner.endlessWave); } startY += 10; cont = new GUIContent("Spawn Upon Start:", "Check to have the spawner start spawning automatically as soon as the game start"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.spawnUponStart = EditorGUI.Toggle(new Rect(startX + spaceX, startY, width, height), spawner.spawnUponStart); cont = new GUIContent("Start Delay:", "Delay (in second) before the spawning start"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); //if(spawner.spawnUponStart) spawner.startDelay = EditorGUI.FloatField(new Rect(startX + spaceX, startY, 40, height), spawner.startDelay); //else // EditorGUI.LabelField(new Rect(startX+spaceX, startY, 40, height), "-"); startY += 10; cont = new GUIContent("Random Rotation:", "Check to have the unit spawned facing random rotation, otherwise the rotation of the spawn area will be used"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.randomRotation = EditorGUI.Toggle(new Rect(startX + spaceX, startY, width, height), spawner.randomRotation); startY += 10; for (int i = 0; i < spawner.spawnAreaList.Count - 1; i++) { if (spawner.spawnAreaList[i] == null) { spawner.spawnAreaList.RemoveAt(i); i -= 1; } } if (spawner.spawnAreaList.Count == 0) { spawner.spawnAreaList.Add(null); } cont = new GUIContent("Spawn Area:", "The area which the unit should be spawn in\nIf unspecified, the unit will simply be spawned at the position of the spawner\nRequire game object with a TDSArea component"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.spawnAreaList[0] = (TDSArea)EditorGUI.ObjectField(new Rect(startX + spaceX, startY, width, height), spawner.spawnAreaList[0], typeof(TDSArea), true); if (spawner.spawnAreaList[0] == null) { TDSArea existingArea = spawner.gameObject.GetComponent <TDSArea>(); if (GUI.Button(new Rect(startX + spaceX + width + 10, startY, 75, height), "Add Area")) { if (existingArea != null) { spawner.spawnAreaList[0] = existingArea; } else { spawner.spawnAreaList[0] = spawner.gameObject.AddComponent <TDSArea>(); } } } //only show extra spawn area in free form or endless mode if (spawner.spawnMode == _SpawnMode.FreeForm || (spawner.spawnMode == _SpawnMode.WaveBased && spawner.endlessWave)) { EditorGUI.HelpBox(new Rect(startX + spaceX + width + 20, startY, 1.5f * width, (spawner.spawnAreaList.Count + 1) * spaceY), "Alternate spawn-area will be randomly selected in freeform and endless mode", MessageType.None); for (int i = 1; i < spawner.spawnAreaList.Count; i++) { EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), " - Alt " + i + ":"); spawner.spawnAreaList[i] = (TDSArea)EditorGUI.ObjectField(new Rect(startX + spaceX, startY, width, height), spawner.spawnAreaList[i], typeof(TDSArea), true); if (GUI.Button(new Rect(startX + spaceX + width + 10, startY, 55, height), "remove")) { spawner.spawnAreaList.RemoveAt(i); i -= 1; } } if (GUI.Button(new Rect(startX + spaceX, startY += spaceY, width / 2, height), "Add")) { spawner.spawnAreaList.Add(null); } if (GUI.Button(new Rect(startX + spaceX + width / 2, startY, width / 2, height), "Remove")) { spawner.spawnAreaList.RemoveAt(spawner.spawnAreaList.Count - 1); } } startY += 10; Vector2 v2 = DrawOverrideHitPoint(startX, startY, spawner); startY = v2.y - 10; if (spawner.spawnMode == _SpawnMode.FreeForm) { int modeL = (int)spawner.limitType; cont = new GUIContent("Limit Type:", "Which mode to determine if the spawning is finished"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont, headerStyle); contL = new GUIContent[limitModeLabel.Length]; for (int i = 0; i < contL.Length; i++) { contL[i] = new GUIContent(limitModeLabel[i], limitModeTooltip[i]); } modeL = EditorGUI.Popup(new Rect(startX + spaceX, startY, width, 15), new GUIContent(""), modeL, contL); spawner.limitType = (_SpawnLimitType)modeL; if (spawner.limitType == _SpawnLimitType.Count) { cont = new GUIContent(" - Count Limit:", "The maximum amount of unit to be spawned. The spawner will stop spawning after it has spawned this many unit."); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.limitSpawnCount = EditorGUI.IntField(new Rect(startX + spaceX, startY, 40, height), spawner.limitSpawnCount); } else if (spawner.limitType == _SpawnLimitType.Timed) { cont = new GUIContent(" - Time Limit:", "The time duration in second which the spawner will be spawning. The spawner will stop spawning when the time is due"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.limitSpawnTime = EditorGUI.IntField(new Rect(startX + spaceX, startY, 40, height), spawner.limitSpawnTime); } else if (spawner.limitType == _SpawnLimitType.None) { EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), ""); EditorGUI.LabelField(new Rect(startX + spaceX, startY, width, height), "Infinite Spawn"); } cont = new GUIContent("Spawn Cooldown:", "The cooldown between each unit spawn"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.spawnCD = EditorGUI.FloatField(new Rect(startX + spaceX, startY, 40, height), spawner.spawnCD); cont = new GUIContent("Active Limit:", "The maximum amount of active spawned unit at any given time"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.activeLimit = EditorGUI.IntField(new Rect(startX + spaceX, startY, 40, height), spawner.activeLimit); startY += 15; v2 = DrawSpawnUnitList(startX, startY, spawner); startY = v2.y; } else if (spawner.spawnMode == _SpawnMode.WaveBased) { cont = new GUIContent("Waves Cooldown:", "cooldown between each wave"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.delayBetweenWave = EditorGUI.FloatField(new Rect(startX + spaceX, startY, 40, height), spawner.delayBetweenWave); startY += 10; if (spawner.endlessWave) { cont = new GUIContent("MaxSubWaveCount:", "Maximum subwave allow for each generated wave"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.maxSubWaveCount = EditorGUI.IntField(new Rect(startX + spaceX, startY, 40, height), spawner.maxSubWaveCount); startY += 5; float cachedX = startX; float spX = 70; cont = new GUIContent("Unit Count:", "starting unit count for each wave"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.unitCount = EditorGUI.IntField(new Rect(startX + spX, startY, 40, height), spawner.unitCount); cont = new GUIContent("Increment:", "increment in unit count for each subsequent wave"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.unitCountInc = EditorGUI.IntField(new Rect(startX + spX, startY, 40, height), spawner.unitCountInc); startY -= 2 * spaceY; startX += 125; cont = new GUIContent("Credit:", "starting unit count for each wave"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.startingCredit = EditorGUI.IntField(new Rect(startX + spX, startY, 40, height), spawner.startingCredit); cont = new GUIContent("Increment:", "increment in unit count for each subsequent wave"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.creditIncrement = EditorGUI.IntField(new Rect(startX + spX, startY, 40, height), spawner.creditIncrement); startY -= 2 * spaceY; startX += 125; cont = new GUIContent("Score:", "starting unit count for each wave"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.startingScore = EditorGUI.IntField(new Rect(startX + spX, startY, 40, height), spawner.startingScore); cont = new GUIContent("Increment:", "increment in unit count for each subsequent wave"); EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), cont); spawner.scoreIncrement = EditorGUI.IntField(new Rect(startX + spX, startY, 40, height), spawner.scoreIncrement); startY += 15; startX = cachedX; v2 = DrawSpawnUnitList(startX, startY, spawner); startY = v2.y; } else { EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), "Waves Count: " + spawner.waveList.Count, headerStyle); if (GUI.Button(new Rect(startX + spaceX, startY, 40, 16), "+")) { spawner.waveList.Add(new Wave()); } if (GUI.Button(new Rect(startX + spaceX + 50, startY, 40, 16), "-")) { if (spawner.waveList.Count > 1) { spawner.waveList.RemoveAt(spawner.waveList.Count - 1); } } for (int i = 0; i < spawner.waveList.Count; i++) { Wave wave = spawner.waveList[i]; startY += spaceY + 10; GUI.Box(new Rect(startX + 25, startY, 655, (2 + wave.subWaveList.Count) * spaceY + 15), ""); startX += 5; startY += 5; EditorGUI.LabelField(new Rect(startX, startY, width, height), (i + 1) + "."); startX += 25; //cont=new GUIContent("Credit:", "The credit gained upon clearing the wave"); //EditorGUI.LabelField(new Rect(startX, startY, width, height), cont); //wave.creditGain=EditorGUI.IntField(new Rect(startX+45, startY, 40, height), wave.creditGain); cont = new GUIContent("Score:", "The score gained upon clearing the wave"); EditorGUI.LabelField(new Rect(startX + 110, startY, width, height), cont); wave.scoreGain = EditorGUI.IntField(new Rect(startX + 154, startY, 40, height), wave.scoreGain); GUI.color = new Color(1f, 0.7f, 0.7f, 1f); if (GUI.Button(new Rect(startX + 585, startY, 55, 16), "remove")) { spawner.waveList.RemoveAt(i); i -= 1; continue; } GUI.color = Color.white; startY += 5; EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, height), "Sub Waves:"); if (GUI.Button(new Rect(startX + spaceX - 20, startY, 40, 16), "+")) { wave.subWaveList.Add(new SubWave()); } if (GUI.Button(new Rect(startX + spaceX + 30, startY, 40, 16), "-")) { if (wave.subWaveList.Count > 1) { wave.subWaveList.RemoveAt(wave.subWaveList.Count - 1); } } for (int n = 0; n < wave.subWaveList.Count; n++) { SubWave subWave = wave.subWaveList[n]; EditorGUI.LabelField(new Rect(startX, startY += spaceY, width, 15), "-"); int unitIdx = subWave.unitPrefab != null?TDSEditor.GetUnitAIIndex(subWave.unitPrefab.prefabID) : 0; unitIdx = EditorGUI.Popup(new Rect(startX + 20, startY, width, 15), unitIdx, unitAILabel); if (unitIdx == 0) { subWave.unitPrefab = null; } else if (unitIdx > 0) { subWave.unitPrefab = unitAIDB.unitList[unitIdx - 1]; } float cachedX = startX; cont = new GUIContent("Count:", "The number of unit to be spawned"); EditorGUI.LabelField(new Rect(startX += 180, startY, width, height), cont); subWave.count = EditorGUI.IntField(new Rect(startX + 45, startY, 25, height), subWave.count); cont = new GUIContent("Delay:", "Delay (in second) before the spawning start"); EditorGUI.LabelField(new Rect(startX += 90, startY, width, height), cont); subWave.startDelay = EditorGUI.FloatField(new Rect(startX + 42, startY, 25, height), subWave.startDelay); cont = new GUIContent("Interval:", "The spawn interval (in second) between each unit"); EditorGUI.LabelField(new Rect(startX += 80, startY, width, height), cont); subWave.interval = EditorGUI.FloatField(new Rect(startX + 52, startY, 25, height), subWave.interval); cont = new GUIContent("Alt-Area:", "The area which the unit of this wave should be spawned, replacing the default area (optional)"); EditorGUI.LabelField(new Rect(startX += 90, startY, width, height), cont); wave.spawnArea = (TDSArea)EditorGUI.ObjectField(new Rect(startX + 60, startY, 100, height), wave.spawnArea, typeof(TDSArea), true); if (wave.subWaveList.Count > 1) { if (GUI.Button(new Rect(startX + 180, startY, 20, 16), "X")) { wave.subWaveList.RemoveAt(n); n -= 1; } } startX = cachedX; } startX -= 5; startY += 5; startX -= 25; } } } return(new Vector2(startX, startY + (2 * spaceY))); }