wgl 5 mesi fa
parent
commit
be3d5f1d67
24 ha cambiato i file con 4309 aggiunte e 1034 eliminazioni
  1. 347 102
      ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/Editor/GameMapEdPopup.cs
  2. 164 84
      ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/Editor/GameMapEditor.cs
  3. 2 2
      ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/GameMap.cs
  4. 14 6
      ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/GameMapLayer.cs
  5. 1 3
      ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/GameMapsAsset.cs
  6. 0 65
      ActionTowerDefense/Assets/Gen/CfgBuilding.cs
  7. 0 11
      ActionTowerDefense/Assets/Gen/CfgCreateBuilding.cs.meta
  8. 6 6
      ActionTowerDefense/Assets/Gen/CfgDynamicEnemy.cs
  9. 1 1
      ActionTowerDefense/Assets/Gen/CfgDynamicEnemy.cs.meta
  10. 0 84
      ActionTowerDefense/Assets/Gen/SingleBuildingConfig.cs
  11. 0 161
      ActionTowerDefense/Assets/Gen/SingleCreateBuildingConfig.cs
  12. 0 11
      ActionTowerDefense/Assets/Gen/SingleCreateBuildingConfig.cs.meta
  13. 5 1
      ActionTowerDefense/Assets/Gen/SingleCreateEnemyConfig.cs
  14. 105 0
      ActionTowerDefense/Assets/Gen/SingleDynamicEnemyConfig.cs
  15. 1 1
      ActionTowerDefense/Assets/Gen/SingleDynamicEnemyConfig.cs.meta
  16. 5 10
      ActionTowerDefense/Assets/Gen/Tables.cs
  17. 213 7
      ActionTowerDefense/Assets/Scripts/EnemyCreater.cs
  18. 0 26
      ActionTowerDefense/GenerateDatas/json/cfgbuilding.json
  19. 0 310
      ActionTowerDefense/GenerateDatas/json/cfgcreatebuilding.json
  20. 3350 143
      ActionTowerDefense/GenerateDatas/json/cfgcreateenemy.json
  21. 95 0
      ActionTowerDefense/GenerateDatas/json/cfgdynamicenemy.json
  22. BIN
      ActionTowerDefense/Luban/Config/Datas/__tables__.xlsx
  23. BIN
      ActionTowerDefense/Luban/Config/Datas/出怪表.xlsx
  24. BIN
      ActionTowerDefense/Luban/Config/Datas/动态出怪表.xlsx

+ 347 - 102
ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/Editor/GameMapEdPopup.cs

@@ -6,7 +6,6 @@ using cfg;
 using System;
 using System.IO;
 using OfficeOpenXml;
-using System.Diagnostics;
 
 public class GameMapEdPopup : PopupWindowContent
 {
@@ -52,7 +51,6 @@ public class GameMapEdPopup : PopupWindowContent
 
 	public override void OnGUI(Rect r)
 	{
-
 		DrawHeader(new Rect(0, 0, r.width, 25));
 		r.y += 25; r.height -= 25;
 		scroll = GUI.BeginScrollView(r, scroll, contentRect, false, true);
@@ -73,28 +71,7 @@ public class GameMapEdPopup : PopupWindowContent
 		GUI.Label(r, GC_Head, EditorStyles.boldLabel);
         r.x = r.xMax - 90; r.y = 5; r.width = 80;
         GUI.enabled = list.index >= 0;
-        //if (GUI.Button(r, GC_Rem, EditorStyles.miniButtonRight))
-        //{
-        //    if (list.index >= 0 && list.index < Asset.maps.Count)
-        //    {
-        //        Undo.RecordObject(Asset, "Remove Game Map");
-        //        int key = list.index;
-        //        Asset.RemoveMapAtIndex(list.index);
-        //        ChangeContentRect();
-        //        if (key == 0)
-        //        {
-        //            OnMapSelected(0);
-        //        }
-        //        else
-        //        {
-        //            OnMapSelected(key - 1);
-        //        }
-
-        //    }
-        //}
-
-        //GUI.enabled = true;
-        //r.x -= 25;
+
         if (GUI.Button(r, GC_Add, EditorStyles.miniButtonLeft))
         {
             if (isSelect)
@@ -106,7 +83,15 @@ public class GameMapEdPopup : PopupWindowContent
 			}
             else
             {
-				SaveAsNewExcelData(GameMapEditor.createEnemyExcelPath);
+				if (GameMapEditor.asset.maps[0].isDynamic)
+				{
+					SaveAsNewCreateEnemyData(true);
+				}
+				else
+				{
+					SaveAsNewCreateEnemyData(false);
+				}
+				
             }
 			editorWindow.Close();
 		}
@@ -121,18 +106,43 @@ public class GameMapEdPopup : PopupWindowContent
 	{
         if (isSelect)
         {
-			ReloadExcelData(GameMapEditor.createEnemyExcelPath, list.index + 1);
+			if(list.index + 1 >= GameMapEditor.asset.dynamicSheetStart)
+            {
+				ReloadDynamicEnemyData(list.index + 1);
+            }
+            else
+            {
+				ReloadCreateEnemyData(list.index + 1);
+			}
+
 			OnMapSelected(0);
         }
         else
         {
-			SaveExcelData(GameMapEditor.createEnemyExcelPath, list.index + 1);
+            if (GameMapEditor.asset.maps[0].isDynamic)
+            {
+				SaveDynamicEnemyData(list.index + 1);
+            }
+            else
+            {
+				SaveCreateEnemyData(list.index + 1);
+			}
         }
 		editorWindow.Close();
 	}
 
-	void SaveAsNewExcelData(string path)
+	void SaveAsNewCreateEnemyData(bool isDynamic)
     {
+		string path = "";
+        if (isDynamic)
+        {
+			path = GameMapEditor.dynamicEnemyExcelPath;
+        }
+        else
+        {
+			path = GameMapEditor.createEnemyExcelPath;
+		}
+		
 		FileInfo fileInfo = new FileInfo(path);
 		using (ExcelPackage package = new ExcelPackage(fileInfo))
         {
@@ -152,11 +162,20 @@ public class GameMapEdPopup : PopupWindowContent
 				return;
 			}
 		}
-		SaveExcelData(path, 0,true);
+        if (isDynamic)
+        {
+			SaveDynamicEnemyData(0, true);
+        }
+        else
+        {
+			SaveCreateEnemyData(0, true);
+		}
+
 	}
 
-	void SaveExcelData(string path, int mapIdx, bool isNew = false)
+	void SaveCreateEnemyData(int mapIdx, bool isNew = false)
 	{
+		string path = GameMapEditor.createEnemyExcelPath;
 		List<string> excelWorksheets = new();
 		GameMap gameMap = GameMapEditor.asset.maps[GameMapEditor.mapIdx];
 		FileInfo fileInfo = new FileInfo(path);
@@ -174,107 +193,218 @@ public class GameMapEdPopup : PopupWindowContent
 			ExcelEditor.RemoveExcelRows(package, gameMap.showIdent, 10, 500);
 			ExcelEditor.ModifyExcel(package, gameMap.showIdent, "D5", GameMapEditor.mapSize_w.ToString());
 			ExcelEditor.ModifyExcel(package, gameMap.showIdent, "D6", GameMapEditor.mapSize_h.ToString());
-			
-
 
 			int cell_row = 10;
 			float idFloat = 0f;
-			int idInt = 0; 
+			int idInt = 0;
 			for(int i = 0; i < gameMap.layers.Length; i++)
             {
 				GameMapLayer layer = gameMap.layers[i];
-				
+
 				ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"C{cell_row}", layer.name);
-                if (layer.isFromTower)
-                {
-					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"E{cell_row}", layer.buildingId);
-					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"F{cell_row}", layer.buildingHp.ToString());
-				}
-                else
-                {
-                    if ((!layer.isTowerWave && !layer.isFromTower) || i == 0)
-                    {
-						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"D{cell_row}", layer.duration.ToString());
-					}
-					
+				switch (layer.waveType) 
+				{
+					case WaveType.Common:
+						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"E{cell_row}", layer.duration.ToString());
+						idInt++;
+						break;
+					case WaveType.FromTower:
+						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"F{cell_row}", layer.buildingId);
+						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"G{cell_row}", layer.buildingHp.ToString());
+						idFloat += 0.01f;
+						break;
+					case WaveType.Tower:
+						if(i == 0)
+                        {
+							ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"E{cell_row}", layer.duration.ToString());
+						}
+						break;
 				}
 
-				if (!layer.isTowerWave)
+				if (layer.isDynamic)
 				{
-					if (layer.isFromTower)
+					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"D{cell_row}", layer.dynamicSheet.ToString());
+					switch (layer.waveType)
 					{
-						idFloat += 0.01f;
+						case WaveType.Common:
+							ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"B{cell_row}", idInt.ToString());
+							break;
+						case WaveType.Tower:
+							ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"B{cell_row}", "0");
+							ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"C{cell_row}", layer.name);
+							break;
+						case WaveType.FromTower:
+							ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"B{cell_row}", $"{idFloat:F2}");
+							break;
 					}
-					else
+					cell_row++;
+                }
+                else
+                {
+					foreach (var item in layer.spawnTimes)
 					{
-						idInt++;
+						SpawnTime spawnTime = item.Value;
+						try
+						{
+							if (spawnTime.pos.Count == 0)
+							{
+								continue;
+							}
+						}
+						catch (Exception e)
+						{
+							UnityEngine.Debug.LogException(e);
+						}
+
+						switch (layer.waveType)
+						{
+							case WaveType.Common:
+								ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"B{cell_row}", idInt.ToString());
+								break;
+							case WaveType.Tower:
+								ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"B{cell_row}", "0");
+								ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"C{cell_row}", layer.name);
+								break;
+							case WaveType.FromTower:
+								ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"B{cell_row}", $"{idFloat:F2}");
+								break;
+						}
+
+						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"H{cell_row}", Asset.tileAsset.GetTile(spawnTime.id).name);
+						string posString = "";
+						for (int k = 0; k < spawnTime.pos.Count; k++)
+						{
+							int pos = spawnTime.pos[k] + 1;
+							int w = pos % GameMapEditor.mapSize_w;
+							int h = pos / GameMapEditor.mapSize_w;
+							if (w == 0)
+							{
+								posString += GameMapEditor.mapSize_w.ToString();
+								posString += ",";
+								posString += h.ToString();
+							}
+							else
+							{
+								posString += w.ToString();
+								posString += ",";
+								posString += (h + 1).ToString();
+							}
+							if (k == spawnTime.pos.Count - 1)
+							{
+								break;
+							}
+							posString += ",";
+						}
+						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"I{cell_row}", posString);
+						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"J{cell_row}", spawnTime.startTime.ToString());
+						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"K{cell_row}", spawnTime.endTime.ToString());
+						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"L{cell_row}", spawnTime.num.ToString());
+						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"M{cell_row}", (spawnTime.attack == 0 ? 1 : spawnTime.attack).ToString());
+						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"N{cell_row}", (spawnTime.moveSpeed == 0 ? 1 : spawnTime.moveSpeed).ToString());
+						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"O{cell_row}", (spawnTime.Hp == 0 ? 1 : spawnTime.Hp).ToString());
+						cell_row++;
 					}
 				}
 
