UnityFactory.cs 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185
  1. /**
  2. * The MIT License (MIT)
  3. *
  4. * Copyright (c) 2012-2017 DragonBones team and other contributors
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  7. * this software and associated documentation files (the "Software"), to deal in
  8. * the Software without restriction, including without limitation the rights to
  9. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10. * the Software, and to permit persons to whom the Software is furnished to do so,
  11. * subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all
  14. * copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. using System.Collections.Generic;
  24. using UnityEngine;
  25. #if UNITY_EDITOR
  26. using UnityEditor;
  27. #endif
  28. namespace DragonBones
  29. {
  30. /// <pjrivate/>
  31. internal class ClockHandler : MonoBehaviour
  32. {
  33. void Update()
  34. {
  35. UnityFactory.factory._dragonBones.AdvanceTime(Time.deltaTime);
  36. }
  37. }
  38. /// <summary>
  39. /// The Egret factory.
  40. /// </summary>
  41. /// <version>DragonBones 3.0</version>
  42. /// <language>en_US</language>
  43. ///
  44. /// <summary>
  45. /// Egret 工厂。
  46. /// </summary>
  47. /// <version>DragonBones 3.0</version>
  48. /// <language>zh_CN</language>
  49. public class UnityFactory : BaseFactory
  50. {
  51. /// <summary>
  52. /// 创建材质时默认使用的 shader。
  53. /// </summary>
  54. /// <version>DragonBones 4.7</version>
  55. /// <language>zh_CN</language>
  56. internal const string defaultShaderName = "Sprites/Default";
  57. /// <summary>
  58. /// 创建UI材质时默认使用的 shader。
  59. /// </summary>
  60. /// <version>DragonBones 4.7</version>
  61. /// <language>zh_CN</language>
  62. internal const string defaultUIShaderName = "UI/Default";
  63. internal static DragonBones _dragonBonesInstance = null;
  64. private static UnityFactory _factory = null;
  65. private static GameObject _gameObject = null;
  66. //
  67. private GameObject _armatureGameObject = null;
  68. private bool _isUGUI = false;
  69. //
  70. private readonly List<UnityDragonBonesData> _cacheUnityDragonBonesData = new List<UnityDragonBonesData>();
  71. /// <summary>
  72. /// A global factory instance that can be used directly.
  73. /// </summary>
  74. /// <version>DragonBones 4.7</version>
  75. /// <language>en_US</language>
  76. /// <summary>
  77. /// 一个可以直接使用的全局工厂实例。
  78. /// </summary>
  79. /// <version>DragonBones 4.7</version>
  80. /// <language>zh_CN</language>
  81. public static UnityFactory factory
  82. {
  83. get
  84. {
  85. if (_factory == null)
  86. {
  87. _factory = new UnityFactory();
  88. }
  89. return _factory;
  90. }
  91. }
  92. /// <inheritDoc/>
  93. public UnityFactory(DataParser dataParser = null) : base(dataParser)
  94. {
  95. Init();
  96. }
  97. private void Init()
  98. {
  99. if (Application.isPlaying)
  100. {
  101. if (_gameObject == null)
  102. {
  103. _gameObject = GameObject.Find("DragonBones Object");
  104. if (_gameObject == null)
  105. {
  106. _gameObject = new GameObject("DragonBones Object", typeof(ClockHandler));
  107. _gameObject.isStatic = true;
  108. _gameObject.hideFlags = HideFlags.HideInHierarchy;
  109. }
  110. }
  111. //全局的
  112. GameObject.DontDestroyOnLoad(_gameObject);
  113. var clockHandler = _gameObject.GetComponent<ClockHandler>();
  114. if (clockHandler == null)
  115. {
  116. _gameObject.AddComponent<ClockHandler>();
  117. }
  118. var eventManager = _gameObject.GetComponent<DragonBoneEventDispatcher>();
  119. if (eventManager == null)
  120. {
  121. eventManager = _gameObject.AddComponent<DragonBoneEventDispatcher>();
  122. }
  123. if (_dragonBonesInstance == null)
  124. {
  125. _dragonBonesInstance = new DragonBones(eventManager);
  126. //
  127. DragonBones.yDown = false;
  128. }
  129. }
  130. else
  131. {
  132. if (_dragonBonesInstance == null)
  133. {
  134. _dragonBonesInstance = new DragonBones(null);
  135. //
  136. DragonBones.yDown = false;
  137. }
  138. }
  139. _dragonBones = _dragonBonesInstance;
  140. }
  141. /// <inheritDoc/>
  142. protected override TextureAtlasData _BuildTextureAtlasData(TextureAtlasData textureAtlasData, object textureAtlas)
  143. {
  144. if (textureAtlasData != null)
  145. {
  146. if (textureAtlas != null)
  147. {
  148. //if ((textureAtlas as Material).name.IndexOf("UI_Mat") > -1)
  149. //{
  150. // (textureAtlasData as UnityTextureAtlasData).uiTexture = textureAtlas as Material;
  151. //}
  152. //else
  153. //{
  154. // (textureAtlasData as UnityTextureAtlasData).texture = textureAtlas as Material;
  155. //}
  156. (textureAtlasData as UnityTextureAtlasData).uiTexture = (textureAtlas as UnityDragonBonesData.TextureAtlas).uiMaterial;
  157. (textureAtlasData as UnityTextureAtlasData).texture = (textureAtlas as UnityDragonBonesData.TextureAtlas).material;
  158. }
  159. }
  160. else
  161. {
  162. textureAtlasData = BaseObject.BorrowObject<UnityTextureAtlasData>();
  163. }
  164. return textureAtlasData;
  165. }
  166. /// <private/>
  167. protected override Armature _BuildArmature(BuildArmaturePackage dataPackage)
  168. {
  169. var armature = BaseObject.BorrowObject<Armature>();
  170. var armatureDisplay = _armatureGameObject == null ? new GameObject(dataPackage.armature.name) : _armatureGameObject;
  171. var armatureComponent = armatureDisplay.GetComponent<UnityArmatureComponent>();
  172. if (armatureComponent == null)
  173. {
  174. armatureComponent = armatureDisplay.AddComponent<UnityArmatureComponent>();
  175. armatureComponent.isUGUI = _isUGUI;
  176. if (armatureComponent.isUGUI)
  177. {
  178. armatureComponent.transform.localScale = Vector2.one * (1.0f / dataPackage.armature.scale);
  179. }
  180. }
  181. else
  182. {
  183. //compatible slotRoot
  184. var slotRoot = armatureDisplay.transform.Find("Slots");
  185. if (slotRoot != null)
  186. {
  187. for (int i = slotRoot.transform.childCount; i > 0; i--)
  188. {
  189. var childSlotDisplay = slotRoot.transform.GetChild(i - 1);
  190. childSlotDisplay.transform.SetParent(armatureDisplay.transform, false);
  191. }
  192. UnityFactoryHelper.DestroyUnityObject(slotRoot.gameObject);
  193. }
  194. }
  195. armatureComponent._armature = armature;
  196. armature.Init(dataPackage.armature, armatureComponent, armatureDisplay, this._dragonBones);
  197. _armatureGameObject = null;
  198. return armature;
  199. }
  200. protected override Armature _BuildChildArmature(BuildArmaturePackage dataPackage, Slot slot, DisplayData displayData)
  201. {
  202. var childDisplayName = slot.slotData.name + " (" + displayData.path + ")"; //
  203. var proxy = slot.armature.proxy as UnityArmatureComponent;
  204. var childTransform = proxy.transform.Find(childDisplayName);
  205. Armature childArmature = null;
  206. if (childTransform == null)
  207. {
  208. if (dataPackage != null)
  209. {
  210. childArmature = BuildArmature(displayData.path, dataPackage.dataName);
  211. }
  212. else
  213. {
  214. childArmature = BuildArmature(displayData.path, displayData.parent.parent.parent.name);
  215. }
  216. }
  217. else
  218. {
  219. if (dataPackage != null)
  220. {
  221. childArmature = BuildArmatureComponent(displayData.path, dataPackage != null ? dataPackage.dataName : "", null, dataPackage.textureAtlasName, childTransform.gameObject).armature;
  222. }
  223. else
  224. {
  225. childArmature = BuildArmatureComponent(displayData.path, null, null, null, childTransform.gameObject).armature;
  226. }
  227. }
  228. if (childArmature == null)
  229. {
  230. return null;
  231. }
  232. //
  233. var childArmatureDisplay = childArmature.display as GameObject;
  234. childArmatureDisplay.GetComponent<UnityArmatureComponent>().isUGUI = proxy.GetComponent<UnityArmatureComponent>().isUGUI;
  235. childArmatureDisplay.name = childDisplayName;
  236. childArmatureDisplay.transform.SetParent(proxy.transform, false);
  237. childArmatureDisplay.gameObject.hideFlags = HideFlags.HideInHierarchy;
  238. childArmatureDisplay.SetActive(false);
  239. return childArmature;
  240. }
  241. /// <private/>
  242. protected override Slot _BuildSlot(BuildArmaturePackage dataPackage, SlotData slotData, Armature armature)
  243. {
  244. var slot = BaseObject.BorrowObject<UnitySlot>();
  245. var armatureDisplay = armature.display as GameObject;
  246. var transform = armatureDisplay.transform.Find(slotData.name);
  247. var gameObject = transform == null ? null : transform.gameObject;
  248. var isNeedIngoreCombineMesh = false;
  249. if (gameObject == null)
  250. {
  251. gameObject = new GameObject(slotData.name);
  252. }
  253. else
  254. {
  255. if (gameObject.hideFlags == HideFlags.None)
  256. {
  257. var combineMeshs = (armature.proxy as UnityArmatureComponent).GetComponent<UnityCombineMeshs>();
  258. if (combineMeshs != null)
  259. {
  260. isNeedIngoreCombineMesh = !combineMeshs.slotNames.Contains(slotData.name);
  261. }
  262. }
  263. }
  264. slot.Init(slotData, armature, gameObject, gameObject);
  265. if (isNeedIngoreCombineMesh)
  266. {
  267. slot.DisallowCombineMesh();
  268. }
  269. return slot;
  270. }
  271. /// <summary>
  272. /// Create a armature from cached DragonBonesData instances and TextureAtlasData instances, then use the {@link #clock} to update it.
  273. /// The difference is that the armature created by {@link #buildArmature} is not WorldClock instance update.
  274. /// </summary>
  275. /// <param name="armatureName">The armature data name</param>
  276. /// <param name="dragonBonesName">The cached name of the DragonBonesData instance (If not set, all DragonBonesData instances are retrieved, and when multiple DragonBonesData instances contain a the same name armature data, it may not be possible to accurately create a specific armature)</param>
  277. /// <param name="skinName">The skin name, you can set a different ArmatureData name to share it's skin data (If not set, use the default skin data)</param>
  278. /// <param name="textureAtlasName">The textureAtlas name</param>
  279. /// <param name="gameObject"></param>
  280. /// <param name="isUGUI">isUGUI default is false</param>
  281. /// <returns>The armature display container.</returns>
  282. /// <version> DragonBones 4.5</version>
  283. /// <language>en_US</language>
  284. /// <summary>
  285. /// 通过缓存的 DragonBonesData 实例和 TextureAtlasData 实例创建一个骨架,并用 {@link #clock} 更新该骨架。
  286. /// 区别在于由 {@link #buildArmature} 创建的骨架没有 WorldClock 实例驱动。
  287. /// </summary>
  288. /// <param name="armatureName">骨架数据名称。</param>
  289. /// <param name="dragonBonesName">实例的缓存名称 (如果未设置,将检索所有的 DragonBonesData 实例,当多个 DragonBonesData 实例中包含同名的骨架数据时,可能无法准确的创建出特定的骨架)</param>
  290. /// <param name="skinName">皮肤名称,可以设置一个其他骨架数据名称来共享其皮肤数据(如果未设置,则使用默认的皮肤数据)</param>
  291. /// <param name="textureAtlasName">贴图集名称</param>
  292. /// <param name="gameObject">骨甲容器,如果未设置,则自动创建</param>
  293. /// <param name="isUGUI">isUGUI 是否是UGUI,默认为false</param>
  294. /// <returns>骨架的显示容器。</returns>
  295. /// <version> DragonBones 4.5</version>
  296. /// <language>zh_CN</language>
  297. public UnityArmatureComponent BuildArmatureComponent(string armatureName, string dragonBonesName = "", string skinName = "", string textureAtlasName = "", GameObject gameObject = null, bool isUGUI = false)
  298. {
  299. _armatureGameObject = gameObject;
  300. _isUGUI = isUGUI;
  301. var armature = BuildArmature(armatureName, dragonBonesName, skinName, textureAtlasName);
  302. if (armature != null)
  303. {
  304. _dragonBones.clock.Add(armature);
  305. var armatureDisplay = armature.display as GameObject;
  306. var armatureComponent = armatureDisplay.GetComponent<UnityArmatureComponent>();
  307. return armatureComponent;
  308. }
  309. return null;
  310. }
  311. /**
  312. * @language zh_CN
  313. * 获取带有指定贴图的显示对象。
  314. * @param textureName 指定的贴图名称。
  315. * @param textureAtlasName 指定的龙骨数据名称,如果未设置,将检索所有的龙骨数据。
  316. * @version DragonBones 3.0
  317. */
  318. public GameObject GetTextureDisplay(string textureName, string textureAtlasName = null)
  319. {
  320. /*var textureData = _getTextureData(textureAtlasName, textureName) as UnityTextureData;
  321. if (textureData != null)
  322. {
  323. if (textureData.texture == null)
  324. {
  325. var textureAtlasTexture = (textureData.parent as UnityTextureAtlasData).texture;
  326. var rect = new Rect(
  327. textureData.region.x,
  328. textureAtlasTexture.height - textureData.region.y - textureData.region.height,
  329. textureData.region.width,
  330. textureData.region.height
  331. );
  332. textureData.texture = Sprite.Create(textureAtlasTexture, rect, new Vector2(), 1.0f);
  333. }
  334. var gameObject = new GameObject();
  335. gameObject.AddComponent<SpriteRenderer>().sprite = textureData.texture;
  336. return gameObject;
  337. }*/
  338. return null;
  339. }
  340. /// <private/>
  341. protected void _RefreshTextureAtlas(UnityTextureAtlasData textureAtlasData, bool isUGUI, bool isEditor = false)
  342. {
  343. Material material = null;
  344. if (isUGUI && textureAtlasData.uiTexture == null)
  345. {
  346. if (isEditor)
  347. {
  348. #if UNITY_EDITOR
  349. if (!Application.isPlaying)
  350. {
  351. material = AssetDatabase.LoadAssetAtPath<Material>(textureAtlasData.imagePath + "_UI_Mat.mat");
  352. }
  353. #endif
  354. }
  355. else
  356. {
  357. material = Resources.Load<Material>(textureAtlasData.imagePath + "_UI_Mat");
  358. }
  359. if (material == null)
  360. {
  361. Texture2D textureAtlas = null;
  362. if (isEditor)
  363. {
  364. #if UNITY_EDITOR
  365. if (!Application.isPlaying)
  366. {
  367. textureAtlas = AssetDatabase.LoadAssetAtPath<Texture2D>(textureAtlasData.imagePath + ".png");
  368. }
  369. #endif
  370. }
  371. else
  372. {
  373. textureAtlas = Resources.Load<Texture2D>(textureAtlasData.imagePath);
  374. }
  375. material = UnityFactoryHelper.GenerateMaterial(defaultUIShaderName, textureAtlas.name + "_UI_Mat", textureAtlas);
  376. if (textureAtlasData.width < 2)
  377. {
  378. textureAtlasData.width = (uint)textureAtlas.width;
  379. }
  380. if (textureAtlasData.height < 2)
  381. {
  382. textureAtlasData.height = (uint)textureAtlas.height;
  383. }
  384. textureAtlasData._disposeEnabled = true;
  385. #if UNITY_EDITOR
  386. if (!Application.isPlaying)
  387. {
  388. string path = AssetDatabase.GetAssetPath(textureAtlas);
  389. path = path.Substring(0, path.Length - 4);
  390. AssetDatabase.CreateAsset(material, path + "_UI_Mat.mat");
  391. AssetDatabase.SaveAssets();
  392. }
  393. #endif
  394. }
  395. //
  396. textureAtlasData.uiTexture = material;
  397. }
  398. else if (!isUGUI && textureAtlasData.texture == null)
  399. {
  400. if (isEditor)
  401. {
  402. #if UNITY_EDITOR
  403. if (!Application.isPlaying)
  404. {
  405. material = AssetDatabase.LoadAssetAtPath<Material>(textureAtlasData.imagePath + "_Mat.mat");
  406. }
  407. #endif
  408. }
  409. else
  410. {
  411. material = Resources.Load<Material>(textureAtlasData.imagePath + "_Mat");
  412. }
  413. if (material == null)
  414. {
  415. Texture2D textureAtlas = null;
  416. if (isEditor)
  417. {
  418. #if UNITY_EDITOR
  419. if (!Application.isPlaying)
  420. {
  421. textureAtlas = AssetDatabase.LoadAssetAtPath<Texture2D>(textureAtlasData.imagePath + ".png");
  422. }
  423. #endif
  424. }
  425. else
  426. {
  427. textureAtlas = Resources.Load<Texture2D>(textureAtlasData.imagePath);
  428. }
  429. material = UnityFactoryHelper.GenerateMaterial(defaultShaderName, textureAtlas.name + "_Mat", textureAtlas);
  430. if (textureAtlasData.width < 2)
  431. {
  432. textureAtlasData.width = (uint)textureAtlas.width;
  433. }
  434. if (textureAtlasData.height < 2)
  435. {
  436. textureAtlasData.height = (uint)textureAtlas.height;
  437. }
  438. textureAtlasData._disposeEnabled = true;
  439. #if UNITY_EDITOR
  440. if (!Application.isPlaying)
  441. {
  442. string path = AssetDatabase.GetAssetPath(textureAtlas);
  443. path = path.Substring(0, path.Length - 4);
  444. AssetDatabase.CreateAsset(material, path + "_Mat.mat");
  445. AssetDatabase.SaveAssets();
  446. }
  447. #endif
  448. }
  449. textureAtlasData.texture = material;
  450. }
  451. }
  452. /// <inheritDoc/>
  453. public override void Clear(bool disposeData = true)
  454. {
  455. base.Clear(disposeData);
  456. _armatureGameObject = null;
  457. _isUGUI = false;
  458. //
  459. _cacheUnityDragonBonesData.Clear();
  460. }
  461. /// <summary>
  462. /// A global sound event manager.
  463. /// Sound events can be listened to uniformly from the manager.
  464. /// </summary>
  465. /// <version>DragonBones 4.5</version>
  466. /// <language>zh_CN</language>
  467. /// <summary>
  468. /// 全局声音事件管理器。
  469. /// 声音事件可以从该管理器统一侦听。
  470. /// </summary>
  471. /// <version>DragonBones 4.5</version>
  472. /// <language>zh_CN</language>
  473. public IEventDispatcher<EventObject> soundEventManager
  474. {
  475. get
  476. {
  477. return _dragonBonesInstance.eventManager;
  478. }
  479. }
  480. /// <summary>
  481. /// Parse the UnityDragonBonesData to a DragonBonesData instance and cache it to the factory.
  482. /// </summary>
  483. /// <param name="data">The UnityDragonBonesData data</param>
  484. /// <param name="isUGUI">is UGUI</param>
  485. /// <param name="armatureScale">The armature scale</param>
  486. /// <param name="texScale">The texture scale</param>
  487. /// <returns></returns>
  488. /// <version>DragonBones 4.5</version>
  489. /// <language>en_US</language>
  490. /// <summary>
  491. /// 将UnityDragonBonesData数据解析为 DragonBonesData 实例,并缓存到工厂中。
  492. /// </summary>
  493. /// <param name="data">龙骨数据</param>
  494. /// <param name="isUGUI">是否是UGUI</param>
  495. /// <param name="armatureScale">骨架缩放值</param>
  496. /// <param name="texScale">贴图缩放值</param>
  497. /// <returns></returns>
  498. /// <version>DragonBones 4.5</version>
  499. /// <language>zh_CN</language>
  500. public DragonBonesData LoadData(UnityDragonBonesData data, bool isUGUI = false, float armatureScale = 0.01f, float texScale = 1.0f)
  501. {
  502. DragonBonesData dragonBonesData = null;
  503. if (data.dragonBonesJSON != null)
  504. {
  505. dragonBonesData = LoadDragonBonesData(data.dragonBonesJSON, data.dataName, armatureScale);
  506. if (!string.IsNullOrEmpty(data.dataName) && dragonBonesData != null && data.textureAtlas != null)
  507. {
  508. #if UNITY_EDITOR
  509. bool isDirty = false;
  510. if (!Application.isPlaying)
  511. {
  512. for (int i = 0; i < data.textureAtlas.Length; ++i)
  513. {
  514. if (isUGUI)
  515. {
  516. if (data.textureAtlas[i].uiMaterial == null)
  517. {
  518. isDirty = true;
  519. break;
  520. }
  521. }
  522. else
  523. {
  524. if (data.textureAtlas[i].material == null)
  525. {
  526. isDirty = true;
  527. break;
  528. }
  529. }
  530. }
  531. }
  532. #endif
  533. var textureAtlasDatas = this.GetTextureAtlasData(data.dataName);
  534. if (textureAtlasDatas != null)
  535. {
  536. for (int i = 0, l = textureAtlasDatas.Count; i < l; ++i)
  537. {
  538. if (i < data.textureAtlas.Length)
  539. {
  540. var textureAtlasData = textureAtlasDatas[i] as UnityTextureAtlasData;
  541. var textureAtlas = data.textureAtlas[i];
  542. textureAtlasData.uiTexture = textureAtlas.uiMaterial;
  543. textureAtlasData.texture = textureAtlas.material;
  544. #if UNITY_EDITOR
  545. if (!Application.isPlaying)
  546. {
  547. textureAtlasData.imagePath = AssetDatabase.GetAssetPath(textureAtlas.texture);
  548. textureAtlasData.imagePath = textureAtlasData.imagePath.Substring(0, textureAtlasData.imagePath.Length - 4);
  549. _RefreshTextureAtlas(textureAtlasData, isUGUI, true);
  550. if (isUGUI)
  551. {
  552. textureAtlas.uiMaterial = textureAtlasData.uiTexture;
  553. }
  554. else
  555. {
  556. textureAtlas.material = textureAtlasData.texture;
  557. }
  558. }
  559. #endif
  560. }
  561. }
  562. }
  563. else
  564. {
  565. for (int i = 0; i < data.textureAtlas.Length; ++i)
  566. {
  567. LoadTextureAtlasData(data.textureAtlas[i], data.dataName, texScale, isUGUI);
  568. }
  569. }
  570. #if UNITY_EDITOR
  571. if (isDirty)
  572. {
  573. AssetDatabase.Refresh();
  574. EditorUtility.SetDirty(data);
  575. AssetDatabase.SaveAssets();
  576. }
  577. #endif
  578. }
  579. }
  580. return dragonBonesData;
  581. }
  582. /// <summary>
  583. /// Parse the raw data to a DragonBonesData instance and cache it to the factory.
  584. /// </summary>
  585. /// <param name="dragonBonesJSONPath">The path of dragonBones data in Resources. (other forms of loading can be extended by themselves)</param>
  586. /// <param name="name">Specify a cache name for the instance so that the instance can be obtained through this name. (If not set, use the instance name instead)</param>
  587. /// <param name="scale">Specify a scaling value for all armatures. (Default does not scale)</param>
  588. /// <returns>DragonBonesData instance</returns>
  589. /// <version>DragonBones 4.5</version>
  590. /// <language>en_US</language>
  591. /// <summary>
  592. /// 将原始数据解析为 DragonBonesData 实例,并缓存到工厂中。
  593. /// </summary>
  594. /// <param name="dragonBonesJSONPath">龙骨数据在 Resources 中的路径。(其他形式的加载可自行扩展)</param>
  595. /// <param name="name">为该实例指定一个缓存名称,以便可以通过此名称获取该实例。 (如果未设置,则使用该实例中的名称)</param>
  596. /// <param name="scale">为所有的骨架指定一个缩放值。 (默认不缩放)</param>
  597. /// <returns>龙骨数据</returns>
  598. /// <version>DragonBones 4.5</version>
  599. /// <language>zh_CN</language>
  600. public DragonBonesData LoadDragonBonesData(string dragonBonesJSONPath, string name = "", float scale = 0.01f)
  601. {
  602. dragonBonesJSONPath = UnityFactoryHelper.CheckResourecdPath(dragonBonesJSONPath);
  603. TextAsset dragonBonesJSON = Resources.Load<TextAsset>(dragonBonesJSONPath);
  604. DragonBonesData dragonBonesData = LoadDragonBonesData(dragonBonesJSON, name);
  605. return dragonBonesData;
  606. }
  607. /// <summary>
  608. /// Parse the json data to a DragonBonesData instance and cache it to the factory.
  609. /// </summary>
  610. /// <param name="dragonBonesJSON">The jsonData of dragonBones</param>
  611. /// <param name="name">Specify a cache name for the instance so that the instance can be obtained through this name. (If not set, use the instance name instead)</param>
  612. /// <param name="scale">Specify a scaling value for all armatures. (Default does not scale)</param>
  613. /// <returns>DragonBonesData instance</returns>
  614. /// <version>DragonBones 4.5</version>
  615. /// <language>en_US</language>
  616. /// <summary>
  617. /// 将json数据解析为 DragonBonesData 实例,并缓存到工厂中。
  618. /// </summary>
  619. /// <param name="dragonBonesJSON">龙骨的json数据。</param>
  620. /// <param name="name">为该实例指定一个缓存名称,以便可以通过此名称获取该实例。 (如果未设置,则使用该实例中的名称)</param>
  621. /// <param name="scale">为所有的骨架指定一个缩放值。 (默认不缩放)</param>
  622. /// <returns>龙骨数据</returns>
  623. /// <version>DragonBones 4.5</version>
  624. /// <language>zh_CN</language>
  625. public DragonBonesData LoadDragonBonesData(TextAsset dragonBonesJSON, string name = "", float scale = 0.01f)
  626. {
  627. if (dragonBonesJSON == null)
  628. {
  629. return null;
  630. }
  631. if (!string.IsNullOrEmpty(name))
  632. {
  633. var existedData = GetDragonBonesData(name);
  634. if (existedData != null)
  635. {
  636. return existedData;
  637. }
  638. }
  639. DragonBonesData data = null;
  640. if (dragonBonesJSON.text == "DBDT")
  641. {
  642. BinaryDataParser.jsonParseDelegate = MiniJSON.Json.Deserialize;
  643. data = ParseDragonBonesData(dragonBonesJSON.bytes, name, scale); // Unity default Scale Factor.
  644. }
  645. else
  646. {
  647. data = ParseDragonBonesData((Dictionary<string, object>)MiniJSON.Json.Deserialize(dragonBonesJSON.text), name, scale); // Unity default Scale Factor.
  648. }
  649. //
  650. name = !string.IsNullOrEmpty(name) ? name : data.name;
  651. //
  652. _dragonBonesDataMap[name] = data;
  653. return data;
  654. }
  655. /// <summary>
  656. /// Parse the textureAtlas json data to a UnityTextureAtlasData instance and cache it to the factory.
  657. /// </summary>
  658. /// <param name="textureAtlasJSONPath">The path of dragonBones data in Resources. (other forms of loading can be extended by themselves. use factory.ParseTextureAtlasData(JSONObject, Material))</param>
  659. /// <param name="name">Specify a cache name for the instance so that the instance can be obtained through this name. (If not set, use the instance name instead)</param>
  660. /// <param name="scale">Specify a scaling value for textureAtlas. (Default does not scale)</param>
  661. /// <param name="isUGUI"></param>
  662. /// <returns></returns>
  663. /// <version>DragonBones 4.5</version>
  664. /// <language>en_US</language>
  665. /// <summary>
  666. /// 将贴图集json数据解析为UnityTextureAtlasData,并缓存到工厂中。
  667. /// </summary>
  668. /// <param name="textureAtlasJSONPath">贴图集数据在 Resources 中的路径。(其他形式的加载可自行扩展,使用 factory.ParseTextureAtlasData(JSONObject, Material))</param>
  669. /// <param name="name">为数据指定一个名称,以便可以通过这个名称获取数据,如果未设置,则使用数据中的名称。</param>
  670. /// <param name="scale">为贴图集设置一个缩放值。</param>
  671. /// <param name="isUGUI"></param>
  672. /// <returns>贴图集数据</returns>
  673. /// <version>DragonBones 4.5</version>
  674. /// <language>zh_CN</language>
  675. public UnityTextureAtlasData LoadTextureAtlasData(string textureAtlasJSONPath, string name = "", float scale = 1.0f, bool isUGUI = false)
  676. {
  677. textureAtlasJSONPath = UnityFactoryHelper.CheckResourecdPath(textureAtlasJSONPath);
  678. TextAsset textureAtlasJSON = Resources.Load<TextAsset>(textureAtlasJSONPath);
  679. //
  680. if (textureAtlasJSON != null)
  681. {
  682. Dictionary<string, object> textureJSONData = (Dictionary<string, object>)MiniJSON.Json.Deserialize(textureAtlasJSON.text);
  683. UnityTextureAtlasData textureAtlasData = ParseTextureAtlasData(textureJSONData, null, name, scale) as UnityTextureAtlasData;
  684. if (textureAtlasData != null)
  685. {
  686. textureAtlasData.imagePath = UnityFactoryHelper.GetTextureAtlasImagePath(textureAtlasJSONPath, textureAtlasData.imagePath);
  687. _RefreshTextureAtlas(textureAtlasData, isUGUI);
  688. }
  689. return textureAtlasData;
  690. }
  691. return null;
  692. }
  693. /// <summary>
  694. /// Parse the TextureAtlas to a UnityTextureAtlasData instance and cache it to the factory.
  695. /// </summary>
  696. /// <param name="textureAtlasJSONPath">The path of dragonBones data in Resources. (other forms of loading can be extended by themselves. use factory.ParseTextureAtlasData(JSONObject, Material))</param>
  697. /// <param name="name">Specify a cache name for the instance so that the instance can be obtained through this name. (If not set, use the instance name instead)</param>
  698. /// <param name="scale">Specify a scaling value for textureAtlas. (Default does not scale)</param>
  699. /// <param name="isUGUI"></param>
  700. /// <returns></returns>
  701. /// <version>DragonBones 4.5</version>
  702. /// <language>en_US</language>
  703. /// <summary>
  704. /// 将TextureAtlas解析为UnityTextureAtlasData,并缓存到工厂中。
  705. /// </summary>
  706. /// <param name="textureAtlas"></param>
  707. /// <param name="name">为数据指定一个名称,以便可以通过这个名称获取数据,如果未设置,则使用数据中的名称。</param>
  708. /// <param name="scale">为贴图集设置一个缩放值。</param>
  709. /// <param name="isUGUI"></param>
  710. /// <returns></returns>
  711. /// <version>DragonBones 4.5</version>
  712. /// <language>zh_CN</language>
  713. public UnityTextureAtlasData LoadTextureAtlasData(UnityDragonBonesData.TextureAtlas textureAtlas, string name, float scale = 1.0f, bool isUGUI = false)
  714. {
  715. Dictionary<string, object> textureJSONData = (Dictionary<string, object>)MiniJSON.Json.Deserialize(textureAtlas.textureAtlasJSON.text);
  716. UnityTextureAtlasData textureAtlasData = ParseTextureAtlasData(textureJSONData, null, name, scale) as UnityTextureAtlasData;
  717. if (textureJSONData.ContainsKey("width"))
  718. {
  719. textureAtlasData.width = uint.Parse(textureJSONData["width"].ToString());
  720. }
  721. if (textureJSONData.ContainsKey("height"))
  722. {
  723. textureAtlasData.height = uint.Parse(textureJSONData["height"].ToString());
  724. }
  725. if (textureAtlasData != null)
  726. {
  727. textureAtlasData.uiTexture = textureAtlas.uiMaterial;
  728. textureAtlasData.texture = textureAtlas.material;
  729. #if UNITY_EDITOR
  730. if (!Application.isPlaying)
  731. {
  732. textureAtlasData.imagePath = AssetDatabase.GetAssetPath(textureAtlas.texture);
  733. textureAtlasData.imagePath = textureAtlasData.imagePath.Substring(0, textureAtlasData.imagePath.Length - 4);
  734. _RefreshTextureAtlas(textureAtlasData, isUGUI, true);
  735. if (isUGUI)
  736. {
  737. textureAtlas.uiMaterial = textureAtlasData.uiTexture;
  738. }
  739. else
  740. {
  741. textureAtlas.material = textureAtlasData.texture;
  742. }
  743. }
  744. #endif
  745. }
  746. return textureAtlasData;
  747. }
  748. /// <summary>
  749. /// Refresh the Armature textureAtlas data.
  750. /// </summary>
  751. /// <param name="unityArmature">UnityArmatureComponent</param>
  752. /// <version>DragonBones 4.5</version>
  753. /// <language>en_US</language>
  754. /// <summary>
  755. /// 刷新骨架的贴图集数据。
  756. /// </summary>
  757. /// <param name="unityArmature">骨架</param>
  758. /// <version>DragonBones 4.5</version>
  759. /// <language>zh_CN</language>
  760. public void RefreshAllTextureAtlas(UnityArmatureComponent unityArmature)
  761. {
  762. foreach (var textureAtlasDatas in _textureAtlasDataMap.Values)
  763. {
  764. foreach (UnityTextureAtlasData textureAtlasData in textureAtlasDatas)
  765. {
  766. _RefreshTextureAtlas(textureAtlasData, unityArmature.isUGUI);
  767. }
  768. }
  769. }
  770. /// <private/>
  771. public override void ReplaceDisplay(Slot slot, DisplayData displayData, int displayIndex = -1)
  772. {
  773. //UGUI Display Object and Normal Display Object cannot be replaced with each other
  774. if (displayData.type == DisplayType.Image || displayData.type == DisplayType.Mesh)
  775. {
  776. var dataName = displayData.parent.parent.parent.name;
  777. var textureData = this._GetTextureData(dataName, displayData.path);
  778. if (textureData != null)
  779. {
  780. var textureAtlasData = textureData.parent as UnityTextureAtlasData;
  781. var oldIsUGUI = (slot._armature.proxy as UnityArmatureComponent).isUGUI;
  782. if ((oldIsUGUI && textureAtlasData.uiTexture == null) || (!oldIsUGUI && textureAtlasData.texture == null))
  783. {
  784. LogHelper.LogWarning("ugui display object and normal display object cannot be replaced with each other");
  785. return;
  786. }
  787. }
  788. }
  789. base.ReplaceDisplay(slot, displayData, displayIndex);
  790. }
  791. /// <summary>
  792. /// 用特定的显示对象数据替换特定插槽当前的显示对象数据。
  793. /// </summary>
  794. /// <param name="dragonBonesName">The DragonBonesData instance cache name</param>
  795. /// <param name="armatureName">The armature data name</param>
  796. /// <param name="slotName">The slot data name</param>
  797. /// <param name="displayName">The display data name</param>
  798. /// <param name="slot">The slot</param>
  799. /// <param name="texture">The new texture</param>
  800. /// <param name="material">The new material</param>
  801. /// <param name="isUGUI">is ugui。</param>
  802. /// <param name="displayIndex">The index of the display data that is replaced. (If it is not set, replaces the current display data)</param>
  803. /// <version>DragonBones 4.5</version>
  804. /// <language>zh_CN</language>
  805. /// <summary>
  806. /// 用特定的显示对象数据替换特定插槽当前的显示对象数据。
  807. /// </summary>
  808. /// <param name="dragonBonesName">指定的龙骨数据名称。</param>
  809. /// <param name="armatureName">指定的骨架名称。</param>
  810. /// <param name="slotName">指定的插槽名称。</param>
  811. /// <param name="displayName">指定的显示对象名称。</param>
  812. /// <param name="slot">指定的插槽实例。</param>
  813. /// <param name="texture">新的贴图。</param>
  814. /// <param name="material">新的材质。</param>
  815. /// <param name="isUGUI">是否为ugui。</param>
  816. /// <param name="displayIndex">被替换的显示对象数据的索引。 (如果未设置,则替换当前的显示对象数据)。</param>
  817. /// <version>DragonBones 4.5</version>
  818. /// <language>zh_CN</language>
  819. public void ReplaceSlotDisplay(
  820. string dragonBonesName, string armatureName, string slotName, string displayName,
  821. Slot slot, Texture2D texture, Material material = null,
  822. bool isUGUI = false, int displayIndex = -1)
  823. {
  824. var armatureData = this.GetArmatureData(armatureName, dragonBonesName);
  825. if (armatureData == null || armatureData.defaultSkin == null)
  826. {
  827. return;
  828. }
  829. var displays = armatureData.defaultSkin.GetDisplays(slotName);
  830. if (displays == null)
  831. {
  832. return;
  833. }
  834. DisplayData prevDispalyData = null;
  835. foreach (var displayData in displays)
  836. {
  837. if (displayData.name == displayName)
  838. {
  839. prevDispalyData = displayData;
  840. break;
  841. }
  842. }
  843. if (prevDispalyData == null || !((prevDispalyData is ImageDisplayData) || (prevDispalyData is MeshDisplayData)))
  844. {
  845. return;
  846. }
  847. TextureData prevTextureData = null;
  848. if(prevDispalyData is ImageDisplayData)
  849. {
  850. prevTextureData = (prevDispalyData as ImageDisplayData).texture;
  851. }
  852. else
  853. {
  854. prevTextureData = (prevDispalyData as MeshDisplayData).texture;
  855. }
  856. UnityTextureData newTextureData = new UnityTextureData();
  857. newTextureData.CopyFrom(prevTextureData);
  858. newTextureData.rotated = false;
  859. newTextureData.region.x = 0.0f;
  860. newTextureData.region.y = 0.0f;
  861. newTextureData.region.width = texture.width;
  862. newTextureData.region.height = texture.height;
  863. newTextureData.frame = newTextureData.region;
  864. newTextureData.name = prevTextureData.name;
  865. newTextureData.parent = new UnityTextureAtlasData();
  866. newTextureData.parent.width = (uint)texture.width;
  867. newTextureData.parent.height = (uint)texture.height;
  868. newTextureData.parent.scale = prevTextureData.parent.scale;
  869. //
  870. if (material == null)
  871. {
  872. if (isUGUI)
  873. {
  874. material = UnityFactoryHelper.GenerateMaterial(defaultUIShaderName, texture.name + "_UI_Mat", texture);
  875. }
  876. else
  877. {
  878. material = UnityFactoryHelper.GenerateMaterial(defaultShaderName, texture.name + "_Mat", texture);
  879. }
  880. }
  881. if (isUGUI)
  882. {
  883. (newTextureData.parent as UnityTextureAtlasData).uiTexture = material;
  884. }
  885. else
  886. {
  887. (newTextureData.parent as UnityTextureAtlasData).texture = material;
  888. }
  889. material.mainTexture = texture;
  890. DisplayData newDisplayData = null;
  891. if (prevDispalyData is ImageDisplayData)
  892. {
  893. newDisplayData = new ImageDisplayData();
  894. newDisplayData.type = prevDispalyData.type;
  895. newDisplayData.name = prevDispalyData.name;
  896. newDisplayData.path = prevDispalyData.path;
  897. newDisplayData.transform.CopyFrom(prevDispalyData.transform);
  898. newDisplayData.parent = prevDispalyData.parent;
  899. (newDisplayData as ImageDisplayData).pivot.CopyFrom((prevDispalyData as ImageDisplayData).pivot);
  900. (newDisplayData as ImageDisplayData).texture = newTextureData;
  901. }
  902. else if (prevDispalyData is MeshDisplayData)
  903. {
  904. newDisplayData = new MeshDisplayData();
  905. newDisplayData.type = prevDispalyData.type;
  906. newDisplayData.name = prevDispalyData.name;
  907. newDisplayData.path = prevDispalyData.path;
  908. newDisplayData.transform.CopyFrom(prevDispalyData.transform);
  909. newDisplayData.parent = prevDispalyData.parent;
  910. (newDisplayData as MeshDisplayData).texture = newTextureData;
  911. (newDisplayData as MeshDisplayData).vertices.inheritDeform = (prevDispalyData as MeshDisplayData).vertices.inheritDeform;
  912. (newDisplayData as MeshDisplayData).vertices.offset = (prevDispalyData as MeshDisplayData).vertices.offset;
  913. (newDisplayData as MeshDisplayData).vertices.data = (prevDispalyData as MeshDisplayData).vertices.data;
  914. (newDisplayData as MeshDisplayData).vertices.weight = (prevDispalyData as MeshDisplayData).vertices.weight;
  915. }
  916. ReplaceDisplay(slot, newDisplayData, displayIndex);
  917. }
  918. //
  919. public UnityDragonBonesData GetCacheUnityDragonBonesData(string draonBonesName)
  920. {
  921. if (string.IsNullOrEmpty(draonBonesName))
  922. {
  923. return null;
  924. }
  925. for (int i = 0; i < this._cacheUnityDragonBonesData.Count; i++)
  926. {
  927. if (this._cacheUnityDragonBonesData[i].dataName == draonBonesName)
  928. {
  929. return this._cacheUnityDragonBonesData[i];
  930. }
  931. }
  932. return null;
  933. }
  934. public void AddCacheUnityDragonBonesData(UnityDragonBonesData unityData)
  935. {
  936. for (int i = 0; i < this._cacheUnityDragonBonesData.Count; i++)
  937. {
  938. if (this._cacheUnityDragonBonesData[i].dataName == unityData.dataName)
  939. {
  940. this._cacheUnityDragonBonesData[i] = unityData;
  941. return;
  942. }
  943. }
  944. this._cacheUnityDragonBonesData.Add(unityData);
  945. }
  946. }
  947. /// <summary>
  948. /// UnityFactory 辅助类
  949. /// </summary>
  950. internal static class UnityFactoryHelper
  951. {
  952. /// <summary>
  953. /// 生成一个材质球
  954. /// </summary>
  955. /// <param name="shaderName"></param>
  956. /// <param name="materialName"></param>
  957. /// <param name="texture"></param>
  958. /// <returns></returns>
  959. internal static Material GenerateMaterial(string shaderName, string materialName, Texture texture)
  960. {
  961. //创建材质球
  962. Shader shader = Shader.Find(shaderName);
  963. Material material = new Material(shader);
  964. material.name = materialName;
  965. material.mainTexture = texture;
  966. return material;
  967. }
  968. /// <summary>
  969. /// 检查路径合法性
  970. /// </summary>
  971. /// <param name="path"></param>
  972. /// <returns></returns>
  973. internal static string CheckResourecdPath(string path)
  974. {
  975. var index = path.LastIndexOf("Resources");
  976. if (index > 0)
  977. {
  978. path = path.Substring(index + 10);
  979. }
  980. index = path.LastIndexOf(".");
  981. if (index > 0)
  982. {
  983. path = path.Substring(0, index);
  984. }
  985. return path;
  986. }
  987. /// <summary>
  988. /// 根据贴图JSON文件的路径和JSON文件中贴图名称获得贴图路径
  989. /// </summary>
  990. /// <param name="textureAtlasJSONPath">贴图JSON文件路径:NewDragon/NewDragon_tex</param>
  991. /// <param name="textureAtlasImageName">贴图名称:NewDragon.png</param>
  992. /// <returns></returns>
  993. internal static string GetTextureAtlasImagePath(string textureAtlasJSONPath, string textureAtlasImageName)
  994. {
  995. var index = textureAtlasJSONPath.LastIndexOf("Resources");
  996. if (index > 0)
  997. {
  998. textureAtlasJSONPath = textureAtlasJSONPath.Substring(index + 10);
  999. }
  1000. index = textureAtlasJSONPath.LastIndexOf("/");
  1001. string textureAtlasImagePath = textureAtlasImageName;
  1002. if (index > 0)
  1003. {
  1004. textureAtlasImagePath = textureAtlasJSONPath.Substring(0, index + 1) + textureAtlasImageName;
  1005. }
  1006. index = textureAtlasImagePath.LastIndexOf(".");
  1007. if (index > 0)
  1008. {
  1009. textureAtlasImagePath = textureAtlasImagePath.Substring(0, index);
  1010. }
  1011. return textureAtlasImagePath;
  1012. }
  1013. /// <summary>
  1014. /// 根据贴图路径获得贴图名称
  1015. /// </summary>
  1016. /// <param name="textureAtlasJSONPath"></param>
  1017. /// <returns></returns>
  1018. internal static string GetTextureAtlasNameByPath(string textureAtlasJSONPath)
  1019. {
  1020. string name = string.Empty;
  1021. int index = textureAtlasJSONPath.LastIndexOf("/") + 1;
  1022. int lastIdx = textureAtlasJSONPath.LastIndexOf("_tex");
  1023. if (lastIdx > -1)
  1024. {
  1025. if (lastIdx > index)
  1026. {
  1027. name = textureAtlasJSONPath.Substring(index, lastIdx - index);
  1028. }
  1029. else
  1030. {
  1031. name = textureAtlasJSONPath.Substring(index);
  1032. }
  1033. }
  1034. else
  1035. {
  1036. if (index > -1)
  1037. {
  1038. name = textureAtlasJSONPath.Substring(index);
  1039. }
  1040. }
  1041. return name;
  1042. }
  1043. internal static void DestroyUnityObject(UnityEngine.Object obj)
  1044. {
  1045. if (obj == null)
  1046. {
  1047. return;
  1048. }
  1049. #if UNITY_EDITOR
  1050. UnityEngine.Object.DestroyImmediate(obj);
  1051. #else
  1052. UnityEngine.Object.Destroy(obj);
  1053. #endif
  1054. }
  1055. }
  1056. internal static class LogHelper
  1057. {
  1058. internal static void LogWarning(object message)
  1059. {
  1060. UnityEngine.Debug.LogWarning("[DragonBones]" + message);
  1061. }
  1062. }
  1063. }