UnityEditor.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. using System.Collections.Generic;
  2. using System.IO;
  3. using UnityEngine;
  4. using UnityEditor;
  5. using UnityEditorInternal;
  6. using System.Reflection;
  7. //using UnityEditor.SceneManagement;
  8. using System.Text.RegularExpressions;
  9. namespace DragonBones
  10. {
  11. /**
  12. * @private
  13. */
  14. [CustomEditor(typeof(UnityArmatureComponent))]
  15. public class UnityArmatureEditor : Editor
  16. {
  17. [MenuItem("GameObject/DragonBones/Armature Object", false, 10)]
  18. private static void _createArmatureObjectMenuItem()
  19. {
  20. _createEmptyObject(_getSelectionParentTransform());
  21. }
  22. #region 右键JSON创建对应的Prefab
  23. [MenuItem("Assets/Create/DragonBones/Armature Object", true)]
  24. private static bool _createArmatureObjectFromJSONValidateMenuItem()
  25. {
  26. return _getDragonBonesJSONPaths().Count > 0;
  27. }
  28. [MenuItem("Assets/Create/DragonBones/Armature Object", false, 10)]
  29. private static void _createArmatureObjectFromJSONMenuItem()
  30. {
  31. var parentTransform = _getSelectionParentTransform();
  32. foreach (var dragonBonesJSONPath in _getDragonBonesJSONPaths())
  33. {
  34. var armatureComponent = _createEmptyObject(parentTransform);
  35. var dragonBonesJSON = AssetDatabase.LoadMainAssetAtPath(dragonBonesJSONPath) as TextAsset;
  36. _changeDragonBonesData(armatureComponent, dragonBonesJSON);
  37. }
  38. }
  39. private static List<string> _getDragonBonesJSONPaths()
  40. {
  41. var dragonBonesJSONPaths = new List<string>();
  42. foreach (var guid in Selection.assetGUIDs)
  43. {
  44. var assetPath = AssetDatabase.GUIDToAssetPath(guid);
  45. if (assetPath.EndsWith(".json"))
  46. {
  47. var jsonCode = File.ReadAllText(assetPath);
  48. if (jsonCode.IndexOf("\"armature\":") > 0)
  49. {
  50. dragonBonesJSONPaths.Add(assetPath);
  51. }
  52. }
  53. }
  54. return dragonBonesJSONPaths;
  55. }
  56. #endregion
  57. private static UnityArmatureComponent _createEmptyObject(UnityEngine.Transform parentTransform)
  58. {
  59. var gameObject = new GameObject("New Armature Object", typeof(UnityArmatureComponent));
  60. var armatureComponent = gameObject.GetComponent<UnityArmatureComponent>();
  61. gameObject.transform.SetParent(parentTransform, false);
  62. //
  63. EditorUtility.FocusProjectWindow();
  64. Selection.activeObject = gameObject;
  65. EditorGUIUtility.PingObject(Selection.activeObject);
  66. Undo.RegisterCreatedObjectUndo(gameObject, "Create Armature Object");
  67. //EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
  68. return armatureComponent;
  69. }
  70. private static void _getTextureAtlasConfigs(List<string> textureAtlasFiles, string filePath, string rawName = null, string suffix = "tex")
  71. {
  72. var folder = Directory.GetParent(filePath).ToString();
  73. var name = rawName != null ? rawName : filePath.Substring(0, filePath.LastIndexOf(".")).Substring(filePath.LastIndexOf("/") + 1);
  74. int index = 0;
  75. var textureAtlasName = "";
  76. var textureAtlasConfigFile = "";
  77. textureAtlasName = !string.IsNullOrEmpty(name) ? name + (!string.IsNullOrEmpty(suffix) ? "_" + suffix : suffix) : suffix;
  78. textureAtlasConfigFile = folder + "/" + textureAtlasName + ".json";
  79. if (File.Exists(textureAtlasConfigFile))
  80. {
  81. textureAtlasFiles.Add(textureAtlasConfigFile);
  82. return;
  83. }
  84. if (textureAtlasFiles.Count > 0 || rawName != null)
  85. {
  86. return;
  87. }
  88. while (true)
  89. {
  90. textureAtlasName = (!string.IsNullOrEmpty(name) ? name + (!string.IsNullOrEmpty(suffix) ? "_" + suffix : suffix) : suffix) + "_" + (index++);
  91. textureAtlasConfigFile = folder + "/" + textureAtlasName + ".json";
  92. if (File.Exists(textureAtlasConfigFile))
  93. {
  94. textureAtlasFiles.Add(textureAtlasConfigFile);
  95. }
  96. else if (index > 1)
  97. {
  98. break;
  99. }
  100. }
  101. _getTextureAtlasConfigs(textureAtlasFiles, filePath, "", suffix);
  102. if (textureAtlasFiles.Count > 0)
  103. {
  104. return;
  105. }
  106. index = name.LastIndexOf("_");
  107. if (index >= 0)
  108. {
  109. name = name.Substring(0, index);
  110. _getTextureAtlasConfigs(textureAtlasFiles, filePath, name, suffix);
  111. if (textureAtlasFiles.Count > 0)
  112. {
  113. return;
  114. }
  115. _getTextureAtlasConfigs(textureAtlasFiles, filePath, name, "");
  116. if (textureAtlasFiles.Count > 0)
  117. {
  118. return;
  119. }
  120. }
  121. if (suffix != "texture")
  122. {
  123. _getTextureAtlasConfigs(textureAtlasFiles, filePath, null, "texture");
  124. }
  125. }
  126. private static bool _changeDragonBonesData(UnityArmatureComponent _armatureComponent, TextAsset dragonBoneJSON)
  127. {
  128. if (dragonBoneJSON != null)
  129. {
  130. var textureAtlasJSONs = new List<string>();
  131. _getTextureAtlasConfigs(textureAtlasJSONs, AssetDatabase.GetAssetPath(dragonBoneJSON.GetInstanceID()));
  132. var dragonBonesData = _armatureComponent.LoadData(dragonBoneJSON, textureAtlasJSONs);
  133. if (dragonBonesData != null)
  134. {
  135. Undo.RecordObject(_armatureComponent, "Set DragonBones");
  136. _armatureComponent.dragonBonesJSON = dragonBoneJSON;
  137. _armatureComponent.textureAtlasJSON = textureAtlasJSONs;
  138. var armatureName = dragonBonesData.armatureNames[0];
  139. _changeArmatureData(_armatureComponent, armatureName, dragonBonesData.name);
  140. _armatureComponent.gameObject.name = armatureName;
  141. EditorUtility.SetDirty(_armatureComponent);
  142. return true;
  143. }
  144. else
  145. {
  146. EditorUtility.DisplayDialog("Error", "Could not load dragonBones data.", "OK", null);
  147. return false;
  148. }
  149. }
  150. else if (_armatureComponent.dragonBonesJSON != null)
  151. {
  152. Undo.RecordObject(_armatureComponent, "Set DragonBones");
  153. _armatureComponent.dragonBonesJSON = null;
  154. if (_armatureComponent.armature != null)
  155. {
  156. _armatureComponent.Dispose(false);
  157. }
  158. EditorUtility.SetDirty(_armatureComponent);
  159. return true;
  160. }
  161. return false;
  162. }
  163. private static void _changeArmatureData(UnityArmatureComponent _armatureComponent, string armatureName, string dragonBonesName)
  164. {
  165. Slot slot = null;
  166. if (_armatureComponent.armature != null)
  167. {
  168. slot = _armatureComponent.armature.parent;
  169. _armatureComponent.Dispose(false);
  170. }
  171. _armatureComponent.armatureName = armatureName;
  172. _armatureComponent = UnityFactory.factory.BuildArmatureComponent(_armatureComponent.armatureName, dragonBonesName, null, null, _armatureComponent.gameObject);
  173. if (slot != null)
  174. {
  175. slot.childArmature = _armatureComponent.armature;
  176. }
  177. _armatureComponent.sortingLayerName = _armatureComponent.sortingLayerName;
  178. _armatureComponent.sortingOrder = _armatureComponent.sortingOrder;
  179. }
  180. private static void _clearGameObjectChildren(GameObject gameObject)
  181. {
  182. var children = new List<GameObject>();
  183. int childCount = gameObject.transform.childCount;
  184. for (int i = 0; i < childCount; ++i)
  185. {
  186. var child = gameObject.transform.GetChild(i).gameObject;
  187. children.Add(child);
  188. }
  189. for (int i = 0; i < childCount; ++i)
  190. {
  191. var child = children[i];
  192. #if UNITY_EDITOR
  193. Object.DestroyImmediate(child);
  194. #else
  195. Object.Destroy(child);
  196. #endif
  197. }
  198. }
  199. private static List<string> _getSortingLayerNames()
  200. {
  201. var internalEditorUtilityType = typeof(InternalEditorUtility);
  202. var sortingLayersProperty = internalEditorUtilityType.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic);
  203. return new List<string>(sortingLayersProperty.GetValue(null, new object[0]) as string[]);
  204. }
  205. private static UnityEngine.Transform _getSelectionParentTransform()
  206. {
  207. var parent = Selection.activeObject as GameObject;
  208. return parent != null ? parent.transform : null;
  209. }
  210. private int _armatureIndex = -1;
  211. private int _animationIndex = -1;
  212. private int _sortingLayerIndex = -1;
  213. private long _nowTime = 0;
  214. private TextAsset _dragonBoneJSON = null;
  215. private List<string> _armatureNames = null;
  216. private List<string> _animationNames = null;
  217. private List<string> _sortingLayerNames = null;
  218. private UnityArmatureComponent _armatureComponent = null;
  219. void OnEnable()
  220. {
  221. _armatureComponent = target as UnityArmatureComponent;
  222. _dragonBoneJSON = _armatureComponent == null ? null : _armatureComponent.dragonBonesJSON; //
  223. //
  224. _nowTime = System.DateTime.Now.Ticks;
  225. _sortingLayerNames = _getSortingLayerNames();
  226. _sortingLayerIndex = _sortingLayerNames.IndexOf(_armatureComponent.sortingLayerName);
  227. // Update armature.
  228. if (
  229. !EditorApplication.isPlayingOrWillChangePlaymode &&
  230. _armatureComponent.armature == null &&
  231. _armatureComponent.dragonBonesJSON != null &&
  232. !string.IsNullOrEmpty(_armatureComponent.armatureName)
  233. )
  234. {
  235. // Load data.
  236. var dragonBonesData = _armatureComponent.LoadData(_armatureComponent.dragonBonesJSON, _armatureComponent.textureAtlasJSON);
  237. // Refresh texture atlas.
  238. UnityFactory.factory.RefreshAllTextureAtlas();
  239. // Refresh armature.
  240. _changeArmatureData(_armatureComponent, _armatureComponent.armatureName, dragonBonesData.name);
  241. // Refresh texture.
  242. _armatureComponent.armature.InvalidUpdate(null, true);
  243. // Play animation.
  244. if (!string.IsNullOrEmpty(_armatureComponent.animationName))
  245. {
  246. _armatureComponent.animation.Play(_armatureComponent.animationName);
  247. }
  248. }
  249. // Update hideFlags.
  250. if (!EditorApplication.isPlayingOrWillChangePlaymode &&
  251. _armatureComponent.armature != null &&
  252. _armatureComponent.armature.parent != null
  253. )
  254. {
  255. _armatureComponent.gameObject.hideFlags = HideFlags.NotEditable;
  256. }
  257. else
  258. {
  259. _armatureComponent.gameObject.hideFlags = HideFlags.None;
  260. }
  261. //
  262. _updateParameters();
  263. }
  264. public override void OnInspectorGUI()
  265. {
  266. // DragonBones Data
  267. EditorGUILayout.BeginHorizontal();
  268. _dragonBoneJSON = EditorGUILayout.ObjectField("DragonBones Data", _dragonBoneJSON, typeof(TextAsset), false) as TextAsset;
  269. var created = false;
  270. if (_dragonBoneJSON != null)
  271. {
  272. if (_armatureComponent.armature == null)
  273. {
  274. if (GUILayout.Button("Create"))
  275. {
  276. created = true;
  277. }
  278. }
  279. else if (_armatureComponent.dragonBonesJSON != _dragonBoneJSON)
  280. {
  281. if (GUILayout.Button("Change"))
  282. {
  283. created = true;
  284. }
  285. }
  286. }
  287. else if (_armatureComponent.dragonBonesJSON != null)
  288. {
  289. created = true;
  290. }
  291. if (created)
  292. {
  293. var currentDragonBoneJSON = _armatureComponent.dragonBonesJSON;
  294. if (_changeDragonBonesData(_armatureComponent, _dragonBoneJSON))
  295. {
  296. _updateParameters();
  297. }
  298. else
  299. {
  300. _dragonBoneJSON = currentDragonBoneJSON;
  301. }
  302. }
  303. EditorGUILayout.EndHorizontal();
  304. EditorGUILayout.Space();
  305. if (_armatureComponent.armature != null)
  306. {
  307. var dragonBonesData = _armatureComponent.armature.armatureData.parent;
  308. // Armature
  309. if (UnityFactory.factory.GetAllDragonBonesData().ContainsValue(dragonBonesData) && _armatureNames != null)
  310. {
  311. var armatureIndex = EditorGUILayout.Popup("Armature", _armatureIndex, _armatureNames.ToArray());
  312. if (_armatureIndex != armatureIndex)
  313. {
  314. _armatureIndex = armatureIndex;
  315. //_clearGameObjectChildren(_armatureComponent.gameObject);
  316. var armatureName = _armatureNames[_armatureIndex];
  317. _changeArmatureData(_armatureComponent, armatureName, dragonBonesData.name);
  318. _updateParameters();
  319. _armatureComponent.gameObject.name = armatureName;
  320. EditorUtility.SetDirty(_armatureComponent);
  321. }
  322. }
  323. // Animation
  324. if (_animationNames != null && _animationNames.Count > 0)
  325. {
  326. EditorGUILayout.BeginHorizontal();
  327. var animationIndex = EditorGUILayout.Popup("Animation", _animationIndex, _animationNames.ToArray());
  328. if (animationIndex != _animationIndex)
  329. {
  330. _animationIndex = animationIndex;
  331. _armatureComponent.animationName = _animationNames[animationIndex];
  332. _armatureComponent.animation.Play(_armatureComponent.animationName);
  333. _updateParameters();
  334. EditorUtility.SetDirty(_armatureComponent);
  335. }
  336. if (_animationIndex >= 0)
  337. {
  338. if (_armatureComponent.animation.isPlaying)
  339. {
  340. if (GUILayout.Button("Stop"))
  341. {
  342. _armatureComponent.animation.Stop();
  343. }
  344. }
  345. else
  346. {
  347. if (GUILayout.Button("Play"))
  348. {
  349. _armatureComponent.animation.Play();
  350. }
  351. }
  352. }
  353. EditorGUILayout.EndHorizontal();
  354. }
  355. EditorGUILayout.Space();
  356. // Sorting Layer
  357. _sortingLayerIndex = EditorGUILayout.Popup("Sorting Layer", _sortingLayerIndex, _sortingLayerNames.ToArray());
  358. if (_sortingLayerNames[_sortingLayerIndex] != _armatureComponent.sortingLayerName)
  359. {
  360. Undo.RecordObject(_armatureComponent, "Sorting Layer");
  361. _armatureComponent.sortingLayerName = _sortingLayerNames[_sortingLayerIndex];
  362. EditorUtility.SetDirty(_armatureComponent);
  363. }
  364. // Sorting Order
  365. var sortingOrder = EditorGUILayout.IntField("Order in Layer", _armatureComponent.sortingOrder);
  366. if (sortingOrder != _armatureComponent.sortingOrder)
  367. {
  368. Undo.RecordObject(_armatureComponent, "Edit Sorting Order");
  369. _armatureComponent.sortingOrder = sortingOrder;
  370. EditorUtility.SetDirty(_armatureComponent);
  371. }
  372. // ZSpace
  373. EditorGUILayout.BeginHorizontal();
  374. _armatureComponent.zSpace = EditorGUILayout.Slider("Z Space", _armatureComponent.zSpace, 0.0f, 0.2f);
  375. EditorGUILayout.EndHorizontal();
  376. // TimeScale
  377. EditorGUILayout.BeginHorizontal();
  378. _armatureComponent.animation.timeScale = EditorGUILayout.Slider("Time Scale", _armatureComponent.animation.timeScale, 0.0f, 2.0f);
  379. EditorGUILayout.EndHorizontal();
  380. // Flip
  381. /*EditorGUILayout.BeginHorizontal();
  382. EditorGUILayout.PrefixLabel("Flip");
  383. _armatureComponent.flipX = GUILayout.Toggle(_armatureComponent.flipX, "X");
  384. _armatureComponent.flipY = GUILayout.Toggle(_armatureComponent.flipY, "Y");
  385. EditorGUILayout.EndHorizontal();*/
  386. EditorGUILayout.Space();
  387. }
  388. if (!EditorApplication.isPlayingOrWillChangePlaymode && Selection.activeObject == _armatureComponent.gameObject)
  389. {
  390. EditorUtility.SetDirty(_armatureComponent);
  391. HandleUtility.Repaint();
  392. }
  393. }
  394. void OnSceneGUI()
  395. {
  396. if (!EditorApplication.isPlayingOrWillChangePlaymode && _armatureComponent.armature != null)
  397. {
  398. var dt = System.DateTime.Now.Ticks - _nowTime;
  399. if (dt >= 1.0f / _armatureComponent.armature.armatureData.frameRate * 1000000.0f)
  400. {
  401. _armatureComponent.armature.AdvanceTime(dt * 0.0000001f);
  402. _nowTime = System.DateTime.Now.Ticks;
  403. }
  404. }
  405. }
  406. private void _updateParameters()
  407. {
  408. _dragonBoneJSON = _armatureComponent.dragonBonesJSON;
  409. if (_armatureComponent.armature != null)
  410. {
  411. _armatureNames = _armatureComponent.armature.armatureData.parent.armatureNames;
  412. _animationNames = _armatureComponent.armature.armatureData.animationNames;
  413. _armatureIndex = _armatureNames.IndexOf(_armatureComponent.armature.name);
  414. _animationIndex = _animationNames.IndexOf(_armatureComponent.armature.animation.lastAnimationName);
  415. }
  416. else
  417. {
  418. _armatureNames = null;
  419. _animationNames = null;
  420. _armatureIndex = -1;
  421. _animationIndex = -1;
  422. }
  423. }
  424. }
  425. }