-				for (int j = 0;j< layer.spawnTimes.Count; j++)
-                {
-					SpawnTime spawnTime = layer.spawnTimes[j];
+
+            }
+			try
+			{
+				package.Save();
+			}
+			catch (System.InvalidOperationException e)
+			{
+				EditorUtility.DisplayDialog("Error", $"出怪表未关闭或Sheet名重复,请重试", "OK");
+				UnityEngine.Debug.LogException(e);
+				return;
+			}
+
+		}
+		UnityEngine.Debug.Log($"\"{gameMap.showIdent}\"表保存完毕!");
+		UnityEngine.Debug.Log("记得运行\"gen_code_json.bat\"更新数据!");
+		ExcelEditor.RunBat();
+	}
+
+	void SaveDynamicEnemyData(int mapIdx, bool isNew = false)
+	{
+		string path = GameMapEditor.dynamicEnemyExcelPath;
+		List<string> excelWorksheets = new();
+		GameMap gameMap = GameMapEditor.asset.maps[GameMapEditor.mapIdx];
+		FileInfo fileInfo = new FileInfo(path);
+		using (ExcelPackage package = new ExcelPackage(fileInfo))
+		{
+			excelWorksheets = ExcelEditor.ReadExcelSheetsInfo(package);
+			if (!isNew)
+			{
+				if (!ExcelEditor.RenameSheet(package, excelWorksheets[mapIdx - 1], gameMap.showIdent))
+				{
+					return;
+				}
+			}
+			ExcelEditor.RemoveExcelRows(package, gameMap.showIdent, 10, 500);
+			ExcelEditor.ModifyExcel(package, gameMap.showIdent, "D5", GameMapEditor.mapSize_w.ToString());
+			ExcelEditor.ModifyExcel(package, gameMap.showIdent, "D6", GameMapEditor.mapSize_h.ToString());
+
+			int cell_row = 10;
+			int idInt = 0;
+			for (int i = 0; i < gameMap.layers.Length; i++)
+			{
+				GameMapLayer layer = gameMap.layers[i];
+
+				ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"C{cell_row}", layer.name);
+				idInt++;
+
+				foreach (var item in layer.spawnTimes)
+				{
+					SpawnTime spawnTime = item.Value;
 					try
 					{
 						if (spawnTime.pos.Count == 0)
 						{
 							continue;
 						}
-					} 
-					catch (Exception e)
-                    {
-						UnityEngine.Debug.LogException(e);
-                    }
-
-					if (layer.isTowerWave)
-					{
-						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"B{cell_row}", "0");
-						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"C{cell_row}", layer.name);
-					}
-					else if (layer.isFromTower)
-					{
-						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"B{cell_row:F2}", idFloat.ToString());
 					}
-					else
+					catch (Exception e)
 					{
-						ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"B{cell_row:F2}", idInt.ToString());
+						UnityEngine.Debug.LogException(e);
 					}
 
-					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"G{cell_row}", Asset.tileAsset.GetTile(spawnTime.id).name);
+					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"B{cell_row}", idInt.ToString());
+					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"D{cell_row}", Asset.tileAsset.GetTile(spawnTime.id).name);
 					string posString = "";
-					for(int k = 0; k < spawnTime.pos.Count; k++)
-                    {
+					for (int k = 0; k < spawnTime.pos.Count; k++)
+					{
 						int pos = spawnTime.pos[k] + 1;
 						int w = pos % GameMapEditor.mapSize_w;
 						int h = pos / GameMapEditor.mapSize_w;
 						if (w == 0)
-                        {
+						{
 							posString += GameMapEditor.mapSize_w.ToString();
 							posString += ",";
 							posString += h.ToString();
 						}
-                        else
-                        {
+						else
+						{
 							posString += w.ToString();
 							posString += ",";
 							posString += (h + 1).ToString();
 						}
-						if(k == spawnTime.pos.Count - 1)
-                        {
+						if (k == spawnTime.pos.Count - 1)
+						{
 							break;
-                        }
+						}
 						posString += ",";
-                    }
-					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"H{cell_row}",	posString);
-					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"I{cell_row}",	spawnTime.startTime.ToString());
-					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"J{cell_row}",	spawnTime.endTime.ToString());
-					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"K{cell_row}",	spawnTime.num.ToString());
-					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"L{cell_row}", (spawnTime.attack == 0?1:spawnTime.attack).ToString());
-					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"M{cell_row}", (spawnTime.moveSpeed == 0?1:spawnTime.moveSpeed).ToString());
-					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"N{cell_row}", (spawnTime.Hp == 0?1:spawnTime.Hp).ToString());
+					}
+					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"E{cell_row}", posString);
+					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"F{cell_row}", spawnTime.startTime.ToString());
+					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"G{cell_row}", spawnTime.endTime.ToString());
+					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"H{cell_row}", spawnTime.num.ToString());
+					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"I{cell_row}", (spawnTime.attack == 0 ? 1 : spawnTime.attack).ToString());
+					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"J{cell_row}", (spawnTime.moveSpeed == 0 ? 1 : spawnTime.moveSpeed).ToString());
+					ExcelEditor.ModifyExcel(package, gameMap.showIdent, $"K{cell_row}", (spawnTime.Hp == 0 ? 1 : spawnTime.Hp).ToString());
 					cell_row++;
 				}
-            }
+			}
 			try
 			{
 				package.Save();
@@ -292,8 +422,9 @@ public class GameMapEdPopup : PopupWindowContent
 		ExcelEditor.RunBat();
 	}
 
-	public void ReloadExcelData(string path, int mapIdx)
+	public void ReloadCreateEnemyData(int mapIdx)
 	{
+		string path = GameMapEditor.createEnemyExcelPath;
 		ExcelEditor.RunBat();
 		List<string> excelWorksheets = new();
 		Tables allCfgData = new Tables(ExcelEditor.Loader);
@@ -316,6 +447,7 @@ public class GameMapEdPopup : PopupWindowContent
 		GameMapEditor.currLayer = -1;
 		int mapId = -1;
 		float id = 0;
+		ArrayUtility.Clear(ref gameMap.layers);
 		for (int i = 0; i < cfgCreateEnemy.Count; i++)
 		{
 			if (cfgCreateEnemy[i].WaveID == -1)
@@ -325,7 +457,6 @@ public class GameMapEdPopup : PopupWindowContent
 					break;
                 }
 				mapId++;
-				ArrayUtility.Clear(ref gameMap.layers);
 				continue;
 			}
 			if(mapId == mapIdx - 1)
@@ -338,7 +469,7 @@ public class GameMapEdPopup : PopupWindowContent
 					GameMapLayer gameMapLayer = gameMap.layers[gameMap.layers.Length - 1];
 					gameMapLayer.name = singleCreateEnemyConfig.WaveName;
 					gameMapLayer.duration = singleCreateEnemyConfig.WaveTime;
-					gameMapLayer.isTowerWave = true;
+					gameMapLayer.waveType = WaveType.Tower;
 
 					ReloadEnemyInWave(gameMapLayer, cfgCreateEnemy[i], excelWorksheets[mapIdx - 1]);
 				}
@@ -363,19 +494,25 @@ public class GameMapEdPopup : PopupWindowContent
 						gameMapLayer.name = singleCreateEnemyConfig.WaveName;
 						if(cfgCreateEnemy[i].WaveID < 1)
                         {
-							gameMapLayer.isFromTower = true;
+							gameMapLayer.waveType = WaveType.FromTower;
 							gameMapLayer.buildingId = singleCreateEnemyConfig.BuildingID;
 							gameMapLayer.buildingHp = singleCreateEnemyConfig.BuildingHP;
 						}
                         else
                         {
-							gameMapLayer.isFromTower = false;
+							gameMapLayer.waveType = WaveType.Common;
 							gameMapLayer.duration = singleCreateEnemyConfig.WaveTime;
 						}
-						
-
-						//波次第一行怪物数据
-						ReloadEnemyInWave(gameMapLayer, cfgCreateEnemy[i], excelWorksheets[mapIdx - 1]);
+						if(cfgCreateEnemy[i].Dynamic == 0)
+                        {
+							//波次第一行怪物数据
+							ReloadEnemyInWave(gameMapLayer, cfgCreateEnemy[i], excelWorksheets[mapIdx - 1]);
+						}
+						else
+                        {
+							gameMapLayer.isDynamic = true;
+							gameMapLayer.dynamicSheet = cfgCreateEnemy[i].Dynamic;
+                        }
 					}
 					else
 					{
@@ -399,6 +536,75 @@ public class GameMapEdPopup : PopupWindowContent
 		UnityEngine.Debug.Log($"\"{excelWorksheets[mapIdx - 1]}\"表导入完毕!");
 	}
 
+	public void ReloadDynamicEnemyData(int mapIdx)
+	{
+		int sheetId = mapIdx - GameMapEditor.asset.dynamicSheetStart;
+		string path = GameMapEditor.dynamicEnemyExcelPath;
+		ExcelEditor.RunBat();
+		List<string> excelWorksheets = new();
+		Tables allCfgData = new Tables(ExcelEditor.Loader);
+		List<SingleDynamicEnemyConfig> cfgDynamicEnemy = allCfgData.CfgDynamicEnemy.DataList;
+		GameMap gameMap = GameMapEditor.asset.maps[0];
+		FileInfo fileInfo = new FileInfo(path);
+		using (ExcelPackage package = new ExcelPackage(fileInfo))
+		{
+			excelWorksheets = ExcelEditor.ReadExcelSheetsInfo(package);
+
+			//导入关卡数据
+			gameMap.ident = GameMapEditor.asset.maps[mapIdx].ident;
+			gameMap.showIdent = gameMap.ident;
+			int.TryParse(ExcelEditor.GetCellData(package, excelWorksheets[sheetId], "D5"), out GameMapEditor.mapSize_w);
+			int.TryParse(ExcelEditor.GetCellData(package, excelWorksheets[sheetId], "D6"), out GameMapEditor.mapSize_h);
+			gameMap.Resize(GameMapEditor.mapSize_w, GameMapEditor.mapSize_h);
+			gameMap.isDynamic = true;
+		}
+
+		//导入波次数据
+		GameMapEditor.currLayer = -1;
+		int mapId = -1;
+		float id = 0;
+		ArrayUtility.Clear(ref gameMap.layers);
+		UnityEngine.Debug.Log(sheetId);
+		for (int i = 0; i < cfgDynamicEnemy.Count; i++)
+		{
+			if (cfgDynamicEnemy[i].WaveID == -1)
+			{
+				if (mapId == sheetId)
+				{
+					break;
+				}
+				mapId++;
+				continue;
+			}
+			if (mapId == sheetId)
+			{
+				
+				if (cfgDynamicEnemy[i].WaveID != id)
+				{
+					//波次第一行的波次数据
+					SingleDynamicEnemyConfig singleDynamicEnemyConfig = cfgDynamicEnemy[i];
+					id = cfgDynamicEnemy[i].WaveID;
+					ArrayUtility.Add(ref gameMap.layers, new GameMapLayer());
+					gameMap.InitLayer(gameMap.layers.Length);
+					GameMapLayer gameMapLayer = gameMap.layers[gameMap.layers.Length - 1];
+					gameMapLayer.name = singleDynamicEnemyConfig.WaveName;
+					gameMapLayer.waveType = WaveType.Common;
+					ReloadDynamicEnemy(gameMapLayer, cfgDynamicEnemy[i], excelWorksheets[sheetId]);
+				}
+				else
+				{
+					GameMapLayer gameMapLayer = gameMap.layers[gameMap.layers.Length - 1];
+					ReloadDynamicEnemy(gameMapLayer, cfgDynamicEnemy[i], excelWorksheets[sheetId]);
+				}
+
+			}
+		}
+		// 标记资源为脏数据,以便保存更改
+		EditorUtility.SetDirty(GameMapEditor.asset);
+		AssetDatabase.SaveAssets();
+		UnityEngine.Debug.Log($"\"{excelWorksheets[sheetId]}\"表导入完毕!");
+	}
+
 
 	public void ReloadEnemyInWave(GameMapLayer layer, SingleCreateEnemyConfig cfgData, string SheetName)
     {
@@ -407,12 +613,11 @@ public class GameMapEdPopup : PopupWindowContent
 			EditorUtility.DisplayDialog("Error", $"\"{SheetName}\"关卡\"{layer.name}\"波次中有怪物名称为空", "OK");
 			return;
 		}
