AnimChangeSkinStateEditor.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using UnityEngine;
  5. using UnityEditor;
  6. using UnityEditor.Animations;
  7. using UnityEditorInternal;
  8. using AnimatorController = UnityEditor.Animations.AnimatorController;
  9. using LuaInterface;
  10. [CustomEditor(typeof(AnimChangeSkinState))]
  11. public class AnimChangeSkinStateEditor : Editor
  12. {
  13. private SerializedProperty m_Script;
  14. private SerializedProperty m_SkinSlotTypes;
  15. private SerializedProperty m_RoleAvatarIds;
  16. private int m_ArraySize = 0;
  17. private ReorderableList m_ReorderableList;
  18. private Dictionary<int, string> m_SkinSlotTypeNames = new Dictionary<int, string>()
  19. {
  20. [1] = "头上",
  21. [2] = "头中",
  22. [3] = "头下",
  23. [4] = "衣服",
  24. [5] = "左手",
  25. [6] = "右手",
  26. [7] = "背部",
  27. [8] = "发型",
  28. [9] = "瞳孔",
  29. [100] = "头发颜色",
  30. [101] = "脸型",
  31. };
  32. private const string c_RoleAvatarCfgPath = "Assets/Lua/Config/RoleAvatarCfg.lua";
  33. private Dictionary<int, string> m_AvatarIdMap = new Dictionary<int, string>();
  34. private void OnEnable() {
  35. m_Script = serializedObject.FindProperty("m_Script");
  36. m_SkinSlotTypes = serializedObject.FindProperty("m_SkinSlotTypes");
  37. m_RoleAvatarIds = serializedObject.FindProperty("m_RoleAvatarIds");
  38. if (Application.isPlaying) return;
  39. m_AvatarIdMap.Clear();
  40. using (LuaState luaState = new LuaState())
  41. {
  42. try
  43. {
  44. luaState.Start();
  45. using (LuaTable luaTable = luaState.DoFile<LuaTable>(c_RoleAvatarCfgPath))
  46. {
  47. try
  48. {
  49. using (LuaDictTable<int, LuaTable> luaDictTable = luaTable.ToDictTable<int, LuaTable>())
  50. {
  51. try
  52. {
  53. foreach (var item in luaDictTable)
  54. {
  55. int id = item.Key;
  56. string name = item.Value["AvatarPrefab"].ToString();
  57. if (!string.IsNullOrEmpty(name))
  58. {
  59. if (m_AvatarIdMap.ContainsKey(id))
  60. {
  61. Debug.LogError(c_RoleAvatarCfgPath + " 存在相同的Id " + id);
  62. }
  63. else
  64. {
  65. m_AvatarIdMap.Add(id, name);
  66. }
  67. }
  68. }
  69. }
  70. catch (System.Exception e)
  71. {
  72. Debug.LogException(e);
  73. }
  74. }
  75. }
  76. catch (System.Exception e)
  77. {
  78. Debug.LogException(e);
  79. }
  80. }
  81. }
  82. catch (System.Exception e)
  83. {
  84. Debug.LogException(e);
  85. }
  86. }
  87. // 检查错误数据
  88. SerializedObjectUpdate();
  89. for (int j = m_SkinSlotTypes.arraySize - 1; j >= 0; j--)
  90. {
  91. int skinSlotType = m_SkinSlotTypes.GetArrayElementAtIndex(j).intValue;
  92. if (!m_SkinSlotTypeNames.ContainsKey(skinSlotType))
  93. {
  94. m_SkinSlotTypes.DeleteArrayElementAtIndex(j);
  95. m_RoleAvatarIds.DeleteArrayElementAtIndex(j);
  96. }
  97. }
  98. SerializedObjectApply();
  99. int arraySize1 = m_SkinSlotTypes.arraySize;
  100. int arraySize2 = m_RoleAvatarIds.arraySize;
  101. m_ArraySize = Mathf.Min(arraySize1, arraySize2, m_SkinSlotTypeNames.Count);
  102. m_ReorderableList = new ReorderableList(serializedObject, m_SkinSlotTypes);
  103. m_ReorderableList.drawHeaderCallback = ReorderableListHeaderCallback;
  104. m_ReorderableList.drawElementCallback = ReorderableListElementCallback;
  105. m_ReorderableList.onCanAddCallback = ReorderableListCanAddCallback;
  106. m_ReorderableList.onAddDropdownCallback = ReorderableListAddDropdownCallback;
  107. m_ReorderableList.onRemoveCallback = ReorderableListRemoveCallback;
  108. }
  109. public override void OnInspectorGUI()
  110. {
  111. SerializedObjectUpdate();
  112. bool defaultEnable = GUI.enabled;
  113. GUI.enabled = false;
  114. EditorGUILayout.PropertyField(m_Script);
  115. GUI.enabled = defaultEnable;
  116. if (Application.isPlaying)
  117. {
  118. EditorGUILayout.Space();
  119. EditorGUILayout.HelpBox("目前只能在非播放模式下编辑", MessageType.Warning);
  120. EditorGUILayout.Space();
  121. }
  122. else
  123. {
  124. m_ReorderableList.DoLayoutList();
  125. }
  126. SerializedObjectApply();
  127. }
  128. private void SerializedObjectUpdate()
  129. {
  130. serializedObject.Update();
  131. }
  132. private void SerializedObjectApply()
  133. {
  134. if (serializedObject.ApplyModifiedProperties())
  135. {
  136. foreach (var item in targets)
  137. {
  138. EditorUtility.SetDirty(item);
  139. }
  140. }
  141. }
  142. public void ReorderableListHeaderCallback(Rect rect)
  143. {
  144. EditorGUI.LabelField(rect, "修改角色皮肤列表");
  145. }
  146. public void ReorderableListElementCallback(Rect rect, int index, bool isActive, bool isFocused)
  147. {
  148. int skinSlotType = m_SkinSlotTypes.GetArrayElementAtIndex(index).intValue;
  149. int avatarId = m_RoleAvatarIds.GetArrayElementAtIndex(index).intValue;
  150. Rect rect1 = new Rect(rect.x, rect.y, 50, rect.height);
  151. Rect rect2 = new Rect(rect.x + 50, rect.y, 50, rect.height);
  152. Rect rect3 = new Rect(rect.x + 105, rect.y, rect.width - 105, rect.height);
  153. EditorGUI.LabelField(rect1, m_SkinSlotTypeNames[skinSlotType]);
  154. int avatarIdTemp = EditorGUI.DelayedIntField(rect2, avatarId);
  155. if (avatarIdTemp != avatarId)
  156. {
  157. avatarId = avatarIdTemp;
  158. m_RoleAvatarIds.GetArrayElementAtIndex(index).intValue = avatarId;
  159. }
  160. if (m_AvatarIdMap.ContainsKey(avatarId))
  161. {
  162. EditorGUI.LabelField(rect3, m_AvatarIdMap[avatarId]);
  163. }
  164. else
  165. {
  166. if (avatarId == 0)
  167. {
  168. EditorGUI.LabelField(rect3, "重置默认值");
  169. }
  170. else if (avatarId == 99999)
  171. {
  172. EditorGUI.LabelField(rect3, "隐藏");
  173. }
  174. else
  175. {
  176. EditorGUI.LabelField(rect3, "当配置中无法找到资源, 也会隐藏");
  177. }
  178. }
  179. Event evt = Event.current;
  180. if (evt.type == EventType.DragUpdated)
  181. {
  182. if (rect.Contains(evt.mousePosition))
  183. {
  184. DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
  185. }
  186. }
  187. else if (evt.type == EventType.DragPerform)
  188. {
  189. if (rect.Contains(evt.mousePosition))
  190. {
  191. DragAndDrop.AcceptDrag();
  192. if (DragAndDrop.objectReferences != null && DragAndDrop.objectReferences.Length > 0)
  193. {
  194. GameObject go = DragAndDrop.objectReferences[0] as GameObject;
  195. if (go)
  196. {
  197. string path = AssetDatabase.GetAssetPath(go);
  198. if (!string.IsNullOrEmpty(path))
  199. {
  200. path = path.Replace("\\", "/");
  201. path = path.Replace(".prefab", "");
  202. string name = path.Replace(Constants.ModelPath + "/", "");
  203. if (!string.IsNullOrEmpty(name))
  204. {
  205. int id = 0;
  206. foreach (var item in m_AvatarIdMap)
  207. {
  208. if (item.Value == name)
  209. {
  210. id = item.Key;
  211. Debug.LogError(id);
  212. break;
  213. }
  214. }
  215. if (id != 0)
  216. {
  217. avatarId = id;
  218. m_RoleAvatarIds.GetArrayElementAtIndex(index).intValue = id;
  219. }
  220. }
  221. }
  222. }
  223. }
  224. }
  225. }
  226. else if (evt.type == EventType.MouseDown)
  227. {
  228. if (rect.Contains(evt.mousePosition))
  229. {
  230. if (m_AvatarIdMap.ContainsKey(avatarId))
  231. {
  232. string path = Constants.ModelPath + "/" + m_AvatarIdMap[avatarId] + ".prefab";
  233. GameObject go = AssetDatabase.LoadAssetAtPath<GameObject>(path);
  234. if (go) EditorGUIUtility.PingObject(go);
  235. }
  236. }
  237. }
  238. }
  239. public bool ReorderableListCanAddCallback(ReorderableList list)
  240. {
  241. return m_SkinSlotTypeNames.Count > list.count;
  242. }
  243. public void ReorderableListAddDropdownCallback(Rect buttonRect, ReorderableList list)
  244. {
  245. GenericMenu genericMenu = new GenericMenu();
  246. int[] arr = new int[m_SkinSlotTypeNames.Count];
  247. m_SkinSlotTypeNames.Keys.CopyTo(arr, 0);
  248. bool isContain = false;
  249. for (int i = 0; i < arr.Length; i++)
  250. {
  251. isContain = false;
  252. for (int j = m_SkinSlotTypes.arraySize - 1; j >= 0; j--)
  253. {
  254. if (arr[i] == m_SkinSlotTypes.GetArrayElementAtIndex(j).intValue)
  255. {
  256. isContain = true;
  257. break;
  258. }
  259. }
  260. if (isContain) continue;
  261. genericMenu.AddItem(EditorGUIUtility.TrTextContent(m_SkinSlotTypeNames[arr[i]]), false, (skinSlotType) =>
  262. {
  263. SerializedObjectUpdate();
  264. m_SkinSlotTypes.arraySize++;
  265. m_RoleAvatarIds.arraySize++;
  266. list.index = m_SkinSlotTypes.arraySize - 1;
  267. m_SkinSlotTypes.GetArrayElementAtIndex(list.index).intValue = (int)skinSlotType;
  268. SerializedObjectApply();
  269. }, arr[i]);
  270. }
  271. genericMenu.ShowAsContext();
  272. }
  273. public void ReorderableListRemoveCallback(ReorderableList list)
  274. {
  275. int index = list.index;
  276. m_SkinSlotTypes.DeleteArrayElementAtIndex(index);
  277. m_RoleAvatarIds.DeleteArrayElementAtIndex(index);
  278. }
  279. }