浏览代码

怪物表和编辑器同步成功

wgl 6 月之前
父节点
当前提交
7533fb4932

+ 69 - 19
ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/Editor/GameMapEdPopup.cs

@@ -5,6 +5,7 @@ using System.Collections.Generic;
 using cfg;
 using System;
 using System.IO;
+using OfficeOpenXml;
 
 public class GameMapEdPopup : PopupWindowContent
 {
@@ -107,44 +108,53 @@ public class GameMapEdPopup : PopupWindowContent
 	{
         if (isSelect)
         {
-			ReloadExcelData(GameMapEditor.enemyExcelPath, list.index);
+			ReloadExcelData(GameMapEditor.createEnemyExcelPath, list.index);
 			OnMapSelected(list.index);
         }
         else
         {
-			SaveExcelData(GameMapEditor.enemyExcelPath, list.index);
+			//SaveExcelData(GameMapEditor.createEnemyExcelPath, list.index);
         }
 		editorWindow.Close();
 	}
 
 	void SaveExcelData(string path, int mapIdx)
 	{
-		List<string> excelWorksheets = ExcelEditor.ReadExcelSheetsInfo(path);
+		List<string> excelWorksheets = new();
 		GameMap gameMap = GameMapEditor.asset.maps[GameMapEditor.mapIdx];
-
-		if(!ExcelEditor.RenameSheet(path, excelWorksheets[mapIdx], gameMap.showIdent))
-        {
-			return;
+		FileInfo fileInfo = new FileInfo(path);
+		using (ExcelPackage package = new ExcelPackage(fileInfo))
+		{
+			excelWorksheets = ExcelEditor.ReadExcelSheetsInfo(package);
+			if (!ExcelEditor.RenameSheet(package, excelWorksheets[mapIdx], gameMap.showIdent))
+			{
+				return;
+			}
+			ExcelEditor.ModifyExcel(package, gameMap.showIdent, "C6", GameMapEditor.mapSize_w.ToString());
+			ExcelEditor.ModifyExcel(package, gameMap.showIdent, "D6", GameMapEditor.mapSize_h.ToString());
+			package.Save();
 		}
-		ExcelEditor.ModifyExcel(path, gameMap.showIdent, "C6", GameMapEditor.mapSize_w.ToString());
-		ExcelEditor.ModifyExcel(path, gameMap.showIdent, "D6", GameMapEditor.mapSize_h.ToString());
-
-		Debug.Log($"\"{gameMap.showIdent}\"表保存成功!");
+		Debug.Log($"\"{gameMap.showIdent}\"表保存完毕!");
 		Debug.Log("记得运行\"gen_code_json.bat\"更新数据!");
 	}
 
-	public static void ReloadExcelData(string path, int mapIdx)
+	public void ReloadExcelData(string path, int mapIdx)
 	{
-		List<string> excelWorksheets = ExcelEditor.ReadExcelSheetsInfo(path);
+		List<string> excelWorksheets = new();
 		Tables allCfgData = new Tables(ExcelEditor.Loader);
 		List<SingleCreateEnemyConfig> cfgCreateEnemy = allCfgData.CfgCreateEnemy.DataList;
 		GameMap gameMap = GameMapEditor.asset.maps[mapIdx];
+		FileInfo fileInfo = new FileInfo(path);
+		using (ExcelPackage package = new ExcelPackage(fileInfo))
+		{
+			excelWorksheets = ExcelEditor.ReadExcelSheetsInfo(package);
 
-		//导入关卡数据
-		gameMap.showIdent = gameMap.ident;
-		int.TryParse(ExcelEditor.GetCellData(path, excelWorksheets[mapIdx], "C6"), out int width);
-		int.TryParse(ExcelEditor.GetCellData(path, excelWorksheets[mapIdx], "D6"), out int height);
-		gameMap.Resize(width, height);
+			//导入关卡数据
+			gameMap.showIdent = gameMap.ident;
+			int.TryParse(ExcelEditor.GetCellData(package, excelWorksheets[mapIdx], "C6"), out GameMapEditor.mapSize_w);
+			int.TryParse(ExcelEditor.GetCellData(package, excelWorksheets[mapIdx], "D6"), out GameMapEditor.mapSize_h);
+			gameMap.Resize(GameMapEditor.mapSize_w, GameMapEditor.mapSize_h);
+		}
 
 		//导入波次数据
 		GameMapEditor.currLayer = -1;
@@ -166,6 +176,7 @@ public class GameMapEdPopup : PopupWindowContent
             {
 				if (cfgCreateEnemy[i].WaveName != waveName)
 				{
+					//波次第一行的波次数据
 					SingleCreateEnemyConfig singleCreateEnemyConfig = cfgCreateEnemy[i];
 					waveName = singleCreateEnemyConfig.WaveName;
 					ArrayUtility.Add(ref gameMap.layers, new GameMapLayer());
@@ -176,6 +187,14 @@ public class GameMapEdPopup : PopupWindowContent
 					gameMapLayer.Hp = singleCreateEnemyConfig.HPRatio;
 					gameMapLayer.moveSpeed = singleCreateEnemyConfig.SpeedRatio;
 					gameMapLayer.attack = singleCreateEnemyConfig.AttackRatio;
+
+					//波次第一行怪物数据
+					ReloadEnemyInWave(gameMapLayer, cfgCreateEnemy[i]);
+				}
+                else
+                {
+					GameMapLayer gameMapLayer = gameMap.layers[gameMap.layers.Length - 1];
+					ReloadEnemyInWave(gameMapLayer, cfgCreateEnemy[i]);
 				}
 			}
             else
@@ -189,8 +208,39 @@ public class GameMapEdPopup : PopupWindowContent
 
 
 		doRepaint = true;
-		Debug.Log($"\"{excelWorksheets[mapIdx]}\"表导入成功!");
+		Debug.Log($"\"{excelWorksheets[mapIdx]}\"表导入完毕!");
 	}
 
+
+	public void ReloadEnemyInWave(GameMapLayer layer, SingleCreateEnemyConfig cfgData)
+    {
+		int spawnTimeId = layer.spawnTimes.FindIndex(x => GameMapEditor.asset.tileAsset.GetTile(x.id).name == cfgData.EnemyName);
+		if (layer.spawnTimes.Count == 0 || spawnTimeId == -1)
+        {
+			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)
+            {
+				Debug.LogError($"出怪表\"{cfgData.WaveName}\"中\"{cfgData.EnemyName}\"的Position格式错误");
+            }
+			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.startTime = cfgData.StartTime;
+			spawnTime.endTime = cfgData.EndTime;
+			spawnTime.num = cfgData.Count;
+
+			layer.spawnTimes.Add(spawnTime);
+        }
+        else
+        {
+			Debug.LogError($"波次中\"{cfgData.EnemyName}\"重复");
+        }
+    }
 	// ----------------------------------------------------------------------------------------------------------------
 }

+ 116 - 25
ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/Editor/GameMapEditor.cs

@@ -7,6 +7,7 @@ using System.Linq;
 using cfg;
 using SimpleJSON;
 using System.IO;
+using OfficeOpenXml;
 
 public class GameMapEditor : EditorWindow
 {
@@ -125,6 +126,7 @@ public class GameMapEditor : EditorWindow
 	private static readonly GUIContent GC_rename = new GUIContent("rename");
 	private static readonly GUIContent GC_apply = new GUIContent("apply");
 	private static readonly GUIContent GC_reload = new GUIContent("reload");
+	private static readonly GUIContent GC_save = new GUIContent("save");
 	private static readonly GUIContent GC_add = new GUIContent("+", "Add");
 	private static readonly GUIContent GC_rem = new GUIContent("-", "Remove selected");
 	private static readonly GUIContent GC_movL = new GUIContent("<", "Move selected");
@@ -703,7 +705,13 @@ public class GameMapEditor : EditorWindow
 
 	void ReloadSheetName(string path)
     {
-		List<string> excelWorksheets = ExcelEditor.ReadExcelSheetsInfo(path);
+		List<string> excelWorksheets = new();
+		FileInfo fileInfo = new FileInfo(path);
+		using (ExcelPackage package = new ExcelPackage(fileInfo))
+        {
+			excelWorksheets = ExcelEditor.ReadExcelSheetsInfo(package);
+		}
+			
 		Tables allCfgData = new Tables(ExcelEditor.Loader);
 		List<SingleCreateEnemyConfig> cfgCreateEnemy = allCfgData.CfgCreateEnemy.DataList;
 		//导入关卡数据
@@ -937,8 +945,7 @@ public class GameMapEditor : EditorWindow
 		// 显示并编辑图层名称
 		EditorGUI.BeginChangeCheck();
 		string addName = EditorGUILayout.TextField("波次名称", layer.name);
-		
-		int duration = EditorGUILayout.IntField("波次出怪时间", layer.duration);
+		int duration = EditorGUILayout.IntField("下一波时间", layer.duration);
 		float addHp = EditorGUILayout.FloatField("血量倍率", layer.Hp);
 		float addMoveSpeed = EditorGUILayout.FloatField("速度倍率", layer.moveSpeed);
 		float addAttack = EditorGUILayout.FloatField("攻击倍率", layer.attack);
@@ -1146,7 +1153,14 @@ public class GameMapEditor : EditorWindow
                 {
 					ReloadEnemyExcelData(enemyExcelPath);
 				}
-            }
+
+				r.x -= 65f;
+				r.width = 60;
+				if (GUI.Button(r, GC_save, EditorStyles.miniButton))
+				{
+					SaveToEnemyExcel(enemyExcelPath);
+				}
+			}
 
 			EditorGUI.BeginChangeCheck();
 			showTileProperties = EditorGUILayout.Foldout(showTileProperties, GC_TilesHead, true);
@@ -1213,6 +1227,7 @@ public class GameMapEditor : EditorWindow
 		DrawTileList(ev);
 	}
 
+	//读取怪物表数据
 	void ReloadEnemyExcelData(string path)
     {
 		for (int i = asset.tileAsset.tiles.Count - 1; i>=0 ; i--)
@@ -1227,32 +1242,108 @@ public class GameMapEditor : EditorWindow
 		tileIdx = -1;
 		Tables allCfgData = new Tables(ExcelEditor.Loader);
 		int id = 0;
-		foreach (var item in allCfgData.CfgEnemy.DataMap)
-        {
-			SingleEnemyConfig cfgEnemy = item.Value;
-			asset.tileAsset.AddTile();
-			GameMapTile tile = asset.tileAsset.tiles[asset.tileAsset.tiles.Count - 1];
 
-			Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>($"Assets/GameLevelEditor/Ui_Textures/{cfgEnemy.SpriteName}.png");
-			tile.name = cfgEnemy.Name;
-			foreach(var sheetName in ExcelEditor.ReadExcelSheetsInfo(createEnemyExcelPath))
-            {
-				ExcelEditor.ModifyExcel(createEnemyExcelPath, sheetName, 7, 3 + id, tile.name);
+		List<string> excelsSheets = new();
+		FileInfo fileInfo = new FileInfo(createEnemyExcelPath);
+		using (ExcelPackage package = new ExcelPackage(fileInfo))
+		{
+			excelsSheets = ExcelEditor.ReadExcelSheetsInfo(package);
+			foreach (var item in allCfgData.CfgEnemy.DataMap)
+			{
+				SingleEnemyConfig cfgEnemy = item.Value;
+				asset.tileAsset.AddTile();
+				GameMapTile tile = asset.tileAsset.tiles[asset.tileAsset.tiles.Count - 1];
+
+				Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>($"Assets/GameLevelEditor/Ui_Textures/{cfgEnemy.SpriteName}.png");
+				tile.name = cfgEnemy.Name;
+				foreach (var sheetName in excelsSheets)
+				{
+					ExcelEditor.ModifyExcel(package, sheetName, 7, 3 + id, tile.name);
+				}
 
+				tile.sprite = sprite;
+				ColorUtility.TryParseHtmlString(cfgEnemy.Color, out tile.color);
+				Enum.TryParse(cfgEnemy.Type, out tile.type);
+				Enum.TryParse(cfgEnemy.EnemyPrefab, out tile.ch);
+				tile.radius = new Vector2(cfgEnemy.Radius[0], cfgEnemy.Radius[1]);
+				tile.parameter.HP = cfgEnemy.HP;
+				tile.parameter.Attack_summon = cfgEnemy.AttackSummon;
+				tile.parameter.Attack_march = cfgEnemy.AttackMarch;
+				tile.parameter.MinMoveSpeed = cfgEnemy.MinMoveSpeed;
+				tile.parameter.MaxMoveSpeed = cfgEnemy.MaxMoveSpeed;
+
+				TileDef def = new TileDef() { id = tile.id };
+				UpdateCachedValues(def, tile, false);
+				tileCache.Add(def.id, def);
+				id++;
 			}
-			
-			tile.sprite = sprite;
-			ColorUtility.TryParseHtmlString(cfgEnemy.Color, out tile.color);
-			Enum.TryParse(cfgEnemy.Type, out tile.type);
-			Enum.TryParse(cfgEnemy.EnemyPrefab, out tile.ch);
-			
-			TileDef def = new TileDef() { id = tile.id };
-			UpdateCachedValues(def, tile, false);
-			tileCache.Add(def.id, def);
-			id++;
+
+			for (int i = 0; i < 100; i++)
+			{
+				foreach (var sheetName in excelsSheets)
+				{
+					ExcelEditor.ModifyExcel(package, sheetName, 7, 3 + id + i, "");
+				}
+			}
+
+			package.Save();
 		}
+
+
+
+
+
 		doRepaint = true;
-		Debug.Log("怪物表数据导入成功!");
+		Debug.Log("怪物表数据导入完毕!");
+	}
+
+	//保存怪物表
+	void SaveToEnemyExcel(string path)
+	{
+		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++)
+			{
+				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++)
+			{
+				foreach (var sheetName in excelsSheets)
+				{
+					ExcelEditor.ModifyExcel(package, sheetName, 7, 3 + asset.tileAsset.tiles.Count + i, "");
+				}
+			}
+			package.Save();
+		}
+		fileInfo = new FileInfo(path);
+		using (ExcelPackage package = new ExcelPackage(fileInfo))
+        {
+			for (int i = 0; i < asset.tileAsset.tiles.Count; i++)
+			{
+				GameMapTile tile = asset.tileAsset.tiles[i];
+				ExcelEditor.ModifyExcel(package, "CfgEnemy", $"B{8 + i}", tile.name);
+				ExcelEditor.ModifyExcel(package, "CfgEnemy", $"C{8 + i}", tile.sprite.name);
+				ExcelEditor.ModifyExcel(package, "CfgEnemy", $"D{8 + i}", $"#{ColorUtility.ToHtmlStringRGB(tile.color)}");
+				ExcelEditor.ModifyExcel(package, "CfgEnemy", $"E{8 + i}", Enum.GetName(typeof(GameMapTile.Type), tile.type));
+				ExcelEditor.ModifyExcel(package, "CfgEnemy", $"F{8 + i}", Enum.GetName(typeof(GameMapTile.CH), tile.ch));
+				ExcelEditor.ModifyExcel(package, "CfgEnemy", $"G{8 + i}", $"{tile.radius.x},{tile.radius.y}");
+				ExcelEditor.ModifyExcel(package, "CfgEnemy", $"H{8 + i}", tile.parameter.HP.ToString());
+				ExcelEditor.ModifyExcel(package, "CfgEnemy", $"I{8 + i}", tile.parameter.Attack_summon.ToString());
+				ExcelEditor.ModifyExcel(package, "CfgEnemy", $"J{8 + i}", tile.parameter.Attack_march.ToString());
+				ExcelEditor.ModifyExcel(package, "CfgEnemy", $"K{8 + i}", tile.parameter.MinMoveSpeed.ToString());
+				ExcelEditor.ModifyExcel(package, "CfgEnemy", $"L{8 + i}", tile.parameter.MaxMoveSpeed.ToString());
+			}
+			ExcelEditor.RemoveExcelRows(package, "CfgEnemy", 8 + asset.tileAsset.tiles.Count, 108 + asset.tileAsset.tiles.Count);
+			package.Save();
+		}
+		Debug.Log("怪物表数据保存完毕!");
 	}
 
 	private void OnAutoTileChange(int idx)

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

@@ -7,10 +7,10 @@ using System.Collections.Generic;
 public struct Parameter
 {
 	public int HP;
-	public float MinMoveSpeed;
-	public float MaxMoveSpeed;
 	public int Attack_summon;
 	public int Attack_march;
+	public float MinMoveSpeed;
+	public float MaxMoveSpeed;
 }
 
 

+ 25 - 37
ActionTowerDefense/Assets/Gen/SingleCreateEnemyConfig.cs

@@ -20,41 +20,35 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
     {
         { if(!_json["WaveName"].IsString) { throw new SerializationException(); }  WaveName = _json["WaveName"]; }
         { if(!_json["WaveTime"].IsNumber) { throw new SerializationException(); }  WaveTime = _json["WaveTime"]; }
+        { 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"]; }
         { 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["Type"].IsNumber) { throw new SerializationException(); }  Type = _json["Type"]; }
-        { if(!_json["Time"].IsNumber) { throw new SerializationException(); }  Time = _json["Time"]; }
         { if(!_json["BuildingHP"].IsNumber) { throw new SerializationException(); }  BuildingHP = _json["BuildingHP"]; }
-        { if(!_json["DelayTime"].IsNumber) { throw new SerializationException(); }  DelayTime = _json["DelayTime"]; }
-        { if(!_json["TimeInterval"].IsNumber) { throw new SerializationException(); }  TimeInterval = _json["TimeInterval"]; }
-        { 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); }   }
         { if(!_json["BuildingID"].IsNumber) { throw new SerializationException(); }  BuildingID = _json["BuildingID"]; }
-        { if(!_json["YRandomRange"].IsNumber) { throw new SerializationException(); }  YRandomRange = _json["YRandomRange"]; }
-        { if(!_json["ZRandomRange"].IsNumber) { throw new SerializationException(); }  ZRandomRange = _json["ZRandomRange"]; }
-        { 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 SingleCreateEnemyConfig(string WaveName, int WaveTime, string EnemyName, int Count, int Type, float Time, float BuildingHP, float DelayTime, float TimeInterval, System.Collections.Generic.List<float> Position, int BuildingID, float YRandomRange, float ZRandomRange, float AttackRatio, float SpeedRatio, float HPRatio ) 
+    public SingleCreateEnemyConfig(string WaveName, int WaveTime, float AttackRatio, float SpeedRatio, float HPRatio, string EnemyName, System.Collections.Generic.List<int> Position, int StartTime, int EndTime, int Count, int Type, float BuildingHP, int BuildingID ) 
     {
         this.WaveName = WaveName;
         this.WaveTime = WaveTime;
+        this.AttackRatio = AttackRatio;
+        this.SpeedRatio = SpeedRatio;
+        this.HPRatio = HPRatio;
         this.EnemyName = EnemyName;
+        this.Position = Position;
+        this.StartTime = StartTime;
+        this.EndTime = EndTime;
         this.Count = Count;
         this.Type = Type;
-        this.Time = Time;
         this.BuildingHP = BuildingHP;
-        this.DelayTime = DelayTime;
-        this.TimeInterval = TimeInterval;
-        this.Position = Position;
         this.BuildingID = BuildingID;
-        this.YRandomRange = YRandomRange;
-        this.ZRandomRange = ZRandomRange;
-        this.AttackRatio = AttackRatio;
-        this.SpeedRatio = SpeedRatio;
-        this.HPRatio = HPRatio;
         PostInit();
     }
 
@@ -74,20 +68,17 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
     /// <summary>
     /// 高
     /// </summary>
+    public float AttackRatio { get; private set; }
+    public float SpeedRatio { get; private set; }
+    public float HPRatio { get; private set; }
     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 int Type { get; private set; }
-    public float Time { get; private set; }
     public float BuildingHP { get; private set; }
-    public float DelayTime { get; private set; }
-    public float TimeInterval { get; private set; }
-    public System.Collections.Generic.List<float> Position { get; private set; }
     public int BuildingID { get; private set; }
-    public float YRandomRange { get; private set; }
-    public float ZRandomRange { 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__ = 691467974;
     public override int GetTypeId() => __ID__;
@@ -106,20 +97,17 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
         return "{ "
         + "WaveName:" + WaveName + ","
         + "WaveTime:" + WaveTime + ","
+        + "AttackRatio:" + AttackRatio + ","
+        + "SpeedRatio:" + SpeedRatio + ","
+        + "HPRatio:" + HPRatio + ","
         + "EnemyName:" + EnemyName + ","
+        + "Position:" + Bright.Common.StringUtil.CollectionToString(Position) + ","
+        + "StartTime:" + StartTime + ","
+        + "EndTime:" + EndTime + ","
         + "Count:" + Count + ","
         + "Type:" + Type + ","
-        + "Time:" + Time + ","
         + "BuildingHP:" + BuildingHP + ","
-        + "DelayTime:" + DelayTime + ","
-        + "TimeInterval:" + TimeInterval + ","
-        + "Position:" + Bright.Common.StringUtil.CollectionToString(Position) + ","
         + "BuildingID:" + BuildingID + ","
-        + "YRandomRange:" + YRandomRange + ","
-        + "ZRandomRange:" + ZRandomRange + ","
-        + "AttackRatio:" + AttackRatio + ","
-        + "SpeedRatio:" + SpeedRatio + ","
-        + "HPRatio:" + HPRatio + ","
         + "}";
     }
     

+ 13 - 9
ActionTowerDefense/Assets/Gen/SingleEnemyConfig.cs

@@ -23,24 +23,26 @@ public sealed partial class SingleEnemyConfig :  Bright.Config.BeanBase
         { if(!_json["Color"].IsString) { throw new SerializationException(); }  Color = _json["Color"]; }
         { if(!_json["Type"].IsString) { throw new SerializationException(); }  Type = _json["Type"]; }
         { if(!_json["EnemyPrefab"].IsString) { throw new SerializationException(); }  EnemyPrefab = _json["EnemyPrefab"]; }
+        { var __json0 = _json["Radius"]; if(!__json0.IsArray) { throw new SerializationException(); } Radius = new System.Collections.Generic.List<int>(__json0.Count); foreach(JSONNode __e0 in __json0.Children) { int __v0;  { if(!__e0.IsNumber) { throw new SerializationException(); }  __v0 = __e0; }  Radius.Add(__v0); }   }
         { if(!_json["HP"].IsNumber) { throw new SerializationException(); }  HP = _json["HP"]; }
-        { var __json0 = _json["Attack1"]; if(!__json0.IsArray) { throw new SerializationException(); } Attack1 = new System.Collections.Generic.List<int>(__json0.Count); foreach(JSONNode __e0 in __json0.Children) { int __v0;  { if(!__e0.IsNumber) { throw new SerializationException(); }  __v0 = __e0; }  Attack1.Add(__v0); }   }
-        { var __json0 = _json["Attack2"]; if(!__json0.IsArray) { throw new SerializationException(); } Attack2 = new System.Collections.Generic.List<int>(__json0.Count); foreach(JSONNode __e0 in __json0.Children) { int __v0;  { if(!__e0.IsNumber) { throw new SerializationException(); }  __v0 = __e0; }  Attack2.Add(__v0); }   }
+        { if(!_json["AttackSummon"].IsNumber) { throw new SerializationException(); }  AttackSummon = _json["AttackSummon"]; }
+        { if(!_json["AttackMarch"].IsNumber) { throw new SerializationException(); }  AttackMarch = _json["AttackMarch"]; }
         { if(!_json["MinMoveSpeed"].IsNumber) { throw new SerializationException(); }  MinMoveSpeed = _json["MinMoveSpeed"]; }
         { if(!_json["MaxMoveSpeed"].IsNumber) { throw new SerializationException(); }  MaxMoveSpeed = _json["MaxMoveSpeed"]; }
         PostInit();
     }
 
-    public SingleEnemyConfig(string Name, string SpriteName, string Color, string Type, string EnemyPrefab, int HP, System.Collections.Generic.List<int> Attack1, System.Collections.Generic.List<int> Attack2, float MinMoveSpeed, float MaxMoveSpeed ) 
+    public SingleEnemyConfig(string Name, string SpriteName, string Color, string Type, string EnemyPrefab, System.Collections.Generic.List<int> Radius, int HP, int AttackSummon, int AttackMarch, float MinMoveSpeed, float MaxMoveSpeed ) 
     {
         this.Name = Name;
         this.SpriteName = SpriteName;
         this.Color = Color;
         this.Type = Type;
         this.EnemyPrefab = EnemyPrefab;
+        this.Radius = Radius;
         this.HP = HP;
-        this.Attack1 = Attack1;
-        this.Attack2 = Attack2;
+        this.AttackSummon = AttackSummon;
+        this.AttackMarch = AttackMarch;
         this.MinMoveSpeed = MinMoveSpeed;
         this.MaxMoveSpeed = MaxMoveSpeed;
         PostInit();
@@ -65,9 +67,10 @@ public sealed partial class SingleEnemyConfig :  Bright.Config.BeanBase
     public string Color { get; private set; }
     public string Type { get; private set; }
     public string EnemyPrefab { get; private set; }
+    public System.Collections.Generic.List<int> Radius { get; private set; }
     public int HP { get; private set; }
-    public System.Collections.Generic.List<int> Attack1 { get; private set; }
-    public System.Collections.Generic.List<int> Attack2 { get; private set; }
+    public int AttackSummon { get; private set; }
+    public int AttackMarch { get; private set; }
     public float MinMoveSpeed { get; private set; }
     public float MaxMoveSpeed { get; private set; }
 
@@ -91,9 +94,10 @@ public sealed partial class SingleEnemyConfig :  Bright.Config.BeanBase
         + "Color:" + Color + ","
         + "Type:" + Type + ","
         + "EnemyPrefab:" + EnemyPrefab + ","
+        + "Radius:" + Bright.Common.StringUtil.CollectionToString(Radius) + ","
         + "HP:" + HP + ","
-        + "Attack1:" + Bright.Common.StringUtil.CollectionToString(Attack1) + ","
-        + "Attack2:" + Bright.Common.StringUtil.CollectionToString(Attack2) + ","
+        + "AttackSummon:" + AttackSummon + ","
+        + "AttackMarch:" + AttackMarch + ","
         + "MinMoveSpeed:" + MinMoveSpeed + ","
         + "MaxMoveSpeed:" + MaxMoveSpeed + ","
         + "}";

+ 99 - 131
ActionTowerDefense/Assets/Scripts/ExcelEditor.cs

@@ -6,168 +6,136 @@ using System.IO;
 using System;
 using SimpleJSON;
 
+/*使用方法
+
+    using OfficeOpenXml;
+    FileInfo fileInfo = new FileInfo(filePath);
+    using (ExcelPackage package = new ExcelPackage(fileInfo))
+    {
+        ...
+        脚本A(package);
+        脚本B(package);
+        ...
+        package.Save(); //如果要保存就加这一行(记得关闭excel!!!)
+    }
+
+使用方法*/
 public class ExcelEditor
 {
     //获取所有Sheet名称
-	public static List<string> ReadExcelSheetsInfo(string filePath)
+	public static List<string> ReadExcelSheetsInfo(ExcelPackage package)
 	{
-		FileInfo fileInfo = new FileInfo(filePath);
-		using (ExcelPackage package = new ExcelPackage(fileInfo))
-		{
-			// 获取Sheet数量
-			int sheetCount = package.Workbook.Worksheets.Count;
-			// 获取所有Sheet名称
-			List<string> sheetNames = new List<string>();
-			foreach (ExcelWorksheet worksheet in package.Workbook.Worksheets)
-			{
-				sheetNames.Add(worksheet.Name);
-			}
-			return sheetNames;
-		}
-	}
+        // 获取Sheet数量
+        int sheetCount = package.Workbook.Worksheets.Count;
+        // 获取所有Sheet名称
+        List<string> sheetNames = new List<string>();
+        foreach (ExcelWorksheet worksheet in package.Workbook.Worksheets)
+        {
+            sheetNames.Add(worksheet.Name);
+        }
+        return sheetNames;
+    }
 
     //修改Sheet名称
-    public static bool RenameSheet(string filePath, string oldSheetName, string newSheetName)
+    public static bool RenameSheet(ExcelPackage package, string oldSheetName, string newSheetName)
     {
-        FileInfo fileInfo = new FileInfo(filePath);
-
-        using (ExcelPackage package = new ExcelPackage(fileInfo))
+        try
         {
-            try
-            {
-                ExcelWorksheet worksheet = package.Workbook.Worksheets[oldSheetName];
-                worksheet.Name = newSheetName;
-                package.Save();
-                Debug.Log($"成功修改Sheet名\"{oldSheetName}\"为\"{newSheetName}\"");
-                return true;
-            }
-            catch (System.InvalidOperationException e)
-            {
-                Debug.LogError($"请关闭Excel后重试");
-                return false;
-            }
-            catch (System.ArgumentException)
-            {
-                Debug.LogError($"Sheet名重复请重试");
-                return false;
-            }
-            catch (System.Exception e)
-            {
-                Debug.Log(e.GetType());
-                Debug.LogException(e);
-                return false;
-            }
+            ExcelWorksheet worksheet = package.Workbook.Worksheets[oldSheetName];
+            worksheet.Name = newSheetName;
+            Debug.Log($"修改Sheet名\"{oldSheetName}\"为\"{newSheetName}\"");
+            return true;
+        }
+        catch (System.InvalidOperationException e)
+        {
+            Debug.LogError($"请关闭Excel后重试");
+            return false;
+        }
+        catch (System.ArgumentException)
+        {
+            Debug.LogError($"Sheet名重复请重试");
+            return false;
+        }
+        catch (System.Exception e)
+        {
+            Debug.Log(e.GetType());
+            Debug.LogException(e);
+            return false;
         }
     }
 
     //获取excel数据
-    public static string GetCellData(string filePath, string sheetName, string cellId)
+    public static string GetCellData(ExcelPackage package, string sheetName, string cellId)
     {
-        FileInfo fileInfo = new FileInfo(filePath);
-
-        using (ExcelPackage package = new ExcelPackage(fileInfo))
-        {
-            ExcelWorksheet worksheet = package.Workbook.Worksheets[sheetName];
-            var value = worksheet.Cells[cellId].Value;
-            return value?.ToString() ?? string.Empty;
-        }
+        ExcelWorksheet worksheet = package.Workbook.Worksheets[sheetName];
+        var value = worksheet.Cells[cellId].Value;
+        return value?.ToString() ?? string.Empty;
     }
 
     //修改excel文件(地址索引)
-    public static bool ModifyExcel(string filePath, string sheetMame, string cellId, string newData)
+    public static bool ModifyExcel(ExcelPackage package, string sheetMame, string cellId, string newData)
     {
-        FileInfo fileInfo = new FileInfo(filePath);
-
-
-        using (ExcelPackage package = new ExcelPackage(fileInfo))
+        try
         {
-            try
-            {
-                ExcelWorksheet worksheet = package.Workbook.Worksheets[sheetMame];
-                worksheet.Cells[cellId].Value = newData; // 通过单元格地址
-                package.Save();
-                return true;
-            }
-            catch (System.InvalidOperationException e)
-            {
-                Debug.LogError($"请关闭Excel后重试");
-                return false;
-            }
-            catch (System.Exception e)
-            {
-                Debug.LogException(e);
-                return false;
-            }
+            ExcelWorksheet worksheet = package.Workbook.Worksheets[sheetMame];
+            worksheet.Cells[cellId].Value = newData; // 通过单元格地址
+            return true;
+        }
+        catch (System.InvalidOperationException e)
+        {
+            Debug.LogError($"请关闭Excel后重试");
+            return false;
+        }
+        catch (System.Exception e)
+        {
+            Debug.LogException(e);
+            return false;
         }
     }
 
     //修改excel文件(行列索引)
-    public static bool ModifyExcel(string filePath, string sheetMame, int cell_row, int cell_column, string newData)
+    public static bool ModifyExcel(ExcelPackage package, string sheetMame, int cell_row, int cell_column, string newData)
     {
-        FileInfo fileInfo = new FileInfo(filePath);
-
-
-        using (ExcelPackage package = new ExcelPackage(fileInfo))
+        try
         {
-            try
-            {
-                ExcelWorksheet worksheet = package.Workbook.Worksheets[sheetMame];
-                worksheet.Cells[cell_row, cell_column].Value = newData; // 通过行列索引
-                package.Save();
-                return true;
-            }
-            catch (System.InvalidOperationException e)
-            {
-                Debug.LogError($"请关闭Excel后重试");
-                return false;
-            }
-            catch (System.Exception e)
-            {
-                Debug.LogException(e);
-                return false;
-            }
+            ExcelWorksheet worksheet = package.Workbook.Worksheets[sheetMame];
+            worksheet.Cells[cell_row, cell_column].Value = newData; // 通过行列索引
+            package.Save();
+            return true;
+        }
+        catch (System.InvalidOperationException e)
+        {
+            Debug.LogError($"请关闭Excel后重试");
+            return false;
+        }
+        catch (System.Exception e)
+        {
+            Debug.LogException(e);
+            return false;
         }
     }
 
-    //删除符合条件的几行数据
-    public static bool RemoveExcelRows(string filePath, string sheetMame, Func<ExcelWorksheet, int, bool> rowCondition)
+    //删除连续多行数据[start_row, end_row]
+    public static bool RemoveExcelRows(ExcelPackage package, string sheetMame, int start_row, int end_row)
     {
-        FileInfo fileInfo = new FileInfo(filePath);
-
-        using (ExcelPackage package = new ExcelPackage(fileInfo))
+        ExcelWorksheet worksheet = package.Workbook.Worksheets[sheetMame];
+        try
         {
-            ExcelWorksheet worksheet = package.Workbook.Worksheets[sheetMame];
-            int rowCount = worksheet.Dimension.Rows;
-            int deletedRows = 0;
-
-            try
+            for (int i = end_row; i >= start_row; i--)
             {
-                // 从最后一行开始遍历,避免索引问题
-                for (int row = rowCount; row >= 1; row--)
-                {
-                    if (rowCondition(worksheet, row))
-                    {
-                        worksheet.DeleteRow(row);
-                        deletedRows++;
-                    }
-                }
-
-                if (deletedRows > 0)
-                {
-                    package.Save();
-                }
-                return true;
-            }
-            catch (System.InvalidOperationException e)
-            {
-                Debug.LogError($"请关闭Excel后重试");
-                return false;
-            }
-            catch (System.Exception e)
-            {
-                Debug.LogException(e);
-                return false;
+                worksheet.DeleteRow(i);
             }
+            return true;
+        }
+        catch (System.InvalidOperationException e)
+        {
+            Debug.LogError($"请关闭Excel后重试");
+            return false;
+        }
+        catch (System.Exception e)
+        {
+            Debug.LogException(e);
+            return false;
         }
     }
 

+ 39 - 52
ActionTowerDefense/GenerateDatas/json/cfgcreateenemy.json

@@ -2,85 +2,72 @@
   {
     "WaveName": "占位行",
     "WaveTime": 0,
+    "AttackRatio": 0,
+    "SpeedRatio": 0,
+    "HPRatio": 0,
     "EnemyName": "",
+    "Position": [],
+    "StartTime": 0,
+    "EndTime": 0,
     "Count": 0,
     "Type": 0,
-    "Time": 0,
     "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 0,
-    "Position": [],
-    "BuildingID": 0,
-    "YRandomRange": 0,
-    "ZRandomRange": 0,
-    "AttackRatio": 0,
-    "SpeedRatio": 0,
-    "HPRatio": 0
+    "BuildingID": 0
   },
   {
     "WaveName": "1",
     "WaveTime": 0,
+    "AttackRatio": 1,
+    "SpeedRatio": 1,
+    "HPRatio": 1,
     "EnemyName": "小猪",
+    "Position": [
+      1,
+      1
+    ],
+    "StartTime": 0,
+    "EndTime": 0,
     "Count": 10,
     "Type": 0,
-    "Time": 5,
     "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 1,
-    "Position": [
-      20,
-      0,
-      0
-    ],
-    "BuildingID": 0,
-    "YRandomRange": 0,
-    "ZRandomRange": 0,
-    "AttackRatio": 1,
-    "SpeedRatio": 1,
-    "HPRatio": 1
+    "BuildingID": 0
   },
   {
     "WaveName": "2",
     "WaveTime": 0,
+    "AttackRatio": 2,
+    "SpeedRatio": 1,
+    "HPRatio": 1,
     "EnemyName": "飞胖",
+    "Position": [
+      1,
+      2,
+      2,
+      3
+    ],
+    "StartTime": 0,
+    "EndTime": 0,
     "Count": 10,
     "Type": 0,
-    "Time": 15,
     "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 1,
-    "Position": [
-      30,
-      0,
-      0
-    ],
-    "BuildingID": 0,
-    "YRandomRange": 4,
-    "ZRandomRange": 0,
-    "AttackRatio": 1,
-    "SpeedRatio": 1,
-    "HPRatio": 1
+    "BuildingID": 0
   },
   {
     "WaveName": "2",
     "WaveTime": 0,
+    "AttackRatio": 0,
+    "SpeedRatio": 0,
+    "HPRatio": 0,
     "EnemyName": "防御塔",
+    "Position": [
+      2,
+      2
+    ],
+    "StartTime": 0,
+    "EndTime": 0,
     "Count": 10,
     "Type": 0,
-    "Time": 15,
     "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 1,
-    "Position": [
-      30,
-      0,
-      0
-    ],
-    "BuildingID": 0,
-    "YRandomRange": 4,
-    "ZRandomRange": 0,
-    "AttackRatio": 1,
-    "SpeedRatio": 1,
-    "HPRatio": 1
+    "BuildingID": 0
   }
 ]

+ 79 - 63
ActionTowerDefense/GenerateDatas/json/cfgenemy.json

@@ -2,145 +2,161 @@
   {
     "Name": "防御塔",
     "SpriteName": "tower",
-    "Color": "#00ff00",
+    "Color": "#00FF00",
     "Type": "Tower",
     "EnemyPrefab": "Tower",
-    "HP": 250,
-    "Attack1": [
-      100
-    ],
-    "Attack2": [
-      100
+    "Radius": [
+      0,
+      0
     ],
+    "HP": 250,
+    "AttackSummon": 100,
+    "AttackMarch": 100,
     "MinMoveSpeed": 4,
     "MaxMoveSpeed": 6
   },
   {
     "Name": "敌方防御塔",
     "SpriteName": "tower",
-    "Color": "#ff0000",
+    "Color": "#FF0000",
     "Type": "Tower",
     "EnemyPrefab": "EnemyTower",
-    "HP": 250,
-    "Attack1": [
-      100
-    ],
-    "Attack2": [
-      100
+    "Radius": [
+      0,
+      0
     ],
+    "HP": 250,
+    "AttackSummon": 100,
+    "AttackMarch": 100,
     "MinMoveSpeed": 4,
     "MaxMoveSpeed": 6
   },
   {
     "Name": "小猪",
     "SpriteName": "1xiaozhu_icon",
-    "Color": "#ffffff",
+    "Color": "#FFFFFF",
     "Type": "Enemy",
     "EnemyPrefab": "Enemy_1001",
-    "HP": 250,
-    "Attack1": [
-      100
-    ],
-    "Attack2": [
-      100
+    "Radius": [
+      1,
+      1
     ],
+    "HP": 250,
+    "AttackSummon": 100,
+    "AttackMarch": 100,
     "MinMoveSpeed": 4,
     "MaxMoveSpeed": 6
   },
   {
     "Name": "道士",
     "SpriteName": "1daoshi_icon",
-    "Color": "#ffffff",
+    "Color": "#FFFFFF",
     "Type": "Enemy",
     "EnemyPrefab": "Enemy_1002",
-    "HP": 100,
-    "Attack1": [
-      40
-    ],
-    "Attack2": [
-      40
+    "Radius": [
+      1,
+      1
     ],
+    "HP": 100,
+    "AttackSummon": 40,
+    "AttackMarch": 40,
     "MinMoveSpeed": 4,
     "MaxMoveSpeed": 6
   },
   {
     "Name": "大猪",
     "SpriteName": "1bigpig_icon",
-    "Color": "#ffffff",
+    "Color": "#FFFFFF",
     "Type": "Enemy",
     "EnemyPrefab": "Enemy_1003",
-    "HP": 1000,
-    "Attack1": [
-      110
-    ],
-    "Attack2": [
-      110
+    "Radius": [
+      1,
+      1
     ],
+    "HP": 1000,
+    "AttackSummon": 110,
+    "AttackMarch": 110,
     "MinMoveSpeed": 1,
     "MaxMoveSpeed": 3
   },
   {
     "Name": "幽灵头",
     "SpriteName": "1ghost 1",
-    "Color": "#ffffff",
+    "Color": "#FFFFFF",
     "Type": "Enemy",
     "EnemyPrefab": "Enemy_1004",
-    "HP": 2000,
-    "Attack1": [
-      550
-    ],
-    "Attack2": [
-      100
+    "Radius": [
+      1,
+      1
     ],
+    "HP": 2000,
+    "AttackSummon": 550,
+    "AttackMarch": 100,
     "MinMoveSpeed": 14,
     "MaxMoveSpeed": 16
   },
   {
     "Name": "虾兵",
     "SpriteName": "1xiatou_icon",
-    "Color": "#ffffff",
+    "Color": "#FFFFFF",
     "Type": "Enemy",
     "EnemyPrefab": "Enemy_1006",
-    "HP": 2000,
-    "Attack1": [
-      110
-    ],
-    "Attack2": [
-      110
+    "Radius": [
+      1,
+      1
     ],
+    "HP": 2000,
+    "AttackSummon": 110,
+    "AttackMarch": 110,
     "MinMoveSpeed": 4,
     "MaxMoveSpeed": 6
   },
   {
     "Name": "老鬼头",
     "SpriteName": "Enemy_Ghost2",
-    "Color": "#ffffff",
+    "Color": "#FFFFFF",
     "Type": "Enemy",
     "EnemyPrefab": "Enemy_1005",
-    "HP": 2000,
-    "Attack1": [
-      100
-    ],
-    "Attack2": [
-      100
+    "Radius": [
+      1,
+      1
     ],
+    "HP": 2000,
+    "AttackSummon": 100,
+    "AttackMarch": 100,
     "MinMoveSpeed": 1,
     "MaxMoveSpeed": 3
   },
   {
     "Name": "飞胖",
     "SpriteName": "Enemy_Flyzombie",
-    "Color": "#ffffff",
+    "Color": "#FFFFFF",
     "Type": "Enemy",
     "EnemyPrefab": "Enemy_1007",
-    "HP": 500,
-    "Attack1": [
-      100
-    ],
-    "Attack2": [
-      0
+    "Radius": [
+      1,
+      1
     ],
+    "HP": 500,
+    "AttackSummon": 100,
+    "AttackMarch": 0,
     "MinMoveSpeed": 4,
     "MaxMoveSpeed": 6
+  },
+  {
+    "Name": "test",
+    "SpriteName": "arrow_icon",
+    "Color": "#FF3232",
+    "Type": "Tower",
+    "EnemyPrefab": "Enemy_1002",
+    "Radius": [
+      0,
+      0
+    ],
+    "HP": 0,
+    "AttackSummon": 0,
+    "AttackMarch": 0,
+    "MinMoveSpeed": 0,
+    "MaxMoveSpeed": 0
   }
 ]

二进制
ActionTowerDefense/Luban/Config/Datas/出怪表.xlsx


二进制
ActionTowerDefense/Luban/Config/Datas/怪物表.xlsx