-		int spawnTimeId = layer.spawnTimes.FindIndex(x => GameMapEditor.asset.tileAsset.GetTile(x.id).name == cfgData.EnemyName);
-		if (layer.spawnTimes.Count == 0 || spawnTimeId == -1)
+		GameMapTile tile = GameMapEditor.asset.tileAsset.tiles.Find(x => x.name == cfgData.EnemyName);
+		if (!layer.spawnTimes.ContainsKey(tile.id))
         {
 			SpawnTime spawnTime = new();
 
-			GameMapTile tile = GameMapEditor.asset.tileAsset.tiles.Find(x => x.name == cfgData.EnemyName);
 			spawnTime.id = tile.id;
             if (cfgData.Position.Count % 2 != 0)
             {
@@ -433,12 +638,52 @@ public class GameMapEdPopup : PopupWindowContent
 			spawnTime.moveSpeed = cfgData.SpeedRatio;
 			spawnTime.attack = cfgData.AttackRatio;
 
-			layer.spawnTimes.Add(spawnTime);
+			layer.spawnTimes.Add(tile.id,spawnTime);
         }
         else
         {
-			UnityEngine.Debug.LogError($"波次中\"{cfgData.EnemyName}\"重复");
+			UnityEngine.Debug.LogError($"\"{layer.name}\"波次中\"{cfgData.EnemyName}\"重复");
         }
     }
+
+	public void ReloadDynamicEnemy(GameMapLayer layer, SingleDynamicEnemyConfig cfgData, string SheetName)
+	{
+		if (cfgData.EnemyName == "")
+		{
+			EditorUtility.DisplayDialog("Error", $"\"{SheetName}\"关卡\"{layer.name}\"波次中有怪物名称为空", "OK");
+			return;
+		}
+		GameMapTile tile = GameMapEditor.asset.tileAsset.tiles.Find(x => x.name == cfgData.EnemyName);
+		if (!layer.spawnTimes.ContainsKey(tile.id))
+		{
+			SpawnTime spawnTime = new();
+
+			spawnTime.id = tile.id;
+			if (cfgData.Position.Count % 2 != 0)
+			{
+				UnityEngine.Debug.LogError($"出怪表\"{cfgData.WaveName}\"中\"{cfgData.EnemyName}\"的Position格式错误");
+			}
+			spawnTime.pos = new();
+			for (int i = 0; i < cfgData.Position.Count; i += 2)
+			{
+				int x = cfgData.Position[i];
+				int y = cfgData.Position[i + 1];
+				layer.grid[(y - 1) * GameMapEditor.mapSize_w + x - 1] = spawnTime.id;
+				spawnTime.pos.Add((y - 1) * GameMapEditor.mapSize_w + x - 1);
+			}
+			spawnTime.startTime = cfgData.StartTime;
+			spawnTime.endTime = cfgData.EndTime;
+			spawnTime.num = cfgData.Count;
+			spawnTime.Hp = cfgData.HPRatio;
+			spawnTime.moveSpeed = cfgData.SpeedRatio;
+			spawnTime.attack = cfgData.AttackRatio;
+
+			layer.spawnTimes.Add(tile.id, spawnTime);
+		}
+		else
+		{
+			UnityEngine.Debug.LogError($"\"{layer.name}\"波次中\"{cfgData.EnemyName}\"重复");
+		}
+	}
 	// ----------------------------------------------------------------------------------------------------------------
 }

+ 164 - 84
ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/Editor/GameMapEditor.cs

@@ -3,9 +3,7 @@ using System.Reflection;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEditor;
-using System.Linq;
 using cfg;
-using SimpleJSON;
 using System.IO;
 using OfficeOpenXml;
 
@@ -140,6 +138,7 @@ public class GameMapEditor : EditorWindow
     private static readonly GUIContent GC_Viz = new GUIContent("*", "Toggle layer visblity in editor");
 
 	public static string createEnemyExcelPath = "Luban/Config/Datas/出怪表.xlsx";
+	public static string dynamicEnemyExcelPath = "Luban/Config/Datas/动态出怪表.xlsx";
 	public static string enemyExcelPath = "Luban/Config/Datas/怪物表.xlsx";
 
     private GenericMenu addTileMenu = null;
@@ -162,6 +161,13 @@ public class GameMapEditor : EditorWindow
 		{ 127, 42 }, { 253, 43 }, { 247, 44 }, { 223, 45 },
 		{ 255, 46 }
 	};
+	private Dictionary<WaveType, string> waveTypeNames = new Dictionary<WaveType, string>()
+	{
+		{ WaveType.Common, "正常" },
+		{ WaveType.Tower, "塔波" },
+		{ WaveType.FromTower, "根据塔血量出" },
+	};
+
 
 	#endregion
 	// ----------------------------------------------------------------------------------------------------------------
@@ -628,7 +634,7 @@ public class GameMapEditor : EditorWindow
 			r.x = r.xMax - 200f; r.width = 100f; r.height = 15f;
             if (GUI.Button(r, GC_ExcelSave))
             {
-				ReloadSheetName(createEnemyExcelPath);
+				ReloadSheetName(createEnemyExcelPath,dynamicEnemyExcelPath,true);
 				mapsPopup.Asset = asset;
 				mapsPopup.isSelect = false;
 				mapsPopup.OnMapSelected = OnMapSelected;
@@ -637,7 +643,7 @@ public class GameMapEditor : EditorWindow
 			r.x = r.xMax; r.width = 100f; r.height = 15f;
 			if (GUI.Button(r, GC_MapSelect))
             {
-				ReloadSheetName(createEnemyExcelPath);
+				ReloadSheetName(createEnemyExcelPath, dynamicEnemyExcelPath);
 				mapsPopup.Asset = asset;
 				mapsPopup.isSelect = true;
 				mapsPopup.OnMapSelected = OnMapSelected;
@@ -708,38 +714,71 @@ public class GameMapEditor : EditorWindow
 		EditorGUILayout.EndVertical();
 	}
 
-	void ReloadSheetName(string path)
+	void ReloadSheetName(string path1, string path2, bool isSave = false)
     {
 		List<string> excelWorksheets = new();
-		FileInfo fileInfo = new FileInfo(path);
+		List<string> excelWorksheets1 = new();
+		FileInfo fileInfo = new FileInfo(path1);
 		using (ExcelPackage package = new ExcelPackage(fileInfo))
         {
 			excelWorksheets = ExcelEditor.ReadExcelSheetsInfo(package);
 		}
-			
+		fileInfo = new FileInfo(path2);
+		using (ExcelPackage package = new ExcelPackage(fileInfo))
+		{
+			excelWorksheets1 = ExcelEditor.ReadExcelSheetsInfo(package);
+		}
 		Tables allCfgData = new Tables(ExcelEditor.Loader);
 		List<SingleCreateEnemyConfig> cfgCreateEnemy = allCfgData.CfgCreateEnemy.DataList;
 		//导入关卡数据
-		if (mapIdx >= excelWorksheets.Count)
-		{
-			mapIdx = 0;
-		}
-		asset.maps[0] = asset.maps[mapIdx];
 		mapIdx = 0;
-		if (asset.maps.Count > excelWorksheets.Count)
+		for (int i = asset.maps.Count - 1; i > 0; i--)
 		{
-			for (int i = asset.maps.Count - 1; i > excelWorksheets.Count; i--)
+			asset.RemoveMapAtIndex(i);
+		}
+		asset.dynamicSheetStart = excelWorksheets.Count + 1;
+		if (isSave)
+        {
+            if (asset.maps[0].isDynamic)
+            {
+				for (int i = 1; i < excelWorksheets1.Count + 1; i++)
+				{
+					if (i >= asset.maps.Count)
+					{
+						asset.AddMap();
+					}
+					asset.maps[i].ident = excelWorksheets1[i - 1];
+				}
+			}else
+            {
+				for (int i = 1; i < excelWorksheets.Count + 1; i++)
+				{
+					if (i >= asset.maps.Count)
+					{
+						asset.AddMap();
+					}
+					asset.maps[i].ident = excelWorksheets[i - 1];
+				}
+			}
+        }
+        else
+        {
+			for (int i = 1; i < excelWorksheets.Count + 1; i++)
 			{
-				asset.RemoveMapAtIndex(i);
+				if (i >= asset.maps.Count)
+				{
+					asset.AddMap();
+				}
+				asset.maps[i].ident = excelWorksheets[i - 1];
 			}
-		}
-		for (int i = 1; i < excelWorksheets.Count + 1; i++)
-		{
-			if (i >= asset.maps.Count)
+			for (int i = asset.dynamicSheetStart; i < asset.dynamicSheetStart + excelWorksheets1.Count; i++)
 			{
-				asset.AddMap();
+				if (i >= asset.maps.Count)
+				{
+					asset.AddMap();
+				}
+				asset.maps[i].ident = excelWorksheets1[i - asset.dynamicSheetStart];
 			}
-			asset.maps[i].ident = excelWorksheets[i - 1];
 		}
 	}
 
@@ -953,23 +992,49 @@ public class GameMapEditor : EditorWindow
 
 		// 显示并编辑图层名称
 		EditorGUI.BeginChangeCheck();
-		string addName = EditorGUILayout.TextField("波次名称", layer.name);
+		string addName = EditorGUILayout.TextField("名称", layer.name);
 		int duration = 0;
 		string buildingId = "";
 		float buildingHp = 0;
-		bool isTowerWave = EditorGUILayout.ToggleLeft("塔波", layer.isTowerWave);
-		bool isFromTower = EditorGUILayout.ToggleLeft("根据塔血量出", layer.isFromTower);
-		if (layer.isFromTower)
+		string[] options = new string[]
 		{
-			buildingId = EditorGUILayout.TextField("出怪建筑", layer.buildingId);
-			buildingHp = EditorGUILayout.FloatField("剩余血量", layer.buildingHp);
-		}
-		else
-		{
-			duration = EditorGUILayout.IntField("下一波时间", layer.duration);
+			waveTypeNames[WaveType.Common],
+			waveTypeNames[WaveType.Tower],
+			waveTypeNames[WaveType.FromTower],
+		};
+		int selectedIndex = (int)layer.waveType;
+		WaveType waveType = WaveType.Common;
+		bool isDynamic = layer.isDynamic;
+		int dynamicSheet = 0;
+		if (!asset.maps[mapIdx].isDynamic)
+        {
+			selectedIndex = EditorGUILayout.Popup("种类", selectedIndex, options);
+			waveType = (WaveType)selectedIndex;
+			switch (layer.waveType)
+			{
+				case WaveType.Common:
+					duration = EditorGUILayout.IntField("下一波时间", layer.duration);
+					break;
+				case WaveType.Tower:
+					if (currLayer == 0)
+					{
+						duration = EditorGUILayout.IntField("下一波时间", layer.duration);
+					}
+					break;
+				case WaveType.FromTower:
+					buildingId = EditorGUILayout.TextField("出怪建筑", layer.buildingId);
+					buildingHp = EditorGUILayout.FloatField("剩余血量", layer.buildingHp);
+					break;
+			}
+			isDynamic = EditorGUILayout.ToggleLeft("动态", layer.isDynamic);
+			if (isDynamic)
+			{
+				dynamicSheet = EditorGUILayout.IntField("动态表", layer.dynamicSheet);
+			}
 		}
 
-		List<SpawnTime> newSpawnTimes = new List<SpawnTime>();
+
+		Dictionary<int, SpawnTime> newSpawnTimes = new();
 		EditorGUILayout.BeginVertical("box");
 		{
 			EditorGUILayout.LabelField("Spawn Times", EditorStyles.boldLabel);
@@ -982,39 +1047,39 @@ public class GameMapEditor : EditorWindow
 					continue;
                 }
 				SpawnTime spawnTime = new SpawnTime();
-				if (newSpawnTimes.Exists(x => x.id == grids[i]))
+                if (newSpawnTimes.ContainsKey(grids[i]))
                 {
-					spawnTime = newSpawnTimes.First(x => x.id == grids[i]);
+					spawnTime = newSpawnTimes[grids[i]];
 					spawnTime.pos.Add(i);
                 }
                 else
                 {
 					spawnTime.id = grids[i];
-					spawnTime.pos = new List<int> { i};
-					newSpawnTimes.Add(spawnTime);
+					spawnTime.pos = new List<int> { i };
+					newSpawnTimes.Add(grids[i], spawnTime);
                 }
 			}
 			
             if (newSpawnTimes.Count >= 1)
             {
-				for(int i = 0; i < newSpawnTimes.Count; i++)
+				Dictionary<int, SpawnTime> copyNewSpawnTime = new Dictionary<int, SpawnTime>(newSpawnTimes);
+				foreach(var item in copyNewSpawnTime)
                 {
-					SpawnTime newSpawnTime = newSpawnTimes[i];
-
+					SpawnTime newSpawnTime = item.Value;
 					EditorGUILayout.LabelField($"{asset.tileAsset.GetTile(newSpawnTime.id).name} - {newSpawnTime.pos.Count}", EditorStyles.boldLabel);
-					if (i >= layer.spawnTimes.Count)
+                    if (layer.spawnTimes.ContainsKey(item.Key))
+                    {
+						newSpawnTime.startTime = EditorGUILayout.IntField("Start Time", layer.spawnTimes[item.Key].startTime);
+						newSpawnTime.endTime = EditorGUILayout.IntField("End Time", layer.spawnTimes[item.Key].endTime);
+						newSpawnTime.num = EditorGUILayout.IntField("Number", layer.spawnTimes[item.Key].num);
+                    }
+                    else
                     {
 						newSpawnTime.startTime = EditorGUILayout.IntField("Start Time", 0);
 						newSpawnTime.endTime = EditorGUILayout.IntField("End Time", 0);
 						newSpawnTime.num = EditorGUILayout.IntField("Number", 0);
 					}
-                    else
-                    {
-						newSpawnTime.startTime = EditorGUILayout.IntField("Start Time", layer.spawnTimes[i].startTime);
-						newSpawnTime.endTime = EditorGUILayout.IntField("End Time", layer.spawnTimes[i].endTime);
-						newSpawnTime.num = EditorGUILayout.IntField("Number", layer.spawnTimes[i].num);
-					}
-					
+
 					if (GUILayout.Button("Remove"))
 					{
 						for (int j = 0; j < newSpawnTime.pos.Count; j++)
@@ -1022,11 +1087,9 @@ public class GameMapEditor : EditorWindow
 							layer.grid[newSpawnTime.pos[j]] = -1;
 						}
 					}
-					newSpawnTimes[i] = newSpawnTime;
+					newSpawnTimes[item.Key] = newSpawnTime;
 				}
             }
-
-
         }
 		EditorGUILayout.EndVertical();
 
@@ -1036,12 +1099,13 @@ public class GameMapEditor : EditorWindow
 			Undo.RecordObject(asset, "Change Layer Information");
 			haveChangeGrid = false;
 			layer.name = addName;
-			layer.isFromTower = isFromTower;
 			layer.duration = duration;
 			layer.buildingId = buildingId;
 			layer.buildingHp = buildingHp;
-			layer.isTowerWave = isTowerWave;
 			layer.spawnTimes = newSpawnTimes;
+			layer.waveType = waveType;
+			layer.isDynamic = isDynamic;
+			layer.dynamicSheet = dynamicSheet;
 			AssetDatabase.SaveAssets();
 		}
 		// 标记资源为脏数据,以便保存更改
@@ -1050,7 +1114,6 @@ public class GameMapEditor : EditorWindow
 		//EditorGUILayout.LabelField($"Grid Size: {layer.gridSize}");
 		//EditorGUILayout.LabelField($"Is Visible: {layer.isVisible}");
 	}
-
 	private void DrawTileProperties(Event ev)
 	{
 		if (asset == null || asset.tileAsset == null || tilesEd == null) return;
@@ -1143,7 +1206,7 @@ public class GameMapEditor : EditorWindow
 				r.width = 60;
 				if (GUI.Button(r, GC_save, EditorStyles.miniButton))
 				{
-					SaveToEnemyExcel(enemyExcelPath);
+					SaveToEnemyExcel();
 				}
 			}
 
@@ -1262,7 +1325,6 @@ public class GameMapEditor : EditorWindow
 				tileCache.Add(def.id, def);
 				id++;
 			}
-
 			for (int i = 0; i < 100; i++)
 			{
 				foreach (var sheetName in excelsSheets)
@@ -1274,48 +1336,66 @@ public class GameMapEditor : EditorWindow
 			package.Save();
 		}
 
-
-
-
-
 		doRepaint = true;
 		Debug.Log("怪物表数据导入完毕!");
 	}
 
 	//保存怪物表
-	void SaveToEnemyExcel(string path)
+	void SaveToEnemyExcel()
 	{
+		string path = enemyExcelPath;
 		List<string> excelsSheets = new();
-		FileInfo fileInfo = new FileInfo(createEnemyExcelPath);
-		using (ExcelPackage package = new ExcelPackage(fileInfo))
-		{
-			excelsSheets = ExcelEditor.ReadExcelSheetsInfo(package);
-			for (int i = 0; i < asset.tileAsset.tiles.Count; i++)
+		FileInfo fileInfo = null;
+		for (int j = 0; j < 2; j++)
+        {
+            switch (j)
+            {
+				case 0:
+					fileInfo = new FileInfo(createEnemyExcelPath);
+					break;
+				case 1:
+					fileInfo = new FileInfo(dynamicEnemyExcelPath);
+					break;
+            }
+			using (ExcelPackage package = new ExcelPackage(fileInfo))
 			{
-				GameMapTile tile = asset.tileAsset.tiles[i];
-				foreach (var sheetName in excelsSheets)
+				excelsSheets = ExcelEditor.ReadExcelSheetsInfo(package);
+				for (int i = 0; i < asset.tileAsset.tiles.Count; i++)
+				{
+					GameMapTile tile = asset.tileAsset.tiles[i];
+					foreach (var sheetName in excelsSheets)
+					{
+						ExcelEditor.ModifyExcel(package, sheetName, 7, 3 + i, tile.name);
+					}
+				}
+				for (int i = 0; i < 100; i++)
 				{
-					ExcelEditor.ModifyExcel(package, sheetName, 7, 3 + i, tile.name);
+					foreach (var sheetName in excelsSheets)
+					{
+						ExcelEditor.ModifyExcel(package, sheetName, 7, 3 + asset.tileAsset.tiles.Count + i, "");
+					}
 				}
-			}
-			for (int i = 0; i < 100; i++)
-			{
-				foreach (var sheetName in excelsSheets)
+				try
 				{
-					ExcelEditor.ModifyExcel(package, sheetName, 7, 3 + asset.tileAsset.tiles.Count + i, "");
-                }
-            }
-            try
-            {
-				package.Save();
-			}
-            catch (System.InvalidOperationException e)
-            {
-				Debug.LogError($"出怪表未关闭请重试");
-				Debug.LogException(e);
-				return;
+					package.Save();
+				}
+				catch (System.InvalidOperationException e)
+				{
+                    switch (j)
+                    {
+						case 0:
+							Debug.LogError($"出怪表未关闭请重试");
+							break;
+						case 1:
+							Debug.LogError($"动态出怪表未关闭请重试");
+							break;
+                    }
+					Debug.LogException(e);
+					return;
+				}
 			}
 		}
+
 		fileInfo = new FileInfo(path);
 		using (ExcelPackage package = new ExcelPackage(fileInfo))
         {

+ 2 - 2
ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/GameMap.cs

@@ -1,5 +1,4 @@
-using System.Collections.Generic;
-using UnityEngine;
+using UnityEngine;
 
 
 /// <summary>
@@ -21,6 +20,7 @@ public class GameMap
 	/// <summary> height of map (determines how big grid is) </summary>
 	public int height;
 
+	public bool isDynamic;
 	/// <summary> The grid/map. -1 is an empty tile, else a value related to GameMapTile.id will be present 
     /// This is also known as layer-0 or the default layer when there are movethan one layer in the map.
     /// </summary>

+ 14 - 6
ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/GameMapLayer.cs

@@ -1,6 +1,9 @@
-using System;
+using Sirenix.OdinInspector;
+using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using UnityEngine;
+
 [Serializable]
 public struct SpawnTime
 {
@@ -14,6 +17,12 @@ public struct SpawnTime
 	[HideInInspector] public float attack;
 }
 
+public enum WaveType
+{
+	Common = 0,		//正常
+	Tower = 1,		//塔波
+	FromTower = 2,	//根据塔血量出
+}
 /// <summary>
 /// A layer consists of a series of values in a grid.
 /// Each GameMap can have one or more layers.
@@ -23,14 +32,13 @@ public class GameMapLayer
 {
 	/// <summary> The layer's grid of tile values. -1 is an empty tile, else a value related to GameMapTile.id will be present </summary>
 	public int[] grid = new int[0];
-	public bool isTowerWave;
-	public bool isFromTower;
 	public int duration;
 	public string buildingId;
 	public float buildingHp;
 	public string name;
-	public List<SpawnTime> spawnTimes = new List<SpawnTime>();
-
-
+	public Dictionary<int, SpawnTime> spawnTimes = new();
+	public WaveType waveType;
+	public bool isDynamic;
+	public int dynamicSheet;
 	// ----------------------------------------------------------------------------------------------------------------
 }

+ 1 - 3
ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/GameMapsAsset.cs

@@ -1,14 +1,12 @@
 using System.Collections.Generic;
 using UnityEngine;
 
-
-/// <summary> Container for all defined maps. It also holds a reference the defined tiles. </summary>
 [System.Serializable]
 public class GameMapsAsset : ScriptableObject
 {
 	/// <summary> All maps created via MapEditor </summary>	
 	[SerializeField] public List<GameMap> maps = new List<GameMap>();
-
+	[DisplayOnly]public int dynamicSheetStart;
 	/// <summary> The tiles asset associated with the maps </summary>	
 	[SerializeField] public GameMapTilesAsset tileAsset;
 

+ 0 - 65
ActionTowerDefense/Assets/Gen/CfgBuilding.cs

@@ -1,65 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-using Bright.Serialization;
-using System.Collections.Generic;
-using SimpleJSON;
-
-
-
-namespace cfg
-{ 
-
-public sealed partial class CfgBuilding
-{
-    private readonly Dictionary<int, SingleBuildingConfig> _dataMap;
-    private readonly List<SingleBuildingConfig> _dataList;
-    
-    public CfgBuilding(JSONNode _json)
-    {
-        _dataMap = new Dictionary<int, SingleBuildingConfig>();
-        _dataList = new List<SingleBuildingConfig>();
-        
-        foreach(JSONNode _row in _json.Children)
-        {
-            var _v = SingleBuildingConfig.DeserializeSingleBuildingConfig(_row);
-            _dataList.Add(_v);
-            _dataMap.Add(_v.ID, _v);
-        }
-        PostInit();
-    }
-
-    public Dictionary<int, SingleBuildingConfig> DataMap => _dataMap;
-    public List<SingleBuildingConfig> DataList => _dataList;
-
-    public SingleBuildingConfig GetOrDefault(int key) => _dataMap.TryGetValue(key, out var v) ? v : null;
-    public SingleBuildingConfig Get(int key) => _dataMap[key];
-    public SingleBuildingConfig this[int key] => _dataMap[key];
-
-    public void Resolve(Dictionary<string, object> _tables)
-    {
-        foreach(var v in _dataList)
-        {
-            v.Resolve(_tables);
-        }
-        PostResolve();
-    }
-
-    public void TranslateText(System.Func<string, string, string> translator)
-    {
-        foreach(var v in _dataList)
-        {
-            v.TranslateText(translator);
-        }
-    }
-    
-    
-    partial void PostInit();
-    partial void PostResolve();
-}
-
-}

+ 0 - 11
ActionTowerDefense/Assets/Gen/CfgCreateBuilding.cs.meta

@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 04efc1f3bb438a0408e88d6f8ad9cd05
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 

+ 6 - 6
ActionTowerDefense/Assets/Gen/CfgCreateBuilding.cs → ActionTowerDefense/Assets/Gen/CfgDynamicEnemy.cs

@@ -14,24 +14,24 @@ using SimpleJSON;
 namespace cfg
 { 
 
-public sealed partial class CfgCreateBuilding
+public sealed partial class CfgDynamicEnemy
 {
-    private readonly List<SingleCreateBuildingConfig> _dataList;
+    private readonly List<SingleDynamicEnemyConfig> _dataList;
     
 
-    public CfgCreateBuilding(JSONNode _json)
+    public CfgDynamicEnemy(JSONNode _json)
     {
-        _dataList = new List<SingleCreateBuildingConfig>();
+        _dataList = new List<SingleDynamicEnemyConfig>();
         
         foreach(JSONNode _row in _json.Children)
         {
-            var _v = SingleCreateBuildingConfig.DeserializeSingleCreateBuildingConfig(_row);
+            var _v = SingleDynamicEnemyConfig.DeserializeSingleDynamicEnemyConfig(_row);
             _dataList.Add(_v);
         }
         PostInit();
     }
 
-    public List<SingleCreateBuildingConfig> DataList => _dataList;
+    public List<SingleDynamicEnemyConfig> DataList => _dataList;
 
 
     public void Resolve(Dictionary<string, object> _tables)

+ 1 - 1
ActionTowerDefense/Assets/Gen/SingleBuildingConfig.cs.meta → ActionTowerDefense/Assets/Gen/CfgDynamicEnemy.cs.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 86a0098ff0f01da489a0f457c793fb18
+guid: bc2b87c48bddd4b418bbf4e0d7e2c473
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2

+ 0 - 84
ActionTowerDefense/Assets/Gen/SingleBuildingConfig.cs

@@ -1,84 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-using Bright.Serialization;
-using System.Collections.Generic;
-using SimpleJSON;
-
-
-
-namespace cfg
-{ 
-
-public sealed partial class SingleBuildingConfig :  Bright.Config.BeanBase 
-{
-    public SingleBuildingConfig(JSONNode _json) 
-    {
-        { if(!_json["ID"].IsNumber) { throw new SerializationException(); }  ID = _json["ID"]; }
-        { if(!_json["BuildingPrefab"].IsString) { throw new SerializationException(); }  BuildingPrefab = _json["BuildingPrefab"]; }
-        { if(!_json["HP"].IsNumber) { throw new SerializationException(); }  HP = _json["HP"]; }
-        { if(!_json["Attack"].IsNumber) { throw new SerializationException(); }  Attack = _json["Attack"]; }
-        PostInit();
-    }
-
-    public SingleBuildingConfig(int ID, string BuildingPrefab, int HP, int Attack ) 
-    {
-        this.ID = ID;
-        this.BuildingPrefab = BuildingPrefab;
-        this.HP = HP;
-        this.Attack = Attack;
-        PostInit();
-    }
-
-    public static SingleBuildingConfig DeserializeSingleBuildingConfig(JSONNode _json)
-    {
-        return new SingleBuildingConfig(_json);
-    }
-
-    /// <summary>
-    /// 建筑ID
-    /// </summary>
-    public int ID { get; private set; }
-    /// <summary>
-    /// 建筑Prefab
-    /// </summary>
-    public string BuildingPrefab { get; private set; }
-    /// <summary>
-    /// 基础血量
-    /// </summary>
-    public int HP { get; private set; }
-    /// <summary>
-    /// 攻击力
-    /// </summary>
-    public int Attack { get; private set; }
-
-    public const int __ID__ = -760344162;
-    public override int GetTypeId() => __ID__;
-
-    public  void Resolve(Dictionary<string, object> _tables)
-    {
-        PostResolve();
-    }
-
-    public  void TranslateText(System.Func<string, string, string> translator)
-    {
-    }
-
-    public override string ToString()
-    {
-        return "{ "
-        + "ID:" + ID + ","
-        + "BuildingPrefab:" + BuildingPrefab + ","
-        + "HP:" + HP + ","
-        + "Attack:" + Attack + ","
-        + "}";
-    }
-    
-    partial void PostInit();
-    partial void PostResolve();
-}
-}

+ 0 - 161
ActionTowerDefense/Assets/Gen/SingleCreateBuildingConfig.cs

@@ -1,161 +0,0 @@
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
-using Bright.Serialization;
-using System.Collections.Generic;
-using SimpleJSON;
-
-
-
-namespace cfg
-{ 
-
-public sealed partial class SingleCreateBuildingConfig :  Bright.Config.BeanBase 
-{
-    public SingleCreateBuildingConfig(JSONNode _json) 
-    {
-        { if(!_json["LevelID"].IsNumber) { throw new SerializationException(); }  LevelID = _json["LevelID"]; }
-        { if(!_json["ID"].IsNumber) { throw new SerializationException(); }  ID = _json["ID"]; }
-        { if(!_json["BuildingID"].IsNumber) { throw new SerializationException(); }  BuildingID = _json["BuildingID"]; }
-        { if(!_json["PositionType"].IsNumber) { throw new SerializationException(); }  PositionType = _json["PositionType"]; }
-        { if(!_json["Type"].IsNumber) { throw new SerializationException(); }  Type = _json["Type"]; }
-        { if(!_json["Time"].IsNumber) { throw new SerializationException(); }  Time = _json["Time"]; }
-        { if(!_json["RefreshBuildingHP"].IsNumber) { throw new SerializationException(); }  RefreshBuildingHP = _json["RefreshBuildingHP"]; }
-        { if(!_json["DelayTime"].IsNumber) { throw new SerializationException(); }  DelayTime = _json["DelayTime"]; }
-        { if(!_json["RefreshBuildingID"].IsNumber) { throw new SerializationException(); }  RefreshBuildingID = _json["RefreshBuildingID"]; }
-        { var __json0 = _json["Position"]; if(!__json0.IsArray) { throw new SerializationException(); } Position = new System.Collections.Generic.List<float>(__json0.Count); foreach(JSONNode __e0 in __json0.Children) { float __v0;  { if(!__e0.IsNumber) { throw new SerializationException(); }  __v0 = __e0; }  Position.Add(__v0); }   }
-        { var __json0 = _json["Position1"]; if(!__json0.IsArray) { throw new SerializationException(); } Position1 = new System.Collections.Generic.List<float>(__json0.Count); foreach(JSONNode __e0 in __json0.Children) { float __v0;  { if(!__e0.IsNumber) { throw new SerializationException(); }  __v0 = __e0; }  Position1.Add(__v0); }   }
-        { var __json0 = _json["Scale"]; if(!__json0.IsArray) { throw new SerializationException(); } Scale = new System.Collections.Generic.List<float>(__json0.Count); foreach(JSONNode __e0 in __json0.Children) { float __v0;  { if(!__e0.IsNumber) { throw new SerializationException(); }  __v0 = __e0; }  Scale.Add(__v0); }   }
-        { if(!_json["AttackRatio"].IsNumber) { throw new SerializationException(); }  AttackRatio = _json["AttackRatio"]; }
-        { if(!_json["HPRatio"].IsNumber) { throw new SerializationException(); }  HPRatio = _json["HPRatio"]; }
-        { if(!_json["DisappearTime"].IsNumber) { throw new SerializationException(); }  DisappearTime = _json["DisappearTime"]; }
-        PostInit();
-    }
-
-    public SingleCreateBuildingConfig(int LevelID, int ID, int BuildingID, int PositionType, int Type, float Time, float RefreshBuildingHP, float DelayTime, int RefreshBuildingID, System.Collections.Generic.List<float> Position, System.Collections.Generic.List<float> Position1, System.Collections.Generic.List<float> Scale, float AttackRatio, float HPRatio, float DisappearTime ) 
-    {
-        this.LevelID = LevelID;
-        this.ID = ID;
-        this.BuildingID = BuildingID;
-        this.PositionType = PositionType;
-        this.Type = Type;
-        this.Time = Time;
-        this.RefreshBuildingHP = RefreshBuildingHP;
-        this.DelayTime = DelayTime;
-        this.RefreshBuildingID = RefreshBuildingID;
-        this.Position = Position;
-        this.Position1 = Position1;
-        this.Scale = Scale;
-        this.AttackRatio = AttackRatio;
-        this.HPRatio = HPRatio;
-        this.DisappearTime = DisappearTime;
-        PostInit();
-    }
-
-    public static SingleCreateBuildingConfig DeserializeSingleCreateBuildingConfig(JSONNode _json)
-    {
-        return new SingleCreateBuildingConfig(_json);
-    }
-
-    /// <summary>
-    /// 表格ID
-    /// </summary>
-    public int LevelID { get; private set; }
-    /// <summary>
-    /// 刷新批次
-    /// </summary>
-    public int ID { get; private set; }
-    /// <summary>
-    /// 建筑物ID
-    /// </summary>
-    public int BuildingID { get; private set; }
-    /// <summary>
-    /// 刷新建筑物位置类型<br/>(0:正常/1:建筑物)
-    /// </summary>
-    public int PositionType { get; private set; }
-    /// <summary>
-    /// 建筑物类型<br/>(0:传送门/1:敌方防御塔)
-    /// </summary>
-    public int Type { get; private set; }
-    /// <summary>
-    /// 刷新时间
-    /// </summary>
-    public float Time { get; private set; }
-    /// <summary>
-    /// 建筑物剩余多少血量时刷(%)
-    /// </summary>
-    public float RefreshBuildingHP { get; private set; }
-    /// <summary>
-    /// 延迟多少时间刷
-    /// </summary>
-    public float DelayTime { get; private set; }
-    /// <summary>
-    /// 建筑物批次
-    /// </summary>
-    public int RefreshBuildingID { get; private set; }
-    /// <summary>
-    /// 刷新位置
-    /// </summary>
-    public System.Collections.Generic.List<float> Position { get; private set; }
-    /// <summary>
-    /// 第二扇传送门刷新位置
-    /// </summary>
-    public System.Collections.Generic.List<float> Position1 { get; private set; }
-    /// <summary>
-    /// 传送门朝向<br/>(-1朝右,1朝左)
-    /// </summary>
-    public System.Collections.Generic.List<float> Scale { get; private set; }
-    /// <summary>
-    /// 攻击力倍率
-    /// </summary>
-    public float AttackRatio { get; private set; }
-    /// <summary>
-    /// 血量倍率
-    /// </summary>
-    public float HPRatio { get; private set; }
-    /// <summary>
-    /// 消失时间
-    /// </summary>
-    public float DisappearTime { get; private set; }
-
-    public const int __ID__ = 2141851578;
-    public override int GetTypeId() => __ID__;
-
-    public  void Resolve(Dictionary<string, object> _tables)
-    {
-        PostResolve();
-    }
-
-    public  void TranslateText(System.Func<string, string, string> translator)
-    {
-    }
-
-    public override string ToString()
-    {
-        return "{ "
-        + "LevelID:" + LevelID + ","
-        + "ID:" + ID + ","
-        + "BuildingID:" + BuildingID + ","
-        + "PositionType:" + PositionType + ","
-        + "Type:" + Type + ","
-        + "Time:" + Time + ","
-        + "RefreshBuildingHP:" + RefreshBuildingHP + ","
-        + "DelayTime:" + DelayTime + ","
-        + "RefreshBuildingID:" + RefreshBuildingID + ","
-        + "Position:" + Bright.Common.StringUtil.CollectionToString(Position) + ","
-        + "Position1:" + Bright.Common.StringUtil.CollectionToString(Position1) + ","
-        + "Scale:" + Bright.Common.StringUtil.CollectionToString(Scale) + ","
-        + "AttackRatio:" + AttackRatio + ","
-        + "HPRatio:" + HPRatio + ","
-        + "DisappearTime:" + DisappearTime + ","
-        + "}";
-    }
-    
-    partial void PostInit();
-    partial void PostResolve();
-}
-}

+ 0 - 11
ActionTowerDefense/Assets/Gen/SingleCreateBuildingConfig.cs.meta

@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 158001d519bcbd34c949e3d8f7f5d1a8
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 

+ 5 - 1
ActionTowerDefense/Assets/Gen/SingleCreateEnemyConfig.cs

@@ -20,6 +20,7 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
     {
         { if(!_json["WaveID"].IsNumber) { throw new SerializationException(); }  WaveID = _json["WaveID"]; }
         { if(!_json["WaveName"].IsString) { throw new SerializationException(); }  WaveName = _json["WaveName"]; }
+        { if(!_json["Dynamic"].IsNumber) { throw new SerializationException(); }  Dynamic = _json["Dynamic"]; }
         { if(!_json["WaveTime"].IsNumber) { throw new SerializationException(); }  WaveTime = _json["WaveTime"]; }
         { if(!_json["BuildingID"].IsString) { throw new SerializationException(); }  BuildingID = _json["BuildingID"]; }
         { if(!_json["BuildingHP"].IsNumber) { throw new SerializationException(); }  BuildingHP = _json["BuildingHP"]; }
@@ -34,10 +35,11 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
         PostInit();
     }
 
-    public SingleCreateEnemyConfig(float WaveID, string WaveName, int WaveTime, string BuildingID, float BuildingHP, string EnemyName, System.Collections.Generic.List<int> Position, int StartTime, int EndTime, int Count, float AttackRatio, float SpeedRatio, float HPRatio ) 
+    public SingleCreateEnemyConfig(float WaveID, string WaveName, int Dynamic, int WaveTime, string BuildingID, float BuildingHP, string EnemyName, System.Collections.Generic.List<int> Position, int StartTime, int EndTime, int Count, float AttackRatio, float SpeedRatio, float HPRatio ) 
     {
         this.WaveID = WaveID;
         this.WaveName = WaveName;
+        this.Dynamic = Dynamic;
         this.WaveTime = WaveTime;
         this.BuildingID = BuildingID;
         this.BuildingHP = BuildingHP;
@@ -68,6 +70,7 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
     /// <summary>
     /// 140
     /// </summary>
+    public int Dynamic { get; private set; }
     public int WaveTime { get; private set; }
     public string BuildingID { get; private set; }
     public float BuildingHP { get; private set; }
@@ -97,6 +100,7 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
         return "{ "
         + "WaveID:" + WaveID + ","
         + "WaveName:" + WaveName + ","
+        + "Dynamic:" + Dynamic + ","
         + "WaveTime:" + WaveTime + ","
         + "BuildingID:" + BuildingID + ","
         + "BuildingHP:" + BuildingHP + ","

+ 105 - 0
ActionTowerDefense/Assets/Gen/SingleDynamicEnemyConfig.cs

@@ -0,0 +1,105 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+using Bright.Serialization;
+using System.Collections.Generic;
+using SimpleJSON;
+
+
+
+namespace cfg
+{ 
+
+public sealed partial class SingleDynamicEnemyConfig :  Bright.Config.BeanBase 
+{
+    public SingleDynamicEnemyConfig(JSONNode _json) 
+    {
+        { if(!_json["WaveID"].IsNumber) { throw new SerializationException(); }  WaveID = _json["WaveID"]; }
+        { if(!_json["WaveName"].IsString) { throw new SerializationException(); }  WaveName = _json["WaveName"]; }
+        { if(!_json["EnemyName"].IsString) { throw new SerializationException(); }  EnemyName = _json["EnemyName"]; }
+        { var __json0 = _json["Position"]; if(!__json0.IsArray) { throw new SerializationException(); } Position = new System.Collections.Generic.List<int>(__json0.Count); foreach(JSONNode __e0 in __json0.Children) { int __v0;  { if(!__e0.IsNumber) { throw new SerializationException(); }  __v0 = __e0; }  Position.Add(__v0); }   }
+        { if(!_json["StartTime"].IsNumber) { throw new SerializationException(); }  StartTime = _json["StartTime"]; }
+        { if(!_json["EndTime"].IsNumber) { throw new SerializationException(); }  EndTime = _json["EndTime"]; }
+        { if(!_json["Count"].IsNumber) { throw new SerializationException(); }  Count = _json["Count"]; }
+        { if(!_json["AttackRatio"].IsNumber) { throw new SerializationException(); }  AttackRatio = _json["AttackRatio"]; }
+        { if(!_json["SpeedRatio"].IsNumber) { throw new SerializationException(); }  SpeedRatio = _json["SpeedRatio"]; }
+        { if(!_json["HPRatio"].IsNumber) { throw new SerializationException(); }  HPRatio = _json["HPRatio"]; }
+        PostInit();
+    }
+
+    public SingleDynamicEnemyConfig(int WaveID, string WaveName, string EnemyName, System.Collections.Generic.List<int> Position, int StartTime, int EndTime, int Count, float AttackRatio, float SpeedRatio, float HPRatio ) 
+    {
+        this.WaveID = WaveID;
+        this.WaveName = WaveName;
+        this.EnemyName = EnemyName;
+        this.Position = Position;
+        this.StartTime = StartTime;
+        this.EndTime = EndTime;
+        this.Count = Count;
+        this.AttackRatio = AttackRatio;
+        this.SpeedRatio = SpeedRatio;
+        this.HPRatio = HPRatio;
+        PostInit();
+    }
+
+    public static SingleDynamicEnemyConfig DeserializeSingleDynamicEnemyConfig(JSONNode _json)
+    {
+        return new SingleDynamicEnemyConfig(_json);
+    }
+
+    /// <summary>
+    /// 表格参数:
+    /// </summary>
+    public int WaveID { get; private set; }
+    /// <summary>
+    /// 宽:
+    /// </summary>
+    public string WaveName { get; private set; }
+    /// <summary>
+    /// 140
+    /// </summary>
+    public string EnemyName { get; private set; }
+    public System.Collections.Generic.List<int> Position { get; private set; }
+    public int StartTime { get; private set; }
+    public int EndTime { get; private set; }
+    public int Count { get; private set; }
+    public float AttackRatio { get; private set; }
+    public float SpeedRatio { get; private set; }
+    public float HPRatio { get; private set; }
+
+    public const int __ID__ = 1939625395;
+    public override int GetTypeId() => __ID__;
+
+    public  void Resolve(Dictionary<string, object> _tables)
+    {
+        PostResolve();
+    }
+
+    public  void TranslateText(System.Func<string, string, string> translator)
+    {
+    }
+
+    public override string ToString()
+    {
+        return "{ "
+        + "WaveID:" + WaveID + ","
+        + "WaveName:" + WaveName + ","
+        + "EnemyName:" + EnemyName + ","
+        + "Position:" + Bright.Common.StringUtil.CollectionToString(Position) + ","
+        + "StartTime:" + StartTime + ","
+        + "EndTime:" + EndTime + ","
+        + "Count:" + Count + ","
+        + "AttackRatio:" + AttackRatio + ","
+        + "SpeedRatio:" + SpeedRatio + ","
+        + "HPRatio:" + HPRatio + ","
+        + "}";
+    }
+    
+    partial void PostInit();
+    partial void PostResolve();
+}
+}

+ 1 - 1
ActionTowerDefense/Assets/Gen/CfgBuilding.cs.meta → ActionTowerDefense/Assets/Gen/SingleDynamicEnemyConfig.cs.meta

@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 1a7ddf155e6aee643bd105cabc908268
+guid: 95a8caa39cf245a4a86d9e132bd42ae9
 MonoImporter:
   externalObjects: {}
   serializedVersion: 2

+ 5 - 10
ActionTowerDefense/Assets/Gen/Tables.cs

@@ -15,9 +15,8 @@ namespace cfg
 public sealed partial class Tables
 {
     public CfgEnemy CfgEnemy {get; }
-    public CfgBuilding CfgBuilding {get; }
     public CfgCreateEnemy CfgCreateEnemy {get; }
-    public CfgCreateBuilding CfgCreateBuilding {get; }
+    public CfgDynamicEnemy CfgDynamicEnemy {get; }
     public CfgSoldierLevel CfgSoldierLevel {get; }
 
     public Tables(System.Func<string, JSONNode> loader)
@@ -25,20 +24,17 @@ public sealed partial class Tables
         var tables = new System.Collections.Generic.Dictionary<string, object>();
         CfgEnemy = new CfgEnemy(loader("cfgenemy")); 
         tables.Add("CfgEnemy", CfgEnemy);
-        CfgBuilding = new CfgBuilding(loader("cfgbuilding")); 
-        tables.Add("CfgBuilding", CfgBuilding);
         CfgCreateEnemy = new CfgCreateEnemy(loader("cfgcreateenemy")); 
         tables.Add("CfgCreateEnemy", CfgCreateEnemy);
-        CfgCreateBuilding = new CfgCreateBuilding(loader("cfgcreatebuilding")); 
-        tables.Add("CfgCreateBuilding", CfgCreateBuilding);
+        CfgDynamicEnemy = new CfgDynamicEnemy(loader("cfgdynamicenemy")); 
+        tables.Add("CfgDynamicEnemy", CfgDynamicEnemy);
         CfgSoldierLevel = new CfgSoldierLevel(loader("cfgsoldierlevel")); 
         tables.Add("CfgSoldierLevel", CfgSoldierLevel);
         PostInit();
 
         CfgEnemy.Resolve(tables); 
-        CfgBuilding.Resolve(tables); 
         CfgCreateEnemy.Resolve(tables); 
-        CfgCreateBuilding.Resolve(tables); 
+        CfgDynamicEnemy.Resolve(tables); 
         CfgSoldierLevel.Resolve(tables); 
         PostResolve();
     }
@@ -46,9 +42,8 @@ public sealed partial class Tables
     public void TranslateText(System.Func<string, string, string> translator)
     {
         CfgEnemy.TranslateText(translator); 
-        CfgBuilding.TranslateText(translator); 
         CfgCreateEnemy.TranslateText(translator); 
-        CfgCreateBuilding.TranslateText(translator); 
+        CfgDynamicEnemy.TranslateText(translator); 
         CfgSoldierLevel.TranslateText(translator); 
     }
     

+ 213 - 7
ActionTowerDefense/Assets/Scripts/EnemyCreater.cs

@@ -1,16 +1,15 @@
-using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using cfg;
 using System.Threading.Tasks;
 using Base.Common;
-using System.Linq;
 using System.Threading;
 
 public class EnemyCreater : MonoBehaviour
 {
     private CancellationTokenSource _cancellationTokenSource;
     public static EnemyCreater instance;
+    public SoldierEXP soldierEXP;
     [SerializeField] public List<SingleCreateEnemyConfig> cfgCreateEnemy;
     public List<bool> createdEnemy;
     public List<List<float>> createEnemyTime = new();
@@ -21,6 +20,7 @@ public class EnemyCreater : MonoBehaviour
     public Dictionary<string, EnemyTower> enemyCreateTowerDic;
     public List<string> createdEnemyTower = new();
     public List<float> createdEnemyTowerHp = new();
+    public List<List<List<SingleDynamicEnemyConfig>>> cfgDynamicEnemy;
 
     private void Awake()
     {
@@ -36,6 +36,7 @@ public class EnemyCreater : MonoBehaviour
         enemyDic = new Dictionary<string, List<Enemy>>();
         buildingDic = new Dictionary<string, List<GameObject>>();
         enemyCreateTowerDic = new Dictionary<string, EnemyTower>();
+        soldierEXP = GetComponent<SoldierEXP>();
     }
 
     private void Start()
@@ -113,6 +114,24 @@ public class EnemyCreater : MonoBehaviour
             end = cfgCreateEnemy.Count - 1;
         }
         idRange = new Vector2Int(start, end);
+
+        List<SingleDynamicEnemyConfig> cfg = GameManager.instance.allCfgData.CfgDynamicEnemy.DataList;
+        cfgDynamicEnemy = new();
+        int sheet = -1;
+        for(int i = 0; i < cfg.Count; i++)
+        {
+            if(cfg[i].WaveID == -1)
+            {
+                sheet++;
+                cfgDynamicEnemy.Add(new List<List<SingleDynamicEnemyConfig>>());
+                for (int j = 0; j < 3; j++)
+                {
+                    cfgDynamicEnemy[sheet].Add(new List<SingleDynamicEnemyConfig>());
+                }
+                continue;
+            }
+            cfgDynamicEnemy[sheet][cfg[i].WaveID - 1].Add(cfg[i]);
+        }
         //把所有怪物prefab生成一遍防止后面初次生成卡顿
         //foreach (var item in createCharacter)
         //{
@@ -154,7 +173,18 @@ public class EnemyCreater : MonoBehaviour
                     if (createEnemyTime[id][0] <= gameTime)
                     {
                         createdEnemy[id] = true;
-                        StartCreateEnemy(cfgCreateEnemy[i]);
+                        if(cfgCreateEnemy[i].Dynamic == 0)
+                        {
+                            StartCreateEnemy(cfgCreateEnemy[i]);
+                        }
+                        else
+                        {
+                            int maxID = MaxSoldierLevel();
+                            foreach(var item in cfgDynamicEnemy[cfgCreateEnemy[i].Dynamic][maxID])
+                            {
+                                StartCreateEnemy(item);
+                            }
+                        }
                     }
                 }
             }
@@ -163,6 +193,57 @@ public class EnemyCreater : MonoBehaviour
 
     //每一行怪
     public async void StartCreateEnemy(SingleCreateEnemyConfig cfgCreateEnemy)
+    {
+        if (!instance)
+        {
+            return;
+        }
+        if(cfgCreateEnemy.Count == 0 || cfgCreateEnemy.Position.Count < 2)
+        {
+            return;
+        }
+        if (cfgCreateEnemy.Count == 1)
+        {
+            int randId = Random.Range(0, cfgCreateEnemy.Position.Count / 2 - 1);
+            Vector3 pos = new Vector3(cfgCreateEnemy.Position[randId * 2], cfgCreateEnemy.Position[randId * 2 + 1], 0);
+            CreateEnemy(cfgCreateEnemy, pos, true);
+            return;
+        }
+        int num1 = cfgCreateEnemy.Count / (cfgCreateEnemy.Position.Count / 2);
+        int num2 = cfgCreateEnemy.Count % (cfgCreateEnemy.Position.Count / 2);
+        float TimeInterval = cfgCreateEnemy.StartTime >= cfgCreateEnemy.EndTime
+            ? 0
+            : (float)(cfgCreateEnemy.EndTime - cfgCreateEnemy.StartTime) / (num2 == 0 ? num1 - 1 : num1);
+        for (int i = 0; i < num1; i++)
+        {
+            for (int j = 0; j < cfgCreateEnemy.Position.Count; j += 2)
+            {
+                Vector3 pos = new Vector3(cfgCreateEnemy.Position[j], cfgCreateEnemy.Position[j + 1], 0);
+                CreateEnemy(cfgCreateEnemy, pos, true);
+            }
+            try
+            {
+                await Task.Delay((int)(TimeInterval * 1000), _cancellationTokenSource.Token);
+            }
+            catch (TaskCanceledException)
+            {
+                return;
+            }
+
+        }
+        List<int> randomPos = new(cfgCreateEnemy.Position);
+        for (int i = 0; i < num2; i++)
+        {
+            int randId = Random.Range(0, randomPos.Count / 2 - 1);
+            Vector3 pos = new Vector3(randomPos[randId * 2], randomPos[randId * 2 + 1], 0);
+            randomPos.Remove(randId * 2 + 1);
+            randomPos.Remove(randId * 2);
+            CreateEnemy(cfgCreateEnemy, pos, true);
+        }
+    }
+
+    //动态每一行怪
+    public async void StartCreateEnemy(SingleDynamicEnemyConfig cfgCreateEnemy)
     {
         if (!instance)
         {
@@ -177,7 +258,7 @@ public class EnemyCreater : MonoBehaviour
         }
         int num1 = cfgCreateEnemy.Count / (cfgCreateEnemy.Position.Count / 2);
         int num2 = cfgCreateEnemy.Count % (cfgCreateEnemy.Position.Count / 2);
-        float TimeInterval = cfgCreateEnemy.StartTime >= cfgCreateEnemy.EndTime 
+        float TimeInterval = cfgCreateEnemy.StartTime >= cfgCreateEnemy.EndTime
             ? 0
             : (float)(cfgCreateEnemy.EndTime - cfgCreateEnemy.StartTime) / (num2 == 0 ? num1 - 1 : num1);
         for (int i = 0; i < num1; i++)
@@ -191,11 +272,11 @@ public class EnemyCreater : MonoBehaviour
             {
                 await Task.Delay((int)(TimeInterval * 1000), _cancellationTokenSource.Token);
             }
-            catch(TaskCanceledException)
+            catch (TaskCanceledException)
             {
                 return;
             }
-            
+
         }
         List<int> randomPos = new(cfgCreateEnemy.Position);
         for (int i = 0; i < num2; i++)
@@ -204,10 +285,61 @@ public class EnemyCreater : MonoBehaviour
             Vector3 pos = new Vector3(randomPos[randId * 2], randomPos[randId * 2 + 1], 0);
             randomPos.Remove(randId * 2 + 1);
             randomPos.Remove(randId * 2);
-            CreateEnemy(cfgCreateEnemy,pos, true);
+            CreateEnemy(cfgCreateEnemy, pos, true);
         }
     }
 
+    public int MaxSoldierLevel()
+    {
+        SoldierEXP.SingleSoldierEXP[] singleSoldierEXP = soldierEXP.ssexp;
+        if (singleSoldierEXP[0].level == singleSoldierEXP[1].level)
+        {
+            if (singleSoldierEXP[1].level == singleSoldierEXP[2].level)
+            {
+                return Random.Range(0, 3);
+            }
+            else
+            {
+                return Random.Range(0, 2);
+            }
+        }
+        else
+        {
+            if (singleSoldierEXP[1].level == singleSoldierEXP[2].level)
+            {
+                return Random.Range(1, 3);
+            }
+            else if (singleSoldierEXP[0].level == singleSoldierEXP[2].level)
+            {
+                return Random.Range(0, 2) == 0 ? 0 : 2;
+            }
+            else
+            {
+                if (singleSoldierEXP[1].level > singleSoldierEXP[0].level)
+                {
+                    if (singleSoldierEXP[2].level > singleSoldierEXP[1].level)
+                    {
+                        return 2;
+                    }
+                    else
+                    {
+                        return 1;
+                    }
+                }
+                else
+                {
+                    if (singleSoldierEXP[2].level > singleSoldierEXP[0].level)
+                    {
+                        return 2;
+                    }
+                    else
+                    {
+                        return 0;
+                    }
+                }
+            }
+        }
+    }
 
     public GameObject CreateEnemy(SingleCreateEnemyConfig cfgCreateEnemy, Vector3 pos, bool active = false)
     {
@@ -283,6 +415,80 @@ public class EnemyCreater : MonoBehaviour
         return enemyObj;
     }
 
+    public GameObject CreateEnemy(SingleDynamicEnemyConfig cfgCreateEnemy, Vector3 pos, bool active = false)
+    {
+        SingleEnemyConfig cfgEnemy = GameManager.instance.allCfgData.CfgEnemy.Get(cfgCreateEnemy.EnemyName);
+        string enemyStr = $"Prefab/{cfgEnemy.Type}/{cfgEnemy.EnemyPrefab}";
+        float posx = pos.x + Random.Range(-cfgEnemy.Radius[0], cfgEnemy.Radius[0]);
+        float posy = pos.y + Random.Range(-cfgEnemy.Radius[1], cfgEnemy.Radius[1]) - 1;
+        pos = new Vector3(posx, posy <= 0 ? 0 : posy, 0);
+        GameObject enemyObj = Util.Instantiate(enemyStr, pos, active: active);
+        AttackInfo attackInfo;
+        if (cfgEnemy.Type == "Tower")
+        {
+            EnemyTower enemyTower = enemyObj.GetComponent<EnemyTower>();
+            Tower tower = enemyObj.GetComponent<Tower>();
+            if (enemyTower != null)
+            {
+                enemyTower.name = cfgEnemy.Name;
+
+                enemyTower.totalHp = (int)(cfgEnemy.HP * cfgCreateEnemy.HPRatio);
+                enemyTower.hp = enemyTower.totalHp;
+
+                attackInfo = enemyTower.attackController.attackInfo;
+                attackInfo.damage = (int)(cfgEnemy.AttackMarch * cfgCreateEnemy.AttackRatio);
+                enemyTower.attackController.attackInfo = attackInfo;
+                enemyTower.Init();
+            }
+            if (tower != null)
+            {
+                tower.name = cfgEnemy.Name;
+
+                tower.totalHp = (int)(cfgEnemy.HP * cfgCreateEnemy.HPRatio);
+                tower.hp = tower.totalHp;
+
+                attackInfo = tower.attackController.attackInfo;
+                attackInfo.damage = (int)(cfgEnemy.AttackMarch * cfgCreateEnemy.AttackRatio);
+                tower.attackController.attackInfo = attackInfo;
+                tower.Init();
+            }
+            if (!buildingDic.ContainsKey(cfgEnemy.Name))
+            {
+                buildingDic.Add(cfgEnemy.Name, new List<GameObject>());
+            }
+            buildingDic[cfgEnemy.Name].Add(enemyObj);
+            enemyCreateTowerDic[cfgCreateEnemy.WaveName] = enemyTower;
+        }
+        else if (cfgEnemy.Type == "Enemy")
+        {
+            Enemy enemy = enemyObj.GetComponent<Enemy>();
+            enemy.name = cfgEnemy.Name;
+            if (!enemyDic.ContainsKey(cfgEnemy.Name))
+            {
+                enemyDic.Add(cfgEnemy.Name, new List<Enemy>());
+            }
+            enemyDic[cfgEnemy.Name].Add(enemy);
+
+            enemy.totalHp = (int)(cfgEnemy.HP * cfgCreateEnemy.HPRatio);
+            enemy.hp = enemy.totalHp;
+            enemy.minMoveSpeed = cfgEnemy.MinMoveSpeed * cfgCreateEnemy.SpeedRatio;
+            enemy.maxMoveSpeed = cfgEnemy.MaxMoveSpeed * cfgCreateEnemy.SpeedRatio;
+
+            attackInfo = enemy.attackController.attackMethod[0].attackInfo;
+            attackInfo.damage = (int)(cfgEnemy.AttackMarch * cfgCreateEnemy.AttackRatio);
+            enemy.attackController.attackMethod[0].attackInfo = attackInfo;
+
+            if (enemy.canFly)
+            {
+                enemy.flyHeight = enemy.transform.position.y;
+            }
+            enemy.Init();
+            enemy.SetSortingOrder(enemy.baseSortingOrder + enemyDic[cfgEnemy.Name].Count);
+        }
+        enemyObj.transform.position = pos;
+        return enemyObj;
+    }
+
     public void OnEnemyRecycle(Enemy enemy)
     {
         if (!enemyDic.ContainsKey(enemy.name))

+ 0 - 26
ActionTowerDefense/GenerateDatas/json/cfgbuilding.json

@@ -1,26 +0,0 @@
-[
-  {
-    "ID": 1,
-    "BuildingPrefab": "Prefab/Portal/Portals",
-    "HP": 1000,
-    "Attack": 0
-  },
-  {
-    "ID": 2,
-    "BuildingPrefab": "Prefab/Portal/Portals_Player",
-    "HP": 1000,
-    "Attack": 0
-  },
-  {
-    "ID": 3,
-    "BuildingPrefab": "Prefab/Portal/EnemyDoor",
-    "HP": 1000,
-    "Attack": 0
-  },
-  {
-    "ID": 4,
-    "BuildingPrefab": "Prefab/Tower/EnemyTower",
-    "HP": 10000,
-    "Attack": 1000
-  }
-]

+ 0 - 310
ActionTowerDefense/GenerateDatas/json/cfgcreatebuilding.json

@@ -1,310 +0,0 @@
-[
-  {
-    "LevelID": 1,
-    "ID": 6,
-    "BuildingID": 4,
-    "PositionType": 0,
-    "Type": 1,
-    "Time": 5,
-    "RefreshBuildingHP": 0,
-    "DelayTime": 0,
-    "RefreshBuildingID": 0,
-    "Position": [
-      5,
-      0,
-      0
-    ],
-    "Position1": [],
-    "Scale": [
-      -1,
-      1
-    ],
-    "AttackRatio": 2,
-    "HPRatio": 2,
-    "DisappearTime": 0
-  },
-  {
-    "LevelID": 2,
-    "ID": 5,
-    "BuildingID": 4,
-    "PositionType": 0,
-    "Type": 1,
-    "Time": 3,
-    "RefreshBuildingHP": 0,
-    "DelayTime": 0,
-    "RefreshBuildingID": 0,
-    "Position": [
-      30,
-      0,
-      0
-    ],
-    "Position1": [],
-    "Scale": [
-      -1,
-      1
-    ],
-    "AttackRatio": 1.5,
-    "HPRatio": 1.5,
-    "DisappearTime": 0
-  },
-  {
-    "LevelID": 2,
-    "ID": 6,
-    "BuildingID": 4,
-    "PositionType": 0,
-    "Type": 1,
-    "Time": 5,
-    "RefreshBuildingHP": 0,
-    "DelayTime": 0,
-    "RefreshBuildingID": 0,
-    "Position": [
-      5,
-      0,
-      0
-    ],
-    "Position1": [],
-    "Scale": [
-      -1,
-      1
-    ],
-    "AttackRatio": 2,
-    "HPRatio": 2,
-    "DisappearTime": 0
-  },
-  {
-    "LevelID": 3,
-    "ID": 4,
-    "BuildingID": 4,
-    "PositionType": 0,
-    "Type": 1,
-    "Time": 3,
-    "RefreshBuildingHP": 0,
-    "DelayTime": 0,
-    "RefreshBuildingID": 0,
-    "Position": [
-      60,
-      0,
-      3
-    ],
-    "Position1": [],
-    "Scale": [
-      -1,
-      1
-    ],
-    "AttackRatio": 1,
-    "HPRatio": 1,
-    "DisappearTime": 0
-  },
-  {
-    "LevelID": 3,
-    "ID": 5,
-    "BuildingID": 4,
-    "PositionType": 0,
-    "Type": 1,
-    "Time": 3,
-    "RefreshBuildingHP": 0,
-    "DelayTime": 0,
-    "RefreshBuildingID": 0,
-    "Position": [
-      30,
-      0,
-      3
-    ],
-    "Position1": [],
-    "Scale": [
-      -1,
-      1
-    ],
-    "AttackRatio": 1.5,
-    "HPRatio": 1.5,
-    "DisappearTime": 0
-  },
-  {
-    "LevelID": 3,
-    "ID": 6,
-    "BuildingID": 4,
-    "PositionType": 0,
-    "Type": 1,
-    "Time": 5,
-    "RefreshBuildingHP": 0,
-    "DelayTime": 0,
-    "RefreshBuildingID": 0,
-    "Position": [
-      5,
-      0,
-      3
-    ],
-    "Position1": [],
-    "Scale": [
-      -1,
-      1
-    ],
-    "AttackRatio": 2,
-    "HPRatio": 2,
-    "DisappearTime": 0
-  },
-  {
-    "LevelID": 4,
-    "ID": 4,
-    "BuildingID": 4,
-    "PositionType": 0,
-    "Type": 1,
-    "Time": 3,
-    "RefreshBuildingHP": 0,
-    "DelayTime": 0,
-    "RefreshBuildingID": 0,
-    "Position": [
-      60,
-      0,
-      0
-    ],
-    "Position1": [],
-    "Scale": [
-      -1,
-      1
-    ],
-    "AttackRatio": 1,
-    "HPRatio": 1,
-    "DisappearTime": 0
-  },
-  {
-    "LevelID": 4,
-    "ID": 5,
-    "BuildingID": 4,
-    "PositionType": 0,
-    "Type": 1,
-    "Time": 3,
-    "RefreshBuildingHP": 0,
-    "DelayTime": 0,
-    "RefreshBuildingID": 0,
-    "Position": [
-      30,
-      0,
-      0
-    ],
-    "Position1": [],
-    "Scale": [
-      -1,
-      1
-    ],
-    "AttackRatio": 1.5,
-    "HPRatio": 1.5,
-    "DisappearTime": 0
-  },
-  {
-    "LevelID": 4,
-    "ID": 6,
-    "BuildingID": 4,
-    "PositionType": 0,
-    "Type": 1,
-    "Time": 3,
-    "RefreshBuildingHP": 0,
-    "DelayTime": 0,
-    "RefreshBuildingID": 0,
-    "Position": [
-      5,
-      0,
-      0
-    ],
-    "Position1": [],
-    "Scale": [
-      -1,
-      1
-    ],
-    "AttackRatio": 2,
-    "HPRatio": 2,
-    "DisappearTime": 0
-  },
-  {
-    "LevelID": 4,
-    "ID": 7,
-    "BuildingID": 3,
-    "PositionType": 0,
-    "Type": 0,
-    "Time": 0,
-    "RefreshBuildingHP": 95,
-    "DelayTime": 0,
-    "RefreshBuildingID": 4,
-    "Position": [
-      70,
-      0,
-      0
-    ],
-    "Position1": [],
-    "Scale": [
-      1
-    ],
-    "AttackRatio": 1,
-    "HPRatio": 1,
-    "DisappearTime": 13
-  },
-  {
-    "LevelID": 4,
-    "ID": 8,
-    "BuildingID": 3,
-    "PositionType": 0,
-    "Type": 0,
-    "Time": 0,
-    "RefreshBuildingHP": 95,
-    "DelayTime": 0,
-    "RefreshBuildingID": 4,
-    "Position": [
-      100,
-      0,
-      0
-    ],
-    "Position1": [],
-    "Scale": [
-      1
-    ],
-    "AttackRatio": 1,
-    "HPRatio": 1,
-    "DisappearTime": 13
-  },
-  {
-    "LevelID": 4,
-    "ID": 9,
-    "BuildingID": 3,
-    "PositionType": 0,
-    "Type": 0,
-    "Time": 0,
-    "RefreshBuildingHP": 80,
-    "DelayTime": 0,
-    "RefreshBuildingID": 5,
-    "Position": [
-      40,
-      0,
-      0
-    ],
-    "Position1": [],
-    "Scale": [
-      1
-    ],
-    "AttackRatio": 1,
-    "HPRatio": 1,
-    "DisappearTime": 13
-  },
-  {
-    "LevelID": 4,
-    "ID": 10,
-    "BuildingID": 3,
-    "PositionType": 0,
-    "Type": 0,
-    "Time": 0,
-    "RefreshBuildingHP": 60,
-    "DelayTime": 0,
-    "RefreshBuildingID": 6,
-    "Position": [
-      15,
-      0,
-      0
-    ],
-    "Position1": [],
-    "Scale": [
-      1
-    ],
-    "AttackRatio": 1,
-    "HPRatio": 1,
-    "DisappearTime": 13
-  }
-]

File diff suppressed because it is too large
+ 3350 - 143
ActionTowerDefense/GenerateDatas/json/cfgcreateenemy.json


+ 95 - 0
ActionTowerDefense/GenerateDatas/json/cfgdynamicenemy.json

@@ -0,0 +1,95 @@
+[
+  {
+    "WaveID": -1,
+    "WaveName": "占位行",
+    "EnemyName": "",
+    "Position": [],
+    "StartTime": 0,
+    "EndTime": 0,
+    "Count": 0,
+    "AttackRatio": 0,
+    "SpeedRatio": 0,
+    "HPRatio": 0
+  },
+  {
+    "WaveID": 1,
+    "WaveName": "弓兵",
+    "EnemyName": "小猪",
+    "Position": [
+      1,
+      1,
+      3,
+      1
+    ],
+    "StartTime": 0,
+    "EndTime": 0,
+    "Count": 2,
+    "AttackRatio": 1,
+    "SpeedRatio": 1,
+    "HPRatio": 1
+  },
+  {
+    "WaveID": 1,
+    "WaveName": "",
+    "EnemyName": "小猪",
+    "Position": [
+      29,
+      1,
+      32,
+      1
+    ],
+    "StartTime": 0,
+    "EndTime": 0,
+    "Count": 2,
+    "AttackRatio": 1,
+    "SpeedRatio": 1,
+    "HPRatio": 1
+  },
+  {
+    "WaveID": 1,
+    "WaveName": "",
+    "EnemyName": "大猪",
+    "Position": [
+      60,
+      1,
+      62,
+      1
+    ],
+    "StartTime": 0,
+    "EndTime": 0,
+    "Count": 2,
+    "AttackRatio": 1,
+    "SpeedRatio": 1,
+    "HPRatio": 1
+  },
+  {
+    "WaveID": 2,
+    "WaveName": "胖子",
+    "EnemyName": "大猪",
+    "Position": [
+      4,
+      3
+    ],
+    "StartTime": 0,
+    "EndTime": 2,
+    "Count": 23,
+    "AttackRatio": 1,
+    "SpeedRatio": 1,
+    "HPRatio": 1
+  },
+  {
+    "WaveID": 3,
+    "WaveName": "棒子",
+    "EnemyName": "大猪",
+    "Position": [
+      59,
+      1
+    ],
+    "StartTime": 0,
+    "EndTime": 10,
+    "Count": 3,
+    "AttackRatio": 1,
+    "SpeedRatio": 1,
+    "HPRatio": 1
+  }
+]

BIN
ActionTowerDefense/Luban/Config/Datas/__tables__.xlsx


BIN
ActionTowerDefense/Luban/Config/Datas/出怪表.xlsx


BIN
ActionTowerDefense/Luban/Config/Datas/动态出怪表.xlsx


Some files were not shown because too many files changed in this diff