SkillEditor.cs 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEditor;
  5. using System;
  6. using System.IO;
  7. using OfficeOpenXml;
  8. using Mono.Xml;
  9. using System.Security;
  10. public class SkillEditor : EditorWindow
  11. {
  12. static string[] s_skilltrigerTypeStr = new string[] { "普通攻击", "顺发技能", "免吟唱持续施法", "吟唱直接施法", "吟唱持续施法", "被动技能" };
  13. static string[] s_professionTypeStr = new string[] { "初心者", "剑士", "盗贼", "弓手", "法师", "手持" };
  14. static string[] s_damageTypeStr = new string[] { "无", " 物理伤害", "魔法伤害", "真实伤害" };
  15. static string[] s_targetSelectRuleStr = new string[] { "无", "敌方单体", "敌方前排", "敌方后排", "敌方全体", "自己", "生命最低的队友",
  16. "本方全体", "随机一个敌方目标", "随机一个敌方后排目标", "敌方整排,优先前排目标",
  17. "敌方整排,优先后排目标", "敌方单体,优先前排", "敌方单体,优先后排", "我方整排,优先前排",
  18. "我方整排,优先后排","我方减益buff最多的单位","我方生命值百分比最低的单位"};
  19. static string[] s_genderStr = new string[] { "无", "女", "男" };
  20. static int[] s_genderInt = new int[] { 0, 1, 2 };
  21. static string s_skillExcelFileName = "SkillCfg.xlsx";
  22. static string s_buffExcelFileName = "BuffCfg.xlsx";
  23. static string s_effectExcelFileName = "EffectCfg.xlsx";
  24. static string s_eventtemplate_XMLFileName = "EventTemplate.xml";
  25. public const string c_ExcelFileExtension = "xlsx";
  26. const string c_XmlFileExtension = "xml";
  27. static string[] s_valTypes = new string[] { "string", "int", "float" };
  28. private SkillAsset currentSkillAsset = null;
  29. static List<BuffDataAsset> m_buffs = new List<BuffDataAsset>();
  30. public static List<EffectAsset> m_effects = new List<EffectAsset>();
  31. public static List<string> m_effectIds = new List<string>();
  32. static List<string> m_icons = new List<string>();
  33. static List<SkillAsset> m_Skills = new List<SkillAsset>();
  34. static List<SkillAsset> m_miniLevelSkills = new List<SkillAsset>();
  35. static List<ActionEventParamEditor> s_template_events = new List<ActionEventParamEditor>();
  36. static Dictionary<int, ActionEventDataEditor> s_ActionEventDic = new Dictionary<int, ActionEventDataEditor>();
  37. //static Dictionary<string, Dictionary<int, ActionEventDataEditor>> s_ActionEventDic = new Dictionary<string, Dictionary<int, ActionEventDataEditor>>();
  38. bool bExtendSkillTree = true;
  39. bool bExtendSkillBaseFold = true;
  40. GUIStyle contentStyle = null;
  41. GUIStyle lblStyle = null;
  42. GUIStyle paramStyle = null;
  43. GUIStyle leftParamStyle = null;
  44. GUIStyle selectedItemStyle = null;
  45. GUIStyle selectedEventTemplateStyle = null;
  46. //[MenuItem("Skill_Tool/Skill Editor")]
  47. public static void ShowSkillTreeViewPanel()
  48. {
  49. ReadEventTemplate();
  50. GetEffectList();
  51. GetSkillIcons();
  52. GetFrameEventFiles();
  53. GetBuffs();
  54. GetSkillData();
  55. RefreshPanel();
  56. }
  57. static SkillEditor m_instance = null;
  58. public static SkillEditor GetPanel()
  59. {
  60. if (null == m_instance)
  61. {
  62. m_instance = EditorWindow.GetWindow<SkillEditor>(false, "技能编辑器", false);
  63. }
  64. return m_instance;
  65. }
  66. #region 读取配置模块
  67. static void GetFrameEventFiles()
  68. {
  69. s_ActionEventDic.Clear();
  70. string[] fileList = FileUtils.TraverseAllFiles(Constants.XmlConfig, "*.xml");
  71. for (int idx = 0; idx < fileList.Length; idx++)
  72. {
  73. if (!fileList[idx].Contains("buff_")) continue;
  74. ReadFrameEvent(fileList[idx]);
  75. }
  76. }
  77. static void ReadFrameEvent(string fileName)
  78. {
  79. TextAsset ta = AssetDatabase.LoadAssetAtPath(fileName, typeof(TextAsset)) as TextAsset;
  80. SecurityParser doc = new SecurityParser();
  81. try
  82. {
  83. doc.LoadXml(ta.text);
  84. }
  85. catch (System.Exception e)
  86. {
  87. DebugHelper.Assert(false, "Load Frame Event, exception = {1}", e.Message);
  88. return;
  89. }
  90. SecurityElement root = doc.SelectSingleNode("FrameEvent");
  91. if (root == null || root.Children == null) return;
  92. for (int idx = 0; idx < root.Children.Count; idx++)
  93. {
  94. var buffNode = root.Children[idx] as SecurityElement;
  95. string idStr = buffNode.Attribute("id");
  96. int id = int.Parse(idStr);
  97. string frameStr = buffNode.Attribute("endFrame");
  98. int frame = int.Parse(frameStr);
  99. string name = buffNode.Attribute("name");
  100. int gender = 2;
  101. if(!int.TryParse(buffNode.Attribute("gender"),out gender))
  102. {
  103. gender = 2;
  104. }
  105. ActionEventDataEditor aed = new ActionEventDataEditor(id, frame, name, gender);
  106. if (buffNode.Children != null)
  107. {
  108. for (int jdx = 0; jdx < buffNode.Children.Count; jdx++)
  109. {
  110. var eventNode = buffNode.Children[jdx] as SecurityElement;
  111. ActionEventParamEditor aep = new ActionEventParamEditor();
  112. int.TryParse(eventNode.Attribute("startFrame"), out aep.startFrame);
  113. int.TryParse(eventNode.Attribute("endFrame"), out aep.endFrame);
  114. int.TryParse(eventNode.Attribute("type"), out aep.eventType);
  115. bool.TryParse(eventNode.Attribute("affectBySing"), out aep.bAffectBySing);
  116. aep.desc = eventNode.Attribute("desc");
  117. aep.frameParams = new List<FrameEventParamEditor>();
  118. if (eventNode.Children != null)
  119. {
  120. for (int kdx = 0; kdx < eventNode.Children.Count; kdx++)
  121. {
  122. var paramNode = eventNode.Children[kdx] as SecurityElement;
  123. FrameEventParamEditor param = new FrameEventParamEditor();
  124. param.name = paramNode.Attribute("name");
  125. param.val = paramNode.Attribute("value");
  126. param.valType = paramNode.Attribute("valueType");
  127. if (string.IsNullOrEmpty(param.valType))
  128. param.valType = paramNode.Attribute("valType");
  129. param.valTypeIdx = GetValueTypeIndex(param.valType);
  130. if(param.name == "effect" || param.name == "hiteffect")
  131. {
  132. int effectId = 0;
  133. if(int.TryParse(param.val,out effectId))
  134. {
  135. param.valIdx = GetEffectIdx(effectId);
  136. }
  137. }
  138. aep.frameParams.Add(param);
  139. }
  140. }
  141. aed.AddEvent(aep);
  142. }
  143. }
  144. int uniqueId = id * 10 + gender;
  145. if (!s_ActionEventDic.ContainsKey(uniqueId))
  146. {
  147. s_ActionEventDic.Add(uniqueId, aed);
  148. }
  149. else
  150. {
  151. Debug.LogError("其他的frameevent配置一样的buff event");
  152. }
  153. }
  154. }
  155. static void ReadEventTemplate()
  156. {
  157. s_template_events.Clear();
  158. try
  159. {
  160. string filePath = EditorPrefs.GetString(s_eventtemplate_XMLFileName, string.Empty);
  161. if (!IsVaildGlobalPath(filePath, s_eventtemplate_XMLFileName))
  162. {
  163. string content = string.Concat("请选择", s_eventtemplate_XMLFileName, "文件");
  164. string[] filters = new string[2]
  165. {
  166. "Xml File", c_XmlFileExtension
  167. };
  168. filePath = EditorUtility.OpenFilePanelWithFilters(content, Application.dataPath, filters);
  169. if (!IsVaildGlobalPath(filePath, s_eventtemplate_XMLFileName))
  170. {
  171. EditorUtility.DisplayDialog("错误", string.Concat("未选择", s_eventtemplate_XMLFileName, "文件"), "确定");
  172. return;
  173. }
  174. EditorPrefs.SetString(s_eventtemplate_XMLFileName, filePath);
  175. }
  176. FileStream stream = new FileStream(filePath, FileMode.Open);
  177. byte[] buffData = new byte[stream.Length];
  178. stream.Read(buffData,0,(int)stream.Length);
  179. stream.Close();
  180. string str =System.Text.Encoding.Default.GetString(buffData, 0, buffData.Length);
  181. SecurityParser doc = new SecurityParser();
  182. try
  183. {
  184. doc.LoadXml(str);
  185. }
  186. catch (System.Exception e)
  187. {
  188. DebugHelper.Assert(false, "Load Frame Event, exception = {1}", e.Message);
  189. return;
  190. }
  191. SecurityElement root = doc.SelectSingleNode("events");
  192. if (root == null || root.Children == null) return;
  193. for (int idx = 0; idx < root.Children.Count; idx++)
  194. {
  195. var eventNode = root.Children[idx] as SecurityElement;
  196. ActionEventParamEditor aep = new ActionEventParamEditor();
  197. int.TryParse(eventNode.Attribute("startFrame"), out aep.startFrame);
  198. int.TryParse(eventNode.Attribute("endFrame"), out aep.endFrame);
  199. int.TryParse(eventNode.Attribute("type"), out aep.eventType);
  200. bool.TryParse(eventNode.Attribute("affectBySing"), out aep.bAffectBySing);
  201. aep.desc = eventNode.Attribute("desc");
  202. aep.frameParams = new List<FrameEventParamEditor>();
  203. if (eventNode.Children != null)
  204. {
  205. for (int kdx = 0; kdx < eventNode.Children.Count; kdx++)
  206. {
  207. var paramNode = eventNode.Children[kdx] as SecurityElement;
  208. FrameEventParamEditor param = new FrameEventParamEditor();
  209. param.name = paramNode.Attribute("name");
  210. param.val = paramNode.Attribute("value");
  211. param.valType = paramNode.Attribute("valueType");
  212. param.valTypeIdx = GetValueTypeIndex(param.valType);
  213. aep.frameParams.Add(param);
  214. }
  215. }
  216. s_template_events.Add(aep);
  217. }
  218. }
  219. catch (Exception e)
  220. {
  221. Debug.LogException(e);
  222. EditorUtility.DisplayDialog("错误", string.Concat("无法读取", s_eventtemplate_XMLFileName, "文件数据"), "确定");
  223. }
  224. Debug.Log("template cnt:" + s_template_events.Count);
  225. }
  226. public static void RefreshPanel()
  227. {
  228. SkillEditor panel = GetPanel();
  229. panel.Repaint();
  230. panel.ResetData();
  231. }
  232. static void GetEffectList()
  233. {
  234. m_effects.Clear();
  235. m_effectIds.Clear();
  236. try
  237. {
  238. string filePath = EditorPrefs.GetString(s_effectExcelFileName, string.Empty);
  239. if (!IsVaildGlobalPath(filePath, s_effectExcelFileName))
  240. {
  241. string content = string.Concat("请选择", s_effectExcelFileName, "文件");
  242. string[] filters = new string[2]
  243. {
  244. "Excel File", c_ExcelFileExtension
  245. };
  246. filePath = EditorUtility.OpenFilePanelWithFilters(content, Application.dataPath, filters);
  247. if (!IsVaildGlobalPath(filePath, s_effectExcelFileName))
  248. {
  249. EditorUtility.DisplayDialog("错误", string.Concat("未选择", s_effectExcelFileName, "文件"), "确定");
  250. return;
  251. }
  252. EditorPrefs.SetString(s_effectExcelFileName, filePath);
  253. }
  254. FileInfo fileInfo = new FileInfo(filePath);
  255. {
  256. using (var excelPackage = new ExcelPackage(fileInfo))
  257. {
  258. var sheets = excelPackage.Workbook.Worksheets;
  259. var sheet = sheets[1];
  260. int rowIndex = 4;
  261. while (!string.IsNullOrEmpty(sheet.GetValue<string>(rowIndex, 1)))
  262. {
  263. EffectAsset effect = EffectAsset.CreateEffectAsset(sheet, rowIndex);
  264. m_effects.Add(effect);
  265. m_effectIds.Add(effect.id.ToString());
  266. rowIndex += 1;
  267. }
  268. }
  269. }
  270. }
  271. catch (Exception e)
  272. {
  273. Debug.LogException(e);
  274. EditorUtility.DisplayDialog("错误", string.Concat("无法读取", s_effectExcelFileName, "文件数据"), "确定");
  275. }
  276. Debug.Log("effect cnt:" + m_effects.Count);
  277. }
  278. static void GetBuffs()
  279. {
  280. m_buffs.Clear();
  281. try
  282. {
  283. string filePath = EditorPrefs.GetString(s_buffExcelFileName, string.Empty);
  284. if (!IsVaildGlobalPath(filePath, s_buffExcelFileName))
  285. {
  286. string content = string.Concat("请选择", s_buffExcelFileName, "文件");
  287. string[] filters = new string[2]
  288. {
  289. "Excel File", c_ExcelFileExtension
  290. };
  291. filePath = EditorUtility.OpenFilePanelWithFilters(content, Application.dataPath, filters);
  292. if (!IsVaildGlobalPath(filePath, s_buffExcelFileName))
  293. {
  294. EditorUtility.DisplayDialog("错误", string.Concat("未选择", s_buffExcelFileName, "文件"), "确定");
  295. return;
  296. }
  297. EditorPrefs.SetString(s_buffExcelFileName, filePath);
  298. }
  299. FileInfo fileInfo = new FileInfo(filePath);
  300. {
  301. using (var excelPackage = new ExcelPackage(fileInfo))
  302. {
  303. var sheets = excelPackage.Workbook.Worksheets;
  304. var sheet = sheets[1];
  305. int rowIndex = 4;
  306. while (!string.IsNullOrEmpty(sheet.GetValue<string>(rowIndex, 1)))
  307. {
  308. BuffDataAsset buff = BuffDataAsset.CreateBuffAsset(sheet, rowIndex);
  309. buff.actionEventData = GetActionEventData(buff.id);
  310. buff.femaleActionEventData = GetActionEventData(buff.id, 1);
  311. m_buffs.Add(buff);
  312. rowIndex += 1;
  313. }
  314. }
  315. }
  316. }
  317. catch (Exception e)
  318. {
  319. Debug.LogException(e);
  320. EditorUtility.DisplayDialog("错误", string.Concat("无法读取", s_buffExcelFileName, "文件数据"), "确定");
  321. }
  322. Debug.Log("buff cnt:" + m_buffs.Count);
  323. }
  324. static void GetSkillData()
  325. {
  326. m_Skills.Clear();
  327. m_miniLevelSkills.Clear();
  328. try
  329. {
  330. string filePath = EditorPrefs.GetString(s_skillExcelFileName, string.Empty);
  331. if (!IsVaildGlobalPath(filePath, s_skillExcelFileName))
  332. {
  333. string content = string.Concat("请选择", s_skillExcelFileName, "文件");
  334. string[] filters = new string[2]
  335. {
  336. "Excel File", c_ExcelFileExtension
  337. };
  338. filePath = EditorUtility.OpenFilePanelWithFilters(content, Application.dataPath, filters);
  339. if (!IsVaildGlobalPath(filePath, s_skillExcelFileName))
  340. {
  341. EditorUtility.DisplayDialog("错误", string.Concat("未选择", s_skillExcelFileName, "文件"), "确定");
  342. return;
  343. }
  344. EditorPrefs.SetString(s_skillExcelFileName, filePath);
  345. }
  346. FileInfo fileInfo = new FileInfo(filePath);
  347. // using (var fs = new FileStream(filePath, FileMode.Open))
  348. {
  349. using (var excelPackage = new ExcelPackage(fileInfo))
  350. {
  351. var sheets = excelPackage.Workbook.Worksheets;
  352. var sheet = sheets[1];
  353. int rowIndex = 4;
  354. while (!string.IsNullOrEmpty(sheet.GetValue<string>(rowIndex, 1)))
  355. {
  356. SkillAsset skill = SkillAsset.CreateSkillAsset(sheet, rowIndex);
  357. if(skill.buffIdList!=null)
  358. {
  359. for(int sIdx = 0; sIdx < skill.buffIdList.Count;sIdx++)
  360. {
  361. BuffDataAsset buffData = GetBuffAsset(skill.buffIdList[sIdx]);
  362. if(buffData == null)
  363. {
  364. buffData = new BuffDataAsset(skill.buffIdList[sIdx]);
  365. }
  366. skill.AddNewBuff(buffData);
  367. }
  368. }
  369. skill.iconIdx = GetIconIdx(skill.skillIcon);
  370. m_Skills.Add(skill);
  371. if (!ExistSkill(skill.skillId))
  372. {
  373. m_miniLevelSkills.Add(skill);
  374. }
  375. rowIndex += 1;
  376. }
  377. }
  378. }
  379. }
  380. catch (Exception e)
  381. {
  382. Debug.LogException(e);
  383. EditorUtility.DisplayDialog("错误", string.Concat("无法读取", s_skillExcelFileName, "文件数据"), "确定");
  384. }
  385. Debug.Log("skill cnt:" + m_Skills.Count);
  386. }
  387. static bool ExistSkill(int skillId)
  388. {
  389. for (int idx = 0; idx < m_miniLevelSkills.Count;idx++)
  390. {
  391. if (m_miniLevelSkills[idx].skillId == skillId)
  392. return true;
  393. }
  394. return false;
  395. }
  396. public static bool IsVaildGlobalPath(string path,string fileName)
  397. {
  398. return (!string.IsNullOrEmpty(path)
  399. && File.Exists(path)
  400. && Path.GetFileName(path) == fileName);
  401. }
  402. static void GetSkillIcons()
  403. {
  404. m_icons.Clear();
  405. string path = Constants.IconDir + "/Skills";
  406. string[] fileList = FileUtils.TraverseAllFiles(path, "*.png");
  407. for(int idx =0; idx < fileList.Length;idx++)
  408. {
  409. string iconName = fileList[idx];
  410. string icon = FileUtils.RemoveExtension(FileUtils.RemoveParent(path, iconName));
  411. m_icons.Add(icon);
  412. }
  413. Debug.Log("icon cnt:" + m_icons.Count);
  414. }
  415. #endregion
  416. private void OnEnable()
  417. {
  418. if (contentStyle == null) {
  419. contentStyle = new GUIStyle();
  420. contentStyle.fontSize = 12;
  421. contentStyle.alignment = TextAnchor.MiddleRight;
  422. contentStyle.normal.textColor = Color.green;
  423. }
  424. if(lblStyle == null)
  425. {
  426. lblStyle = new GUIStyle();
  427. lblStyle.fontSize = 40;
  428. lblStyle.alignment = TextAnchor.MiddleCenter;
  429. lblStyle.fontStyle = FontStyle.Bold;
  430. }
  431. if(paramStyle == null)
  432. {
  433. paramStyle = new GUIStyle();
  434. paramStyle.fontSize = 12;
  435. paramStyle.alignment = TextAnchor.MiddleRight;
  436. paramStyle.normal.textColor = Color.red;
  437. }
  438. if(leftParamStyle == null)
  439. {
  440. leftParamStyle = new GUIStyle();
  441. leftParamStyle.fontSize = 12;
  442. leftParamStyle.alignment = TextAnchor.MiddleLeft;
  443. leftParamStyle.normal.textColor = Color.white;
  444. }
  445. if (selectedItemStyle == null)
  446. {
  447. selectedItemStyle = new GUIStyle();
  448. selectedItemStyle.fontSize = 20;
  449. selectedItemStyle.alignment = TextAnchor.MiddleLeft;
  450. selectedItemStyle.normal.textColor = Color.green;
  451. }
  452. if(selectedEventTemplateStyle == null)
  453. {
  454. selectedEventTemplateStyle = new GUIStyle();
  455. selectedEventTemplateStyle.fontSize = 20;
  456. selectedEventTemplateStyle.alignment = TextAnchor.MiddleLeft;
  457. selectedEventTemplateStyle.normal.textColor = Color.red;
  458. }
  459. }
  460. private void OnGUI()
  461. {
  462. EditorGUILayout.BeginHorizontal();
  463. DrawSkillTree();
  464. EditorGUILayout.BeginVertical();
  465. DrawSpace(4);
  466. ShowOpPnl();
  467. DrawSpace(1);
  468. DrawSkillPnl();
  469. EditorGUILayout.EndVertical();
  470. drawEventTemplatePnl();
  471. EditorGUILayout.EndHorizontal();
  472. DrawSpace(6);
  473. }
  474. void DrawSpace(int cnt)
  475. {
  476. for(int idx =0; idx < cnt;idx++)
  477. EditorGUILayout.Space();
  478. }
  479. void ShowOpPnl()
  480. {
  481. EditorGUILayout.BeginHorizontal();
  482. if(GUILayout.Button("新增技能",GUILayout.Width(100)))
  483. {
  484. AddNewSkill();
  485. }
  486. if (GUILayout.Button("删除当前", GUILayout.Width(100)))
  487. {
  488. RemoveCurSkill();
  489. }
  490. if(GUILayout.Button("应用修改", GUILayout.Width(100)))
  491. {
  492. ApplyCurChange();
  493. }
  494. if(GUILayout.Button("撤销修改", GUILayout.Width(100)))
  495. {
  496. CancelCurChange();
  497. }
  498. if(GUILayout.Button("保存到文件",GUILayout.Width(100)))
  499. {
  500. if(SaveData())
  501. {
  502. EditorUtility.DisplayDialog("提示", "保存成功 请关闭!!", "确定");
  503. }
  504. }
  505. EditorGUILayout.EndHorizontal();
  506. }
  507. void SetCurrentEditSkill(int idx)
  508. {
  509. curSkillIdx = idx;
  510. if (curSkillIdx >= 0 && curSkillIdx < m_miniLevelSkills.Count)
  511. {
  512. if (currentSkillAsset == null)
  513. {
  514. currentSkillAsset = new SkillAsset();
  515. }
  516. currentSkillAsset.Copy(m_miniLevelSkills[idx]);
  517. }
  518. else
  519. {
  520. currentSkillAsset = null;
  521. }
  522. }
  523. void AddNewSkill()
  524. {
  525. SkillAsset newSkill = new SkillAsset();
  526. m_Skills.Add(newSkill);
  527. m_miniLevelSkills.Add(newSkill);
  528. _scrollPos.y = 3500;
  529. SetCurrentEditSkill(m_miniLevelSkills.Count - 1);
  530. }
  531. void RemoveCurSkill()
  532. {
  533. if (curSkillIdx < 0 || curSkillIdx >= m_miniLevelSkills.Count) return;
  534. RemoveSkillById(m_miniLevelSkills[curSkillIdx].skillId);
  535. m_miniLevelSkills.RemoveAt(curSkillIdx);
  536. if (curSkillIdx >= m_miniLevelSkills.Count)
  537. {
  538. SetCurrentEditSkill(m_miniLevelSkills.Count - 1);
  539. }
  540. else
  541. {
  542. SetCurrentEditSkill(curSkillIdx);
  543. }
  544. }
  545. void RemoveSkillById(int skillId)
  546. {
  547. for(int idx = m_Skills.Count -1; idx >= 0; idx--)
  548. {
  549. if(m_Skills[idx].skillId == skillId)
  550. {
  551. m_Skills.RemoveAt(idx);
  552. }
  553. }
  554. }
  555. void CancelCurChange()
  556. {
  557. if (curSkillIdx < 0 || curSkillIdx >= m_miniLevelSkills.Count) return;
  558. currentSkillAsset.Copy(m_miniLevelSkills[curSkillIdx]);
  559. currentSkillAsset.bAddNewBuff = false;
  560. }
  561. public void ApplyCurChange()
  562. {
  563. if (curSkillIdx < 0 || curSkillIdx >= m_miniLevelSkills.Count) return;
  564. m_miniLevelSkills[curSkillIdx].Apply(currentSkillAsset);
  565. currentSkillAsset.bAddNewBuff = false;
  566. }
  567. bool ExistBuff(int buffId)
  568. {
  569. for(int idx =0; idx < m_buffs.Count;idx++)
  570. {
  571. if (m_buffs[idx].id == buffId)
  572. return true;
  573. }
  574. return false;
  575. }
  576. int GetBuffIndex(int buffId)
  577. {
  578. for (int idx = 0; idx < m_buffs.Count; idx++)
  579. {
  580. if (m_buffs[idx].id == buffId)
  581. return idx;
  582. }
  583. return -1;
  584. }
  585. public bool SaveData()
  586. {
  587. return SaveBuffDataToExcel() && SaveSkillDataToExcel();
  588. }
  589. public bool SaveBuffDataToExcel()
  590. {
  591. bool success = true;
  592. try
  593. {
  594. string filePath = EditorPrefs.GetString(s_buffExcelFileName, string.Empty);
  595. FileInfo fileInfo = new FileInfo(filePath);
  596. using (var excelPackage = new ExcelPackage(fileInfo))
  597. {
  598. var sheets = excelPackage.Workbook.Worksheets;
  599. var sheet = sheets[1];
  600. int rowIndex = 4;
  601. for (int idx = 0; idx < m_buffs.Count; idx++)
  602. {
  603. m_buffs[idx].SaveAssetToExcel(ref sheet, rowIndex);
  604. rowIndex += 1;
  605. }
  606. excelPackage.SaveAs(fileInfo);
  607. }
  608. }
  609. catch (Exception e)
  610. {
  611. Debug.LogException(e);
  612. EditorUtility.DisplayDialog("错误", string.Concat("有其它程序在使用该文件", s_buffExcelFileName, ", 请关闭"), "确定");
  613. success = false;
  614. }
  615. return success;
  616. }
  617. public bool SaveSkillDataToExcel()
  618. {
  619. bool success = true;
  620. try
  621. {
  622. string filePath = EditorPrefs.GetString(s_skillExcelFileName, string.Empty);
  623. FileInfo fileInfo = new FileInfo(filePath);
  624. using (var excelPackage = new ExcelPackage(fileInfo))
  625. {
  626. var sheets = excelPackage.Workbook.Worksheets;
  627. var sheet = sheets[1];
  628. int rowIndex = 4;
  629. for (int idx = 0; idx < m_Skills.Count; idx++)
  630. {
  631. m_Skills[idx].SaveAssetToExcel(ref sheet, rowIndex);
  632. rowIndex += 1;
  633. }
  634. excelPackage.SaveAs(fileInfo);
  635. }
  636. }
  637. catch (Exception e)
  638. {
  639. Debug.LogException(e);
  640. EditorUtility.DisplayDialog("错误", string.Concat("有其它程序在使用该文件", s_skillExcelFileName, ", 请关闭"), "确定");
  641. success = false;
  642. }
  643. return success;
  644. }
  645. #region 显示技能模块
  646. private Vector2 _scrollPos;
  647. int curSkillIdx = -1;
  648. void DrawSkillTree()
  649. {
  650. EditorGUILayout.BeginVertical(GUILayout.Width(200));
  651. bExtendSkillTree = EditorGUILayout.Foldout(bExtendSkillTree, "技能列表");
  652. if(bExtendSkillTree)
  653. {
  654. if(m_miniLevelSkills.Count > 0)
  655. {
  656. _scrollPos = EditorGUILayout.BeginScrollView(_scrollPos, false, false, GUILayout.Width(200));
  657. EditorGUI.indentLevel += 1;
  658. for (int idx = 0; idx < m_miniLevelSkills.Count; idx++)
  659. {
  660. if (curSkillIdx == idx)
  661. {
  662. EditorGUILayout.Foldout(false, m_miniLevelSkills[idx].skillId.ToString(), true, selectedItemStyle);
  663. }
  664. else
  665. {
  666. bool flag = EditorGUILayout.Foldout(false, m_miniLevelSkills[idx].skillId.ToString(), true);
  667. if (flag)
  668. {
  669. SetCurrentEditSkill(idx);
  670. }
  671. }
  672. }
  673. EditorGUI.indentLevel -= 1;
  674. EditorGUILayout.EndScrollView();
  675. }
  676. else
  677. {
  678. DrawSpace(20);
  679. if(GUILayout.Button("加载技能数据",GUILayout.Width(100),GUILayout.Height(60)))
  680. {
  681. ReadEventTemplate();
  682. GetSkillIcons();
  683. GetFrameEventFiles();
  684. GetEffectList();
  685. GetBuffs();
  686. GetSkillData();
  687. }
  688. }
  689. }
  690. EditorGUILayout.EndVertical();
  691. }
  692. Vector2 _templateScrollPos = Vector2.zero;
  693. ActionEventParamEditor curSelectedEventTemplate = null;
  694. int curEventTemplateIdx = -1;
  695. void drawEventTemplatePnl()
  696. {
  697. if (currentSkillAsset == null) return;
  698. if (s_template_events.Count > 0)
  699. {
  700. EditorGUILayout.BeginVertical(GUILayout.Width(200));
  701. bExtendEventTemplate = EditorGUILayout.Foldout(bExtendEventTemplate, "事件模板");
  702. if (bExtendEventTemplate)
  703. {
  704. _templateScrollPos = EditorGUILayout.BeginScrollView(_templateScrollPos, false, false, GUILayout.Width(200));
  705. EditorGUI.indentLevel += 1;
  706. for (int idx = 0; idx < s_template_events.Count; idx++)
  707. {
  708. if(curEventTemplateIdx == idx)
  709. {
  710. EditorGUILayout.Foldout(false, s_template_events[idx].desc.ToString(), true,selectedEventTemplateStyle);
  711. }
  712. else
  713. {
  714. bool flag = EditorGUILayout.Foldout(false, s_template_events[idx].desc.ToString(), true);
  715. if (flag)
  716. {
  717. curSelectedEventTemplate = s_template_events[idx];
  718. curEventTemplateIdx = idx;
  719. }
  720. }
  721. }
  722. EditorGUI.indentLevel -= 1;
  723. EditorGUILayout.EndScrollView();
  724. }
  725. EditorGUILayout.EndVertical();
  726. }
  727. }
  728. Vector2 skillScrollPos = Vector2.zero;
  729. void DrawSkillPnl()
  730. {
  731. if (currentSkillAsset == null) return;
  732. skillScrollPos = EditorGUILayout.BeginScrollView(skillScrollPos, false, false);
  733. EditorGUILayout.BeginVertical();
  734. bExtendSkillBaseFold = EditorGUILayout.Foldout(bExtendSkillBaseFold, "技能基础属性");
  735. if(bExtendSkillBaseFold)
  736. {
  737. EditorGUI.indentLevel += 1;
  738. #region 技能基础信息
  739. currentSkillAsset.skillId = EditorGUILayout.IntField("技能ID:", currentSkillAsset.skillId,GUILayout.Width(400));
  740. currentSkillAsset.skillLv = EditorGUILayout.IntField("技能等级:", currentSkillAsset.skillLv, GUILayout.Width(400));
  741. currentSkillAsset.skillName = EditorGUILayout.TextField("技能名字:", currentSkillAsset.skillName, GUILayout.Width(400));
  742. currentSkillAsset.skillDesc = EditorGUILayout.TextField("技能描述:", currentSkillAsset.skillDesc, GUILayout.Width(400));
  743. currentSkillAsset.levelUpDesc = EditorGUILayout.TextField("升级描述:", currentSkillAsset.levelUpDesc, GUILayout.Width(400));
  744. //currentSkillAsset.skillIcon = EditorGUILayout.TextField("技能icon:", currentSkillAsset.skillIcon, GUILayout.Width(400));
  745. EditorGUILayout.BeginHorizontal();
  746. string lastFileName = currentSkillAsset.skillIcon;
  747. Sprite icon = null;
  748. if (currentSkillAsset.iconIdx >= 0)
  749. {
  750. currentSkillAsset.skillIcon = "Skills/"+m_icons[currentSkillAsset.iconIdx];
  751. if ((!string.IsNullOrEmpty(currentSkillAsset.skillIcon) && lastFileName != currentSkillAsset.skillIcon) || icon == null)
  752. icon = AssetDatabase.LoadAssetAtPath<Sprite>(Constants.IconDir + "/" + currentSkillAsset.skillIcon + ".png");
  753. }
  754. EditorGUILayout.LabelField("技能ICON:", GUILayout.Width(100));
  755. currentSkillAsset.iconIdx = EditorGUILayout.Popup(currentSkillAsset.iconIdx, m_icons.ToArray(), GUILayout.Width(200));
  756. if (icon != null)
  757. EditorGUILayout.ObjectField(icon, typeof(Sprite), GUILayout.Width(120), GUILayout.Height(100));
  758. EditorGUILayout.EndHorizontal();
  759. currentSkillAsset.skillType = EditorGUILayout.Popup("技能类型:", currentSkillAsset.skillType,s_skilltrigerTypeStr, GUILayout.Width(400));
  760. currentSkillAsset.cost = EditorGUILayout.IntField("SP消耗:", currentSkillAsset.cost, GUILayout.Width(400));
  761. currentSkillAsset.jobType = EditorGUILayout.Popup("职业类型:", currentSkillAsset.jobType,s_professionTypeStr, GUILayout.Width(400));
  762. currentSkillAsset.jobStage = EditorGUILayout.IntField("职业阶段:", currentSkillAsset.jobStage, GUILayout.Width(400));
  763. currentSkillAsset.fixedSingTime = EditorGUILayout.FloatField("固定吟唱时间:", currentSkillAsset.fixedSingTime, GUILayout.Width(400));
  764. currentSkillAsset.changeSingTime = EditorGUILayout.FloatField("可变吟唱时间:", currentSkillAsset.changeSingTime, GUILayout.Width(400));
  765. currentSkillAsset.preCastingTime = EditorGUILayout.FloatField("施法前摇时间:", currentSkillAsset.preCastingTime, GUILayout.Width(400));
  766. currentSkillAsset.castingTime = EditorGUILayout.FloatField("持续施法时间:", currentSkillAsset.castingTime, GUILayout.Width(400));
  767. currentSkillAsset.afterCastingTime = EditorGUILayout.FloatField("施法后摇时间:", currentSkillAsset.afterCastingTime, GUILayout.Width(400));
  768. currentSkillAsset.cd = EditorGUILayout.FloatField("施法延迟:", currentSkillAsset.cd, GUILayout.Width(400));
  769. currentSkillAsset.hide = EditorGUILayout.Toggle("技能树中是否隐藏:", currentSkillAsset.hide, GUILayout.Width(400));
  770. currentSkillAsset.extendPerceptionFold = EditorGUILayout.Foldout(currentSkillAsset.extendPerceptionFold, "感知范围");
  771. if(currentSkillAsset.extendPerceptionFold)
  772. {
  773. EditorGUI.indentLevel += 1;
  774. EditorGUILayout.BeginHorizontal();
  775. for (int idx = 0; idx <= 2; idx++)
  776. {
  777. string lblName = CommonUtil.GetProfessionName(idx);
  778. currentSkillAsset.PerceptionRange[idx] = EditorGUILayout.FloatField(lblName+":", currentSkillAsset.PerceptionRange[idx], GUILayout.Width(200));
  779. }
  780. EditorGUILayout.EndHorizontal();
  781. EditorGUILayout.BeginHorizontal();
  782. for (int idx=3; idx <= 5;idx++)
  783. {
  784. string lblName = CommonUtil.GetProfessionName(idx);
  785. currentSkillAsset.PerceptionRange[idx] = EditorGUILayout.FloatField(lblName + ":", currentSkillAsset.PerceptionRange[idx], GUILayout.Width(200));
  786. }
  787. EditorGUILayout.EndHorizontal();
  788. EditorGUI.indentLevel -= 1;
  789. }
  790. #endregion
  791. EditorGUI.indentLevel -= 1;
  792. }
  793. EditorGUILayout.BeginVertical(GUILayout.Height(800));
  794. currentSkillAsset.extendBuffFold = EditorGUILayout.Foldout(currentSkillAsset.extendBuffFold, "技能buff配置");
  795. if (currentSkillAsset.extendBuffFold)
  796. {
  797. EditorGUI.indentLevel += 1;
  798. if (currentSkillAsset.buffList != null && currentSkillAsset.buffList.Count > 0)
  799. {
  800. for (int idx = 0; idx < currentSkillAsset.buffList.Count; idx++)
  801. {
  802. EditorGUILayout.BeginHorizontal(GUILayout.Width(220));
  803. currentSkillAsset.buffList[idx].id = EditorGUILayout.IntField("buffId", currentSkillAsset.buffList[idx].id, contentStyle, GUILayout.Width(200));
  804. EditorGUILayout.LabelField("", GUILayout.Width(200));
  805. if (GUILayout.Button("删除buff",GUILayout.Width(100)))
  806. {
  807. RemoveBuff(currentSkillAsset.buffList[idx]);
  808. return;
  809. }
  810. if(idx == currentSkillAsset.buffList.Count-1)
  811. {
  812. if (GUILayout.Button("添加新buff", GUILayout.Width(100)))
  813. {
  814. AddNewBuff();
  815. return;
  816. }
  817. }
  818. EditorGUILayout.EndHorizontal();
  819. DrawBuff(currentSkillAsset.buffList[idx]);
  820. }
  821. }
  822. else
  823. {
  824. DrawSpace(20);
  825. EditorGUILayout.BeginHorizontal();
  826. EditorGUILayout.LabelField("", GUILayout.Width(500));
  827. if (GUILayout.Button("添加技能buff", GUILayout.Width(200), GUILayout.Height(60)))
  828. {
  829. AddNewBuff();
  830. return;
  831. }
  832. EditorGUILayout.LabelField("", GUILayout.Width(500));
  833. EditorGUILayout.EndHorizontal();
  834. }
  835. EditorGUI.indentLevel -= 1;
  836. }
  837. EditorGUILayout.EndVertical();
  838. EditorGUILayout.EndVertical();
  839. EditorGUILayout.EndScrollView();
  840. }
  841. void RemoveBuff(BuffDataAsset buffData)
  842. {
  843. if (currentSkillAsset == null) return;
  844. currentSkillAsset.RemoveBuff(buffData);
  845. }
  846. void AddNewBuff()
  847. {
  848. if (currentSkillAsset == null) return;
  849. BuffDataAsset newBuffData = new BuffDataAsset();
  850. currentSkillAsset.AddNewBuff(newBuffData);
  851. currentSkillAsset.bAddNewBuff = true;
  852. }
  853. bool bExtendEventTemplate = true;
  854. void DrawBuff(BuffDataAsset buffData)
  855. {
  856. if (buffData == null) return;
  857. #region buff基础信息
  858. buffData.extendBaseFold = EditorGUILayout.Foldout(buffData.extendBaseFold, "buff基本信息");
  859. if (buffData.extendBaseFold)
  860. {
  861. EditorGUILayout.BeginVertical(GUILayout.Width(700));
  862. buffData.desc = EditorGUILayout.TextField("描述:", buffData.desc);
  863. buffData.damageType = EditorGUILayout.Popup("伤害类型:", buffData.damageType, s_damageTypeStr);
  864. buffData.targetType = EditorGUILayout.Popup("目标类型:", buffData.targetType, s_targetSelectRuleStr);
  865. EditorGUILayout.EndVertical();
  866. EditorGUILayout.BeginHorizontal();
  867. EditorGUILayout.LabelField("命中效果:", GUILayout.Width(100));
  868. buffData.canPerfectDodge = EditorGUILayout.ToggleLeft("可完美闪避", buffData.canPerfectDodge, GUILayout.Width(160), GUILayout.Height(40));
  869. buffData.canDodge = EditorGUILayout.ToggleLeft("可闪避", buffData.canDodge, GUILayout.Width(100), GUILayout.Height(40));
  870. buffData.canResist = EditorGUILayout.ToggleLeft("可抵抗", buffData.canResist, GUILayout.Width(100), GUILayout.Height(40));
  871. buffData.canCrit = EditorGUILayout.ToggleLeft("可暴击", buffData.canCrit, GUILayout.Width(100), GUILayout.Height(40));
  872. EditorGUILayout.EndHorizontal();
  873. buffData.effectiveness = EditorGUILayout.IntField("生效率:", buffData.effectiveness, GUILayout.Width(400));
  874. buffData.ignoreMultiHurt = EditorGUILayout.Toggle("是否忽略多段伤害", buffData.ignoreMultiHurt);
  875. }
  876. #endregion
  877. #region buff效果配置
  878. EditorGUILayout.BeginVertical();
  879. buffData.extendFunFold = EditorGUILayout.Foldout(buffData.extendFunFold, "buff效果配置");
  880. if(buffData.extendFunFold)
  881. {
  882. if(buffData.funList!=null && buffData.funList.Count > 0)
  883. {
  884. EditorGUI.indentLevel += 1;
  885. for (int idx = 0; idx < buffData.funList.Count; idx++)
  886. {
  887. EditorGUILayout.BeginHorizontal();
  888. FunctionValData funParam = buffData.funList[idx];
  889. DrawFunParam(funParam);
  890. if(GUILayout.Button("-",GUILayout.Width(60)))
  891. {
  892. buffData.funList.RemoveAt(idx);
  893. return;
  894. }
  895. if(idx == buffData.funList.Count -1)
  896. {
  897. if (!FunctionEventEditor.isShowing)
  898. {
  899. if (GUILayout.Button("+", GUILayout.Width(60)))
  900. {
  901. FunctionEventEditor.GetFunctionEventEditor(buffData.id);
  902. return;
  903. }
  904. }
  905. }
  906. EditorGUILayout.EndHorizontal();
  907. EditorGUILayout.Space();
  908. }
  909. EditorGUI.indentLevel -= 1;
  910. }
  911. else
  912. {
  913. DrawSpace(20);
  914. EditorGUILayout.BeginHorizontal();
  915. EditorGUILayout.LabelField("", GUILayout.Width(500));
  916. if (GUILayout.Button("添加Function", GUILayout.Width(200), GUILayout.Height(40)))
  917. {
  918. FunctionEventEditor.GetFunctionEventEditor(buffData.id);
  919. return;
  920. }
  921. EditorGUILayout.LabelField("", GUILayout.Width(500));
  922. EditorGUILayout.EndHorizontal();
  923. }
  924. }
  925. EditorGUILayout.EndVertical();
  926. #endregion
  927. #region 动作预览对象
  928. buffData.extendModelPrefab = EditorGUILayout.Foldout(buffData.extendModelPrefab, "预览模型");
  929. EditorGUILayout.BeginVertical();
  930. if (buffData.extendModelPrefab)
  931. {
  932. UnityEngine.Object temp = EditorGUILayout.ObjectField("动作控制器:",buffData.modelAnimator,typeof(RuntimeAnimatorController),GUILayout.Width(300));
  933. if (temp != null) {
  934. RuntimeAnimatorController ctrl = temp as RuntimeAnimatorController;
  935. if(buffData.modelAnimator != ctrl)
  936. {
  937. buffData.modelAnimator = ctrl;
  938. UnityEditor.Animations.AnimatorController ac = ctrl as UnityEditor.Animations.AnimatorController;
  939. buffData.stateMachine = ac.layers[0].stateMachine;
  940. buffData.animClipNames = new string[buffData.stateMachine.states.Length];
  941. for (int i = 0; i < buffData.animClipNames.Length; i++) {
  942. buffData.animClipNames[i] = buffData.stateMachine.states[i].state.name;
  943. }
  944. }
  945. }
  946. }
  947. EditorGUILayout.EndVertical();
  948. #endregion
  949. #region buff帧事件
  950. buffData.extendFrameEventFold = EditorGUILayout.Foldout(buffData.extendFrameEventFold, "frameevent");
  951. EditorGUILayout.BeginVertical();
  952. if (buffData.extendFrameEventFold)
  953. {
  954. EditorGUI.indentLevel += 1;
  955. int flag = DrawFrameEvent(buffData.id, ref buffData.actionEventData,2,buffData.animClipNames, buffData.stateMachine);
  956. if (flag == 1)
  957. {
  958. SaveCurrentBuffFrameEvent(buffData);
  959. }else if(flag == 2)
  960. {
  961. buffData.SaveFrameEventToXml();
  962. }
  963. EditorGUI.indentLevel -= 1;
  964. }
  965. EditorGUILayout.EndVertical();
  966. buffData.extendFemaleFrameEventFold = EditorGUILayout.Foldout(buffData.extendFemaleFrameEventFold, "female_frameevent");
  967. EditorGUILayout.BeginVertical();
  968. if (buffData.extendFemaleFrameEventFold)
  969. {
  970. EditorGUI.indentLevel += 1;
  971. int flag = DrawFrameEvent(buffData.id, ref buffData.femaleActionEventData, 1, buffData.animClipNames, buffData.stateMachine);
  972. if (flag == 1)
  973. {
  974. SaveCurrentBuffFrameEvent(buffData);
  975. }
  976. else if (flag == 2)
  977. {
  978. buffData.SaveFemaleFrameEventToXml();
  979. }
  980. EditorGUI.indentLevel -= 1;
  981. }
  982. EditorGUILayout.EndVertical();
  983. #endregion
  984. }
  985. void DrawFunParam(FunctionValData param)
  986. {
  987. EditorGUILayout.LabelField("id:",contentStyle, GUILayout.Width(50)); param.funId = EditorGUILayout.IntField(param.funId, GUILayout.Width(100));
  988. EditorGUILayout.LabelField("数值:", contentStyle, GUILayout.Width(50)); param.val = EditorGUILayout.FloatField(param.val, GUILayout.Width(100));
  989. EditorGUILayout.LabelField("数值增量:", contentStyle, GUILayout.Width(90)); param.incVal = EditorGUILayout.FloatField( param.incVal, GUILayout.Width(100));
  990. EditorGUILayout.LabelField("持续时长:", contentStyle, GUILayout.Width(90)); param.duration = EditorGUILayout.FloatField(param.duration, GUILayout.Width(100));
  991. EditorGUILayout.LabelField("时长增量:", contentStyle, GUILayout.Width(90)); param.incDuration = EditorGUILayout.FloatField(param.incDuration, GUILayout.Width(100));
  992. EditorGUILayout.LabelField("来源属性:", contentStyle, GUILayout.Width(90)); param.fromAttr = EditorGUILayout.IntField(param.fromAttr, GUILayout.Width(100));
  993. EditorGUILayout.LabelField("间隔时间:", contentStyle, GUILayout.Width(90)); param.intervalTime = EditorGUILayout.FloatField(param.intervalTime, GUILayout.Width(100));
  994. }
  995. int DrawFrameEvent(int buffId,ref ActionEventDataEditor actionEventData,int gender,string[] animNames, UnityEditor.Animations.AnimatorStateMachine ctrl)
  996. {
  997. if (actionEventData != null)
  998. {
  999. DrawSpace(1);
  1000. EditorGUILayout.BeginHorizontal();
  1001. actionEventData.Name = EditorGUILayout.TextField("名字", actionEventData.Name, GUILayout.Width(400));
  1002. actionEventData.TotalFrame = EditorGUILayout.IntField("帧数", actionEventData.TotalFrame, GUILayout.Width(200));
  1003. EditorGUILayout.LabelField("",GUILayout.Width(200));
  1004. if (GUILayout.Button("保存buff帧数据", GUILayout.Width(100), GUILayout.Height(20)))
  1005. {
  1006. return 1;
  1007. }
  1008. EditorGUILayout.EndHorizontal();
  1009. DrawSpace(4);
  1010. List<ActionEventParamEditor> eventList = actionEventData.ActionEventList;
  1011. if (eventList != null && eventList.Count > 0)
  1012. {
  1013. for (int idx = 0; idx < eventList.Count; idx++)
  1014. {
  1015. int flag = DrawEvent(idx + 1, eventList.Count, eventList[idx], animNames,ctrl);
  1016. if (flag == 1) //移除帧数据
  1017. {
  1018. eventList.RemoveAt(idx);
  1019. return 0;
  1020. }
  1021. else if (flag == 2) //增加新帧数据
  1022. {
  1023. if (curSelectedEventTemplate != null)
  1024. {
  1025. ActionEventParamEditor newEvent = new ActionEventParamEditor(curSelectedEventTemplate);
  1026. eventList.Add(newEvent);
  1027. }
  1028. else
  1029. {
  1030. EditorUtility.DisplayDialog("错误", string.Concat("没有选择添加的事件模板"), "确定");
  1031. }
  1032. return 0;
  1033. }
  1034. DrawSpace(2);
  1035. }
  1036. }
  1037. else
  1038. {
  1039. DrawSpace(20);
  1040. EditorGUILayout.BeginHorizontal();
  1041. EditorGUILayout.LabelField("", GUILayout.Width(500));
  1042. if (GUILayout.Button("新增Event Node",GUILayout.Width(200),GUILayout.Height(40)))
  1043. {
  1044. if(eventList == null)
  1045. {
  1046. if (curSelectedEventTemplate != null)
  1047. {
  1048. ActionEventParamEditor newEvent = new ActionEventParamEditor(curSelectedEventTemplate);
  1049. actionEventData.AddEvent(newEvent);
  1050. }
  1051. else
  1052. {
  1053. EditorUtility.DisplayDialog("错误", string.Concat("没有选择添加的事件模板"), "确定");
  1054. }
  1055. return 0;
  1056. }
  1057. }
  1058. EditorGUILayout.LabelField("", GUILayout.Width(500));
  1059. EditorGUILayout.EndHorizontal();
  1060. }
  1061. }
  1062. else
  1063. {
  1064. DrawSpace(20);
  1065. EditorGUILayout.BeginHorizontal();
  1066. EditorGUILayout.LabelField("", GUILayout.Width(500));
  1067. if (GUILayout.Button("创建FrameEvent文件", GUILayout.Width(300), GUILayout.Height(40)))
  1068. {
  1069. actionEventData = new ActionEventDataEditor(buffId, 30, buffId.ToString(), gender);
  1070. return 2;
  1071. }
  1072. EditorGUILayout.LabelField("", GUILayout.Width(500));
  1073. EditorGUILayout.EndHorizontal();
  1074. }
  1075. return 0;
  1076. }
  1077. int DrawEvent(int cnt,int maxCnt,ActionEventParamEditor eventParam, string[] animNames, UnityEditor.Animations.AnimatorStateMachine ctrl)
  1078. {
  1079. EditorGUILayout.BeginVertical();
  1080. EditorGUILayout.BeginHorizontal();
  1081. EditorGUILayout.LabelField(string.Format("Event{0}",cnt), contentStyle, GUILayout.Width(80));
  1082. EditorGUILayout.LabelField("起始帧数:", contentStyle, GUILayout.Width(80)); eventParam.startFrame = EditorGUILayout.IntField(eventParam.startFrame, GUILayout.Width(100));
  1083. EditorGUILayout.LabelField("结束帧数:", contentStyle, GUILayout.Width(80)); eventParam.endFrame = EditorGUILayout.IntField(eventParam.endFrame, GUILayout.Width(100));
  1084. SkillActionFrameEventType eType = (SkillActionFrameEventType)eventParam.eventType;
  1085. EditorGUILayout.LabelField("事件类型:", contentStyle, GUILayout.Width(80)); eType = (SkillActionFrameEventType)EditorGUILayout.EnumPopup(eType, GUILayout.Width(300)); eventParam.eventType = (int)eType;
  1086. EditorGUILayout.LabelField("受吟唱影响:", contentStyle, GUILayout.Width(100)); eventParam.bAffectBySing = EditorGUILayout.Toggle(eventParam.bAffectBySing, GUILayout.Width(40));
  1087. EditorGUILayout.LabelField("备注:", contentStyle, GUILayout.Width(60)); eventParam.desc = EditorGUILayout.TextField(eventParam.desc, GUILayout.Width(240));
  1088. if (GUILayout.Button("-", GUILayout.Width(40)))
  1089. {
  1090. return 1;
  1091. }
  1092. if (cnt == maxCnt)
  1093. {
  1094. if (!FunctionEventEditor.isShowing)
  1095. {
  1096. if (GUILayout.Button("+", GUILayout.Width(40)))
  1097. {
  1098. return 2;
  1099. }
  1100. }
  1101. }
  1102. EditorGUILayout.EndHorizontal();
  1103. EditorGUI.indentLevel += 1;
  1104. for (int idx =0; idx < eventParam.frameParams.Count;idx++)
  1105. {
  1106. DrawEventParam(eventParam.frameParams[idx], animNames,ctrl);
  1107. EditorGUILayout.Space();
  1108. }
  1109. EditorGUI.indentLevel -= 1;
  1110. EditorGUILayout.EndVertical();
  1111. return 0;
  1112. }
  1113. void DrawEventParam(FrameEventParamEditor param, string[] animNames, UnityEditor.Animations.AnimatorStateMachine stateMachine)
  1114. {
  1115. EditorGUILayout.BeginHorizontal();
  1116. EditorGUILayout.LabelField("参数名字:", paramStyle, GUILayout.Width(100)); param.name = EditorGUILayout.TextField(param.name, GUILayout.Width(200));
  1117. if(param.name=="effect" || param.name == "hiteffect")
  1118. {
  1119. if (param.valIdx >= 0)
  1120. {
  1121. param.val = m_effects[param.valIdx].id.ToString();
  1122. }
  1123. EditorGUILayout.LabelField("参数数值:", paramStyle, GUILayout.Width(100)); EditorGUILayout.LabelField(param.val, GUILayout.Width(200));
  1124. param.valIdx = EditorGUILayout.Popup(param.valIdx, m_effectIds.ToArray(), GUILayout.Width(200));
  1125. }else if(param.name == "animName")
  1126. {
  1127. EditorGUILayout.LabelField("参数数值:", paramStyle, GUILayout.Width(100));
  1128. if(animNames != null)
  1129. {
  1130. if(param.valIdx == -1)
  1131. {
  1132. for (int i = 0; i < animNames.Length; i++)
  1133. {
  1134. if (param.val == animNames[i])
  1135. {
  1136. param.valIdx = i;
  1137. break;
  1138. }
  1139. }
  1140. }
  1141. int frameCnt = 0;
  1142. param.valIdx = EditorGUILayout.Popup(param.valIdx, animNames, GUILayout.Width(200));
  1143. if (param.valIdx >= 0) {
  1144. param.val = animNames[param.valIdx];
  1145. if(stateMachine != null)
  1146. {
  1147. Motion motion = stateMachine.states[param.valIdx].state.motion;
  1148. if (motion != null)
  1149. {
  1150. frameCnt = (int)(motion.averageDuration * 30);
  1151. }
  1152. }
  1153. }
  1154. EditorGUILayout.LabelField(param.val.ToString(), paramStyle, GUILayout.Width(100));
  1155. EditorGUILayout.LabelField(frameCnt.ToString(), selectedItemStyle, GUILayout.Width(80));
  1156. }
  1157. }
  1158. else
  1159. {
  1160. EditorGUILayout.LabelField("参数数值:", paramStyle, GUILayout.Width(100)); param.val = EditorGUILayout.TextField(param.val, GUILayout.Width(200));
  1161. }
  1162. EditorGUILayout.LabelField("数值类型:", paramStyle, GUILayout.Width(100)); param.valTypeIdx = EditorGUILayout.Popup(param.valTypeIdx,s_valTypes, GUILayout.Width(150));
  1163. if (param.valTypeIdx >= 0)
  1164. param.valType = s_valTypes[param.valTypeIdx];
  1165. else
  1166. param.valType = "";
  1167. EditorGUILayout.EndHorizontal();
  1168. }
  1169. public void ResetData()
  1170. {
  1171. if(curSkillIdx >= 0 && curSkillIdx<m_miniLevelSkills.Count)
  1172. {
  1173. currentSkillAsset = m_miniLevelSkills[curSkillIdx];
  1174. }
  1175. else
  1176. {
  1177. curSkillIdx = -1;
  1178. currentSkillAsset = null;
  1179. }
  1180. if(curEventTemplateIdx>=0 && curEventTemplateIdx < s_template_events.Count)
  1181. {
  1182. curSelectedEventTemplate = s_template_events[curEventTemplateIdx];
  1183. }
  1184. else
  1185. {
  1186. curEventTemplateIdx = -1;
  1187. curSelectedEventTemplate = null;
  1188. }
  1189. }
  1190. void SaveCurrentBuffFrameEvent(BuffDataAsset buffDataAsset)
  1191. {
  1192. if (buffDataAsset == null || buffDataAsset.id == 0) return;
  1193. string buffFrameEventFileName = string.Format("{0}/Content/Xml/buff_{1}.xml", Application.dataPath, buffDataAsset.id);
  1194. SecurityElement root = new SecurityElement("FrameEvent");
  1195. SecurityElement buffNode = buffDataAsset.SaveFrameEventToXml();
  1196. if (buffNode != null)
  1197. {
  1198. root.AddChild(buffNode);
  1199. }
  1200. SecurityElement femaleBuffNode = buffDataAsset.SaveFemaleFrameEventToXml();
  1201. if(femaleBuffNode!=null)
  1202. {
  1203. root.AddChild(femaleBuffNode);
  1204. }
  1205. SecurityTools.DumpSecurityElementToXml(root, buffFrameEventFileName);
  1206. }
  1207. #endregion
  1208. static BuffDataAsset GetBuffAsset(int buffId)
  1209. {
  1210. for(int idx =0; idx < m_buffs.Count;idx++)
  1211. {
  1212. if (m_buffs[idx].id == buffId)
  1213. return m_buffs[idx];
  1214. }
  1215. return null;
  1216. }
  1217. public static ActionEventDataEditor GetActionEventData(int id, int gender = 2)
  1218. {
  1219. int uniqueId = id * 10 + gender;
  1220. ActionEventDataEditor data = null;
  1221. if (s_ActionEventDic.TryGetValue(uniqueId, out data))
  1222. {
  1223. return data;
  1224. }
  1225. return null;
  1226. }
  1227. static int GetValueTypeIndex(string valType)
  1228. {
  1229. for(int idx = 0; idx < s_valTypes.Length;idx++)
  1230. {
  1231. if (s_valTypes[idx] == valType) return idx;
  1232. }
  1233. return -1;
  1234. }
  1235. static int GetIconIdx(string name)
  1236. {
  1237. string pureName = FileUtils.ExtractPureName(name);
  1238. if (string.IsNullOrEmpty(name)) return -1;
  1239. for (int idx = 0; idx < m_icons.Count; idx++)
  1240. {
  1241. if (string.Compare(m_icons[idx], pureName) == 0)
  1242. return idx;
  1243. }
  1244. return -1;
  1245. }
  1246. public static void AddFunEventToBuff(int buffId,FunctionDataAsset funAsset)
  1247. {
  1248. GetPanel().AddFunToSkillBuff(buffId,funAsset);
  1249. }
  1250. public static int GetEffectIdx(int effectId)
  1251. {
  1252. if (effectId <= 0) return -1;
  1253. for (int idx = 0; idx < m_effects.Count; idx++)
  1254. {
  1255. if (m_effects[idx].id == effectId)
  1256. return idx;
  1257. }
  1258. return -1;
  1259. }
  1260. public void AddFunToSkillBuff(int buffId, FunctionDataAsset funAsset)
  1261. {
  1262. if (currentSkillAsset == null) return;
  1263. currentSkillAsset.AddFunEventToBuff(buffId, funAsset);
  1264. }
  1265. }