Procházet zdrojové kódy

怪物表角色与编辑器相对应

wgl před 6 měsíci
rodič
revize
d3da3e725b

+ 11 - 5
ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/Editor/GameMapEdPopup.cs

@@ -126,8 +126,8 @@ public class GameMapEdPopup : PopupWindowContent
         {
 			return;
 		}
-		ExcelEditor.ModifyExcel(path, gameMap.showIdent, "C6", GameMapEditor.mapSize_w);
-		ExcelEditor.ModifyExcel(path, gameMap.showIdent, "D6", GameMapEditor.mapSize_h);
+		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("记得运行\"gen_code_json.bat\"更新数据!");
@@ -152,7 +152,7 @@ public class GameMapEdPopup : PopupWindowContent
 		String waveName = "";
 		for (int i = 0; i < cfgCreateEnemy.Count; i++)
 		{
-			if (cfgCreateEnemy[i].WaveName == "这一行不要动")
+			if (cfgCreateEnemy[i].WaveName == "占位行")
 			{
 				if(mapId == mapIdx)
                 {
@@ -166,10 +166,16 @@ public class GameMapEdPopup : PopupWindowContent
             {
 				if (cfgCreateEnemy[i].WaveName != waveName)
 				{
-					waveName = cfgCreateEnemy[i].WaveName;
+					SingleCreateEnemyConfig singleCreateEnemyConfig = cfgCreateEnemy[i];
+					waveName = singleCreateEnemyConfig.WaveName;
 					ArrayUtility.Add(ref gameMap.layers, new GameMapLayer());
 					gameMap.InitLayer(gameMap.layers.Length);
-					gameMap.layers[gameMap.layers.Length - 1].name = waveName;
+					GameMapLayer gameMapLayer = gameMap.layers[gameMap.layers.Length - 1];
+					gameMapLayer.name = waveName;
+					gameMapLayer.duration = singleCreateEnemyConfig.WaveTime;
+					gameMapLayer.Hp = singleCreateEnemyConfig.HPRatio;
+					gameMapLayer.moveSpeed = singleCreateEnemyConfig.SpeedRatio;
+					gameMapLayer.attack = singleCreateEnemyConfig.AttackRatio;
 				}
 			}
             else

+ 83 - 39
ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/Editor/GameMapEditor.cs

@@ -124,7 +124,7 @@ public class GameMapEditor : EditorWindow
 	private static readonly GUIContent GC_new = new GUIContent("new");
 	private static readonly GUIContent GC_rename = new GUIContent("rename");
 	private static readonly GUIContent GC_apply = new GUIContent("apply");
-	private static readonly GUIContent GC_clear = new GUIContent("x", "Clear tile selection. Draw empty tiles.");
+	private static readonly GUIContent GC_reload = new GUIContent("reload");
 	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");
@@ -136,7 +136,8 @@ public class GameMapEditor : EditorWindow
 	private static readonly GUIContent GC_EditAuto = new GUIContent("Setup Auto-tile");
     private static readonly GUIContent GC_Viz = new GUIContent("*", "Toggle layer visblity in editor");
 
-	public static string enemyExcelPath = "Luban/Config/Datas/出怪表.xlsx";
+	public static string createEnemyExcelPath = "Luban/Config/Datas/出怪表.xlsx";
+	public static string enemyExcelPath = "Luban/Config/Datas/怪物表.xlsx";
 
     private GenericMenu addTileMenu = null;
 
@@ -624,7 +625,7 @@ public class GameMapEditor : EditorWindow
 			r.x = r.xMax - 200f; r.width = 100f; r.height = 15f;
             if (GUI.Button(r, GC_ExcelSave))
             {
-				ReloadSheetName(enemyExcelPath);
+				ReloadSheetName(createEnemyExcelPath);
 				mapsPopup.Asset = asset;
 				mapsPopup.isSelect = false;
 				mapsPopup.OnMapSelected = OnMapSelected;
@@ -633,7 +634,7 @@ public class GameMapEditor : EditorWindow
 			r.x = r.xMax; r.width = 100f; r.height = 15f;
 			if (GUI.Button(r, GC_MapSelect))
             {
-				ReloadSheetName(enemyExcelPath);
+				ReloadSheetName(createEnemyExcelPath);
 				mapsPopup.Asset = asset;
 				mapsPopup.isSelect = true;
 				mapsPopup.OnMapSelected = OnMapSelected;
@@ -935,12 +936,12 @@ public class GameMapEditor : EditorWindow
 
 		// 显示并编辑图层名称
 		EditorGUI.BeginChangeCheck();
-		string addName = EditorGUILayout.TextField("Wave Name", layer.name);
+		string addName = EditorGUILayout.TextField("波次名称", layer.name);
 		
-		int duration = EditorGUILayout.IntField("Next Wave", layer.duration);
-		float addHp = EditorGUILayout.FloatField("Hp", layer.Hp);
-		float addMoveSpeed = EditorGUILayout.FloatField("MoveSpeed", layer.moveSpeed);
-		float addAttack = EditorGUILayout.FloatField("Attack", layer.attack);
+		int duration = EditorGUILayout.IntField("波次出怪时间", layer.duration);
+		float addHp = EditorGUILayout.FloatField("血量倍率", layer.Hp);
+		float addMoveSpeed = EditorGUILayout.FloatField("速度倍率", layer.moveSpeed);
+		float addAttack = EditorGUILayout.FloatField("攻击倍率", layer.attack);
 
 		EditorGUILayout.BeginVertical("box");
 		{
@@ -1074,24 +1075,30 @@ public class GameMapEditor : EditorWindow
                 GUI.enabled = tileIdx >= 0;
                 if (GUI.Button(r, GC_rem, EditorStyles.miniButtonRight))
                 {
-                    if (autoTileSelected)
-                    {
-                        if (tileCache.ContainsKey(asset.tileAsset.autoTiles[tileIdx].tiles[0].id)) tileCache.Remove(asset.tileAsset.autoTiles[tileIdx].tiles[0].id);
-                        Undo.RecordObject(asset.tileAsset, "Remove Auto-Tile Definition");
-                        asset.tileAsset.RemoveAutoTileAtIndex(tileIdx);
-                        EditorUtility.SetDirty(asset.tileAsset);
-                        tileIdx--; if (tileIdx < 0 && asset.tileAsset.autoTiles.Count > 0) tileIdx = 0;
-                        if (tileIdx < 0 && asset.tileAsset.tiles.Count > 0) { tileIdx = 0; autoTileSelected = false; }
-                    }
-                    else
-                    {
-                        if (tileCache.ContainsKey(asset.tileAsset.tiles[tileIdx].id)) tileCache.Remove(asset.tileAsset.tiles[tileIdx].id);
-                        Undo.RecordObject(asset.tileAsset, "Remove Tile Definition");
-                        asset.tileAsset.RemoveTileAtIndex(tileIdx);
-                        EditorUtility.SetDirty(asset.tileAsset);
-                        tileIdx--; if (tileIdx < 0 && asset.tileAsset.tiles.Count > 0) tileIdx = 0;
-                        if (tileIdx < 0 && asset.tileAsset.autoTiles.Count > 0) { tileIdx = 0; autoTileSelected = true; }
-                    }
+                    if (tileCache.ContainsKey(asset.tileAsset.tiles[tileIdx].id)) tileCache.Remove(asset.tileAsset.tiles[tileIdx].id);
+                    Undo.RecordObject(asset.tileAsset, "Remove Tile Definition");
+                    asset.tileAsset.RemoveTileAtIndex(tileIdx);
+                    EditorUtility.SetDirty(asset.tileAsset);
+                    tileIdx--; if (tileIdx < 0 && asset.tileAsset.tiles.Count > 0) tileIdx = 0;
+                    if (tileIdx < 0 && asset.tileAsset.autoTiles.Count > 0) { tileIdx = 0; autoTileSelected = true; }
+                    //if (autoTileSelected)
+                    //{
+                    //    if (tileCache.ContainsKey(asset.tileAsset.autoTiles[tileIdx].tiles[0].id)) tileCache.Remove(asset.tileAsset.autoTiles[tileIdx].tiles[0].id);
+                    //    Undo.RecordObject(asset.tileAsset, "Remove Auto-Tile Definition");
+                    //    asset.tileAsset.RemoveAutoTileAtIndex(tileIdx);
+                    //    EditorUtility.SetDirty(asset.tileAsset);
+                    //    tileIdx--; if (tileIdx < 0 && asset.tileAsset.autoTiles.Count > 0) tileIdx = 0;
+                    //    if (tileIdx < 0 && asset.tileAsset.tiles.Count > 0) { tileIdx = 0; autoTileSelected = false; }
+                    //}
+                    //else
+                    //{
+                    //    if (tileCache.ContainsKey(asset.tileAsset.tiles[tileIdx].id)) tileCache.Remove(asset.tileAsset.tiles[tileIdx].id);
+                    //    Undo.RecordObject(asset.tileAsset, "Remove Tile Definition");
+                    //    asset.tileAsset.RemoveTileAtIndex(tileIdx);
+                    //    EditorUtility.SetDirty(asset.tileAsset);
+                    //    tileIdx--; if (tileIdx < 0 && asset.tileAsset.tiles.Count > 0) tileIdx = 0;
+                    //    if (tileIdx < 0 && asset.tileAsset.autoTiles.Count > 0) { tileIdx = 0; autoTileSelected = true; }
+                    //}
                     doRepaint = true;
                 }
                 r.x -= 25f;
@@ -1102,8 +1109,8 @@ public class GameMapEditor : EditorWindow
                     {
                         addTileMenu = new GenericMenu();
                         addTileMenu.AddItem(new GUIContent("Tile"), false, OnAddTile, 0);
-                        addTileMenu.AddItem(new GUIContent("Auto-16Tile"), false, OnAddTile, 1);
-                        addTileMenu.AddItem(new GUIContent("Auto-46Tile"), false, OnAddTile, 2);
+                        //addTileMenu.AddItem(new GUIContent("Auto-16Tile"), false, OnAddTile, 1);
+                        //addTileMenu.AddItem(new GUIContent("Auto-46Tile"), false, OnAddTile, 2);
                     }
 
                     addTileMenu.ShowAsContext();
@@ -1133,17 +1140,12 @@ public class GameMapEditor : EditorWindow
                 }
                 GUI.enabled = true;
 
-                r.x -= 28f;
-                if (GUI.Button(r, GC_clear, EditorStyles.miniButton))
+                r.x -= 85f;
+				r.width = 80;
+                if (GUI.Button(r, GC_reload, EditorStyles.miniButton))
                 {
-                    pasting = false;
-                    marking = false;
-                    clearMarked = false;
-                    markedTiles.Clear();
-                    tileIdx = -1;
-                    autoTileSelected = false;
-                    doRepaint = true;
-                }
+					ReloadEnemyExcelData(enemyExcelPath);
+				}
             }
 
 			EditorGUI.BeginChangeCheck();
@@ -1211,6 +1213,48 @@ public class GameMapEditor : EditorWindow
 		DrawTileList(ev);
 	}
 
+	void ReloadEnemyExcelData(string path)
+    {
+		for (int i = asset.tileAsset.tiles.Count - 1; i>=0 ; i--)
+        {
+			if (tileCache.ContainsKey(asset.tileAsset.tiles[i].id)) tileCache.Remove(asset.tileAsset.tiles[i].id);
+			asset.tileAsset.RemoveTileAtIndex(i);
+		}
+		pasting = false;
+		marking = false;
+		clearMarked = false;
+		markedTiles.Clear();		
+		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);
+
+			}
+			
+			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++;
+		}
+		doRepaint = true;
+		Debug.Log("怪物表数据导入成功!");
+	}
+
 	private void OnAutoTileChange(int idx)
 	{
 		if (autoTileSelected && tileIdx >= 0 && tileIdx < asset.tileAsset.autoTiles.Count)

+ 6 - 4
ActionTowerDefense/Assets/GameLevelEditor/GameMap/CoreScripts/GameMapTile.cs

@@ -24,10 +24,13 @@ public class GameMapTile
 
 	/// <summary> Unique identifier for tile. This is the value stored in GameMap.grid[] (-1 is used for empty tiles in the grid) </summary>
 	public int id;
+	public string name;
 
 	/// <summary> Sprite representing the tile. </summary>
 	[GameMapTilePreview] public Sprite sprite;
-		// You may choose not to use this but do not remove it since it is required by auto-tiles system.
+	// You may choose not to use this but do not remove it since it is required by auto-tiles system.
+
+	[GameMapTilePreview] public Color color = Color.white;
 
 	public int _aid = -1; // helper for auto-tiles; do not remove.
 
@@ -42,12 +45,11 @@ public class GameMapTile
 
 	public enum Type { Null = 0,  Tower=1, Enemy=2}
 	public Type type = Type.Null;   // the runtime might use something like this to identify what the placed tile means
-    public enum CH { Tower = 0, EnemyTower = 1, Enemy_Arrow = 2, Enemy_Giant = 3, Enemy_Sword = 4, Enemy_1001, Enemy_1002, Enemy_1003, Enemy_1004, Enemy_1005, Enemy_1006, Enemy_1007 };            // this value could depend on the chosen type. For example, if NPC then this could indicate which NPC prefab to spawn from an array of NPC prefabs.
+    public enum CH { Tower = 0, EnemyTower = 1,Enemy_1001, Enemy_1002, Enemy_1003, Enemy_1004, Enemy_1005, Enemy_1006, Enemy_1007 };            // this value could depend on the chosen type. For example, if NPC then this could indicate which NPC prefab to spawn from an array of NPC prefabs.
     public CH ch;
 
-    [GameMapTilePreview] public Color color = Color.white;
 	public Vector2 radius;
-	public string name;
+	
 	[HideInInspector]public int index = -1;
 	[HideInInspector]public bool hasOut = false;
 	public Parameter parameter;

+ 7 - 7
ActionTowerDefense/Assets/Gen/CfgEnemy.cs

@@ -16,29 +16,29 @@ namespace cfg
 
 public sealed partial class CfgEnemy
 {
-    private readonly Dictionary<int, SingleEnemyConfig> _dataMap;
+    private readonly Dictionary<string, SingleEnemyConfig> _dataMap;
     private readonly List<SingleEnemyConfig> _dataList;
     
     public CfgEnemy(JSONNode _json)
     {
-        _dataMap = new Dictionary<int, SingleEnemyConfig>();
+        _dataMap = new Dictionary<string, SingleEnemyConfig>();
         _dataList = new List<SingleEnemyConfig>();
         
         foreach(JSONNode _row in _json.Children)
         {
             var _v = SingleEnemyConfig.DeserializeSingleEnemyConfig(_row);
             _dataList.Add(_v);
-            _dataMap.Add(_v.ID, _v);
+            _dataMap.Add(_v.Name, _v);
         }
         PostInit();
     }
 
-    public Dictionary<int, SingleEnemyConfig> DataMap => _dataMap;
+    public Dictionary<string, SingleEnemyConfig> DataMap => _dataMap;
     public List<SingleEnemyConfig> DataList => _dataList;
 
-    public SingleEnemyConfig GetOrDefault(int key) => _dataMap.TryGetValue(key, out var v) ? v : null;
-    public SingleEnemyConfig Get(int key) => _dataMap[key];
-    public SingleEnemyConfig this[int key] => _dataMap[key];
+    public SingleEnemyConfig GetOrDefault(string key) => _dataMap.TryGetValue(key, out var v) ? v : null;
+    public SingleEnemyConfig Get(string key) => _dataMap[key];
+    public SingleEnemyConfig this[string key] => _dataMap[key];
 
     public void Resolve(Dictionary<string, object> _tables)
     {

+ 13 - 6
ActionTowerDefense/Assets/Gen/SingleCreateEnemyConfig.cs

@@ -19,7 +19,7 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
     public SingleCreateEnemyConfig(JSONNode _json) 
     {
         { if(!_json["WaveName"].IsString) { throw new SerializationException(); }  WaveName = _json["WaveName"]; }
-        { if(!_json["EnemyID"].IsNumber) { throw new SerializationException(); }  EnemyID = _json["EnemyID"]; }
+        { if(!_json["WaveTime"].IsNumber) { throw new SerializationException(); }  WaveTime = _json["WaveTime"]; }
         { if(!_json["EnemyName"].IsString) { throw new SerializationException(); }  EnemyName = _json["EnemyName"]; }
         { if(!_json["Count"].IsNumber) { throw new SerializationException(); }  Count = _json["Count"]; }
         { if(!_json["Type"].IsNumber) { throw new SerializationException(); }  Type = _json["Type"]; }
@@ -32,14 +32,15 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
         { 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 EnemyID, 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 HPRatio ) 
+    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 ) 
     {
         this.WaveName = WaveName;
-        this.EnemyID = EnemyID;
+        this.WaveTime = WaveTime;
         this.EnemyName = EnemyName;
         this.Count = Count;
         this.Type = Type;
@@ -52,6 +53,7 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
         this.YRandomRange = YRandomRange;
         this.ZRandomRange = ZRandomRange;
         this.AttackRatio = AttackRatio;
+        this.SpeedRatio = SpeedRatio;
         this.HPRatio = HPRatio;
         PostInit();
     }
@@ -62,13 +64,16 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
     }
 
     /// <summary>
-    /// 表格参数
+    /// 表格参数
     /// </summary>
     public string WaveName { get; private set; }
     /// <summary>
+    /// 宽
+    /// </summary>
+    public int WaveTime { get; private set; }
+    /// <summary>
     /// 高
     /// </summary>
-    public int EnemyID { get; private set; }
     public string EnemyName { get; private set; }
     public int Count { get; private set; }
     public int Type { get; private set; }
@@ -81,6 +86,7 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
     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;
@@ -99,7 +105,7 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
     {
         return "{ "
         + "WaveName:" + WaveName + ","
-        + "EnemyID:" + EnemyID + ","
+        + "WaveTime:" + WaveTime + ","
         + "EnemyName:" + EnemyName + ","
         + "Count:" + Count + ","
         + "Type:" + Type + ","
@@ -112,6 +118,7 @@ public sealed partial class SingleCreateEnemyConfig :  Bright.Config.BeanBase
         + "YRandomRange:" + YRandomRange + ","
         + "ZRandomRange:" + ZRandomRange + ","
         + "AttackRatio:" + AttackRatio + ","
+        + "SpeedRatio:" + SpeedRatio + ","
         + "HPRatio:" + HPRatio + ","
         + "}";
     }

+ 21 - 21
ActionTowerDefense/Assets/Gen/SingleEnemyConfig.cs

@@ -18,7 +18,10 @@ public sealed partial class SingleEnemyConfig :  Bright.Config.BeanBase
 {
     public SingleEnemyConfig(JSONNode _json) 
     {
-        { if(!_json["ID"].IsNumber) { throw new SerializationException(); }  ID = _json["ID"]; }
+        { if(!_json["Name"].IsString) { throw new SerializationException(); }  Name = _json["Name"]; }
+        { if(!_json["SpriteName"].IsString) { throw new SerializationException(); }  SpriteName = _json["SpriteName"]; }
+        { 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"]; }
         { 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); }   }
@@ -28,9 +31,12 @@ public sealed partial class SingleEnemyConfig :  Bright.Config.BeanBase
         PostInit();
     }
 
-    public SingleEnemyConfig(int ID, 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, int HP, System.Collections.Generic.List<int> Attack1, System.Collections.Generic.List<int> Attack2, float MinMoveSpeed, float MaxMoveSpeed ) 
     {
-        this.ID = ID;
+        this.Name = Name;
+        this.SpriteName = SpriteName;
+        this.Color = Color;
+        this.Type = Type;
         this.EnemyPrefab = EnemyPrefab;
         this.HP = HP;
         this.Attack1 = Attack1;
@@ -46,32 +52,23 @@ public sealed partial class SingleEnemyConfig :  Bright.Config.BeanBase
     }
 
     /// <summary>
-    /// 怪物ID
+    /// 角色类型汇总:
     /// </summary>
-    public int ID { get; private set; }
+    public string Name { get; private set; }
     /// <summary>
-    /// 怪物Prefab
+    /// Enemy
     /// </summary>
-    public string EnemyPrefab { get; private set; }
+    public string SpriteName { get; private set; }
     /// <summary>
-    /// 基础血量
+    /// Tower
     /// </summary>
+    public string Color { get; private set; }
+    public string Type { get; private set; }
+    public string EnemyPrefab { get; private set; }
     public int HP { get; private set; }
-    /// <summary>
-    /// Attack1攻击力
-    /// </summary>
     public System.Collections.Generic.List<int> Attack1 { get; private set; }
-    /// <summary>
-    /// Attack2攻击力
-    /// </summary>
     public System.Collections.Generic.List<int> Attack2 { get; private set; }
-    /// <summary>
-    /// 最小移动速度
-    /// </summary>
     public float MinMoveSpeed { get; private set; }
-    /// <summary>
-    /// 最大移动速度
-    /// </summary>
     public float MaxMoveSpeed { get; private set; }
 
     public const int __ID__ = 491839330;
@@ -89,7 +86,10 @@ public sealed partial class SingleEnemyConfig :  Bright.Config.BeanBase
     public override string ToString()
     {
         return "{ "
-        + "ID:" + ID + ","
+        + "Name:" + Name + ","
+        + "SpriteName:" + SpriteName + ","
+        + "Color:" + Color + ","
+        + "Type:" + Type + ","
         + "EnemyPrefab:" + EnemyPrefab + ","
         + "HP:" + HP + ","
         + "Attack1:" + Bright.Common.StringUtil.CollectionToString(Attack1) + ","

+ 30 - 2
ActionTowerDefense/Assets/Scripts/ExcelEditor.cs

@@ -73,8 +73,8 @@ public class ExcelEditor
         }
     }
 
-    //修改excel文件
-    public static bool ModifyExcel(string filePath, string sheetMame, string cellId, int newData)
+    //修改excel文件(地址索引)
+    public static bool ModifyExcel(string filePath, string sheetMame, string cellId, string newData)
     {
         FileInfo fileInfo = new FileInfo(filePath);
 
@@ -101,6 +101,34 @@ public class ExcelEditor
         }
     }
 
+    //修改excel文件(行列索引)
+    public static bool ModifyExcel(string filePath, string sheetMame, int cell_row, int cell_column, string newData)
+    {
+        FileInfo fileInfo = new FileInfo(filePath);
+
+
+        using (ExcelPackage package = new ExcelPackage(fileInfo))
+        {
+            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;
+            }
+        }
+    }
+
     //删除符合条件的几行数据
     public static bool RemoveExcelRows(string filePath, string sheetMame, Func<ExcelWorksheet, int, bool> rowCondition)
     {

+ 12 - 252
ActionTowerDefense/GenerateDatas/json/cfgcreateenemy.json

@@ -1,7 +1,7 @@
 [
   {
-    "WaveName": "这一行不要动",
-    "EnemyID": 0,
+    "WaveName": "占位行",
+    "WaveTime": 0,
     "EnemyName": "",
     "Count": 0,
     "Type": 0,
@@ -14,12 +14,13 @@
     "YRandomRange": 0,
     "ZRandomRange": 0,
     "AttackRatio": 0,
+    "SpeedRatio": 0,
     "HPRatio": 0
   },
   {
     "WaveName": "1",
-    "EnemyID": 11001,
-    "EnemyName": "",
+    "WaveTime": 0,
+    "EnemyName": "小猪",
     "Count": 10,
     "Type": 0,
     "Time": 5,
@@ -35,12 +36,13 @@
     "YRandomRange": 0,
     "ZRandomRange": 0,
     "AttackRatio": 1,
+    "SpeedRatio": 1,
     "HPRatio": 1
   },
   {
     "WaveName": "2",
-    "EnemyID": 11002,
-    "EnemyName": "",
+    "WaveTime": 0,
+    "EnemyName": "飞胖",
     "Count": 10,
     "Type": 0,
     "Time": 15,
@@ -56,151 +58,13 @@
     "YRandomRange": 4,
     "ZRandomRange": 0,
     "AttackRatio": 1,
-    "HPRatio": 1
-  },
-  {
-    "WaveName": "3",
-    "EnemyID": 3,
-    "EnemyName": "",
-    "Count": 10,
-    "Type": 0,
-    "Time": 5,
-    "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 3,
-    "Position": [
-      60,
-      0,
-      0
-    ],
-    "BuildingID": 0,
-    "YRandomRange": 0,
-    "ZRandomRange": 0,
-    "AttackRatio": 1,
-    "HPRatio": 1
-  },
-  {
-    "WaveName": "4",
-    "EnemyID": 4,
-    "EnemyName": "",
-    "Count": 2,
-    "Type": 0,
-    "Time": 5,
-    "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 10,
-    "Position": [
-      0,
-      0,
-      0
-    ],
-    "BuildingID": 0,
-    "YRandomRange": 0,
-    "ZRandomRange": 0,
-    "AttackRatio": 1,
-    "HPRatio": 1
-  },
-  {
-    "WaveName": "6",
-    "EnemyID": 6,
-    "EnemyName": "",
-    "Count": 2,
-    "Type": 0,
-    "Time": 5,
-    "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 10,
-    "Position": [
-      50,
-      0,
-      0
-    ],
-    "BuildingID": 0,
-    "YRandomRange": 0,
-    "ZRandomRange": 0,
-    "AttackRatio": 1,
-    "HPRatio": 1
-  },
-  {
-    "WaveName": "7",
-    "EnemyID": 7,
-    "EnemyName": "",
-    "Count": 2,
-    "Type": 0,
-    "Time": 5,
-    "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 10,
-    "Position": [
-      0,
-      5,
-      0
-    ],
-    "BuildingID": 0,
-    "YRandomRange": 0,
-    "ZRandomRange": 0,
-    "AttackRatio": 1,
-    "HPRatio": 1
-  },
-  {
-    "WaveName": "8",
-    "EnemyID": 0,
-    "EnemyName": "",
-    "Count": 0,
-    "Type": 0,
-    "Time": 0,
-    "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 0,
-    "Position": [],
-    "BuildingID": 0,
-    "YRandomRange": 0,
-    "ZRandomRange": 0,
-    "AttackRatio": 0,
-    "HPRatio": 0
-  },
-  {
-    "WaveName": "这一行不要动",
-    "EnemyID": 0,
-    "EnemyName": "",
-    "Count": 0,
-    "Type": 0,
-    "Time": 0,
-    "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 0,
-    "Position": [],
-    "BuildingID": 0,
-    "YRandomRange": 0,
-    "ZRandomRange": 0,
-    "AttackRatio": 0,
-    "HPRatio": 0
-  },
-  {
-    "WaveName": "1",
-    "EnemyID": 11001,
-    "EnemyName": "",
-    "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
   },
   {
     "WaveName": "2",
-    "EnemyID": 11002,
-    "EnemyName": "",
+    "WaveTime": 0,
+    "EnemyName": "防御塔",
     "Count": 10,
     "Type": 0,
     "Time": 15,
@@ -216,111 +80,7 @@
     "YRandomRange": 4,
     "ZRandomRange": 0,
     "AttackRatio": 1,
-    "HPRatio": 1
-  },
-  {
-    "WaveName": "3",
-    "EnemyID": 3,
-    "EnemyName": "",
-    "Count": 10,
-    "Type": 0,
-    "Time": 5,
-    "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 3,
-    "Position": [
-      60,
-      0,
-      0
-    ],
-    "BuildingID": 0,
-    "YRandomRange": 0,
-    "ZRandomRange": 0,
-    "AttackRatio": 1,
-    "HPRatio": 1
-  },
-  {
-    "WaveName": "4",
-    "EnemyID": 4,
-    "EnemyName": "",
-    "Count": 2,
-    "Type": 0,
-    "Time": 5,
-    "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 10,
-    "Position": [
-      0,
-      0,
-      0
-    ],
-    "BuildingID": 0,
-    "YRandomRange": 0,
-    "ZRandomRange": 0,
-    "AttackRatio": 1,
-    "HPRatio": 1
-  },
-  {
-    "WaveName": "5",
-    "EnemyID": 5,
-    "EnemyName": "",
-    "Count": 2,
-    "Type": 0,
-    "Time": 5,
-    "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 10,
-    "Position": [
-      0,
-      6,
-      0
-    ],
-    "BuildingID": 0,
-    "YRandomRange": 4,
-    "ZRandomRange": 0,
-    "AttackRatio": 1,
-    "HPRatio": 1
-  },
-  {
-    "WaveName": "6",
-    "EnemyID": 6,
-    "EnemyName": "",
-    "Count": 2,
-    "Type": 0,
-    "Time": 5,
-    "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 10,
-    "Position": [
-      50,
-      0,
-      0
-    ],
-    "BuildingID": 0,
-    "YRandomRange": 0,
-    "ZRandomRange": 0,
-    "AttackRatio": 1,
-    "HPRatio": 1
-  },
-  {
-    "WaveName": "7",
-    "EnemyID": 7,
-    "EnemyName": "",
-    "Count": 2,
-    "Type": 0,
-    "Time": 5,
-    "BuildingHP": 0,
-    "DelayTime": 0,
-    "TimeInterval": 10,
-    "Position": [
-      0,
-      5,
-      0
-    ],
-    "BuildingID": 0,
-    "YRandomRange": 0,
-    "ZRandomRange": 0,
-    "AttackRatio": 1,
+    "SpeedRatio": 1,
     "HPRatio": 1
   }
 ]

+ 67 - 53
ActionTowerDefense/GenerateDatas/json/cfgenemy.json

@@ -1,7 +1,10 @@
 [
   {
-    "ID": 1,
-    "EnemyPrefab": "Prefab/Enemy/Enemy_Sword",
+    "Name": "防御塔",
+    "SpriteName": "tower",
+    "Color": "#00ff00",
+    "Type": "Tower",
+    "EnemyPrefab": "Tower",
     "HP": 250,
     "Attack1": [
       100
@@ -13,8 +16,43 @@
     "MaxMoveSpeed": 6
   },
   {
-    "ID": 2,
-    "EnemyPrefab": "Prefab/Enemy/Enemy_Arrow",
+    "Name": "敌方防御塔",
+    "SpriteName": "tower",
+    "Color": "#ff0000",
+    "Type": "Tower",
+    "EnemyPrefab": "EnemyTower",
+    "HP": 250,
+    "Attack1": [
+      100
+    ],
+    "Attack2": [
+      100
+    ],
+    "MinMoveSpeed": 4,
+    "MaxMoveSpeed": 6
+  },
+  {
+    "Name": "小猪",
+    "SpriteName": "1xiaozhu_icon",
+    "Color": "#ffffff",
+    "Type": "Enemy",
+    "EnemyPrefab": "Enemy_1001",
+    "HP": 250,
+    "Attack1": [
+      100
+    ],
+    "Attack2": [
+      100
+    ],
+    "MinMoveSpeed": 4,
+    "MaxMoveSpeed": 6
+  },
+  {
+    "Name": "道士",
+    "SpriteName": "1daoshi_icon",
+    "Color": "#ffffff",
+    "Type": "Enemy",
+    "EnemyPrefab": "Enemy_1002",
     "HP": 100,
     "Attack1": [
       40
@@ -26,8 +64,11 @@
     "MaxMoveSpeed": 6
   },
   {
-    "ID": 3,
-    "EnemyPrefab": "Prefab/Enemy/Enemy_Giant",
+    "Name": "大猪",
+    "SpriteName": "1bigpig_icon",
+    "Color": "#ffffff",
+    "Type": "Enemy",
+    "EnemyPrefab": "Enemy_1003",
     "HP": 1000,
     "Attack1": [
       110
@@ -39,8 +80,11 @@
     "MaxMoveSpeed": 3
   },
   {
-    "ID": 4,
-    "EnemyPrefab": "Prefab/Enemy/ESpirits_Assassin",
+    "Name": "幽灵头",
+    "SpriteName": "1ghost 1",
+    "Color": "#ffffff",
+    "Type": "Enemy",
+    "EnemyPrefab": "Enemy_1004",
     "HP": 2000,
     "Attack1": [
       550
@@ -52,8 +96,11 @@
     "MaxMoveSpeed": 16
   },
   {
-    "ID": 5,
-    "EnemyPrefab": "Prefab/Enemy/ESpirits_Float",
+    "Name": "虾兵",
+    "SpriteName": "1xiatou_icon",
+    "Color": "#ffffff",
+    "Type": "Enemy",
+    "EnemyPrefab": "Enemy_1006",
     "HP": 2000,
     "Attack1": [
       110
@@ -65,8 +112,11 @@
     "MaxMoveSpeed": 6
   },
   {
-    "ID": 6,
-    "EnemyPrefab": "Prefab/Enemy/ESpirits_Cook",
+    "Name": "老鬼头",
+    "SpriteName": "Enemy_Ghost2",
+    "Color": "#ffffff",
+    "Type": "Enemy",
+    "EnemyPrefab": "Enemy_1005",
     "HP": 2000,
     "Attack1": [
       100
@@ -78,8 +128,11 @@
     "MaxMoveSpeed": 3
   },
   {
-    "ID": 7,
-    "EnemyPrefab": "Prefab/Enemy/ESpirits_Invisible",
+    "Name": "飞胖",
+    "SpriteName": "Enemy_Flyzombie",
+    "Color": "#ffffff",
+    "Type": "Enemy",
+    "EnemyPrefab": "Enemy_1007",
     "HP": 500,
     "Attack1": [
       100
@@ -89,44 +142,5 @@
     ],
     "MinMoveSpeed": 4,
     "MaxMoveSpeed": 6
-  },
-  {
-    "ID": 30001,
-    "EnemyPrefab": "Prefab/Boss/YuMenGuan/Boss_YuMenGuan",
-    "HP": 10000,
-    "Attack1": [
-      0
-    ],
-    "Attack2": [
-      0
-    ],
-    "MinMoveSpeed": 2,
-    "MaxMoveSpeed": 4
-  },
-  {
-    "ID": 11001,
-    "EnemyPrefab": "Prefab/Enemy/Enemy_11001",
-    "HP": 200,
-    "Attack1": [
-      100
-    ],
-    "Attack2": [
-      100
-    ],
-    "MinMoveSpeed": 4,
-    "MaxMoveSpeed": 6
-  },
-  {
-    "ID": 11002,
-    "EnemyPrefab": "Prefab/Enemy/Enemy_11002",
-    "HP": 200,
-    "Attack1": [
-      80
-    ],
-    "Attack2": [
-      80
-    ],
-    "MinMoveSpeed": 4,
-    "MaxMoveSpeed": 6
   }
 ]

binární
ActionTowerDefense/Luban/Config/Datas/出怪表.xlsx


binární
ActionTowerDefense/Luban/Config/Datas/怪物表.xlsx