UnityFactory.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. namespace DragonBones
  4. {
  5. /**
  6. * @private
  7. */
  8. internal class ClockHandler : MonoBehaviour
  9. {
  10. void Update()
  11. {
  12. UnityFactory._clock.AdvanceTime(Time.deltaTime);
  13. }
  14. }
  15. /**
  16. * @language zh_CN
  17. * Unity 工厂。
  18. * @version DragonBones 3.0
  19. */
  20. public class UnityFactory : BaseFactory
  21. {
  22. private static IEventDispatcher<EventObject> _eventManager = null;
  23. private static GameObject _gameObject = null;
  24. /**
  25. * @private
  26. */
  27. internal static readonly WorldClock _clock = new WorldClock();
  28. /**
  29. * @language zh_CN
  30. * 一个可以直接使用的全局工厂实例。
  31. * @version DragonBones 4.7
  32. */
  33. public static readonly UnityFactory factory = new UnityFactory();
  34. /**
  35. * @language zh_CN
  36. * 创建材质时默认使用的 shader。
  37. * @version DragonBones 4.7
  38. */
  39. public string defaultShaderName = "Sprites/Default";
  40. private string _textureAtlasPath = null;
  41. private GameObject _armatureGameObject = null;
  42. private readonly Dictionary<string, DragonBonesData> _pathDragonBonesDataMap = new Dictionary<string, DragonBonesData>();
  43. private readonly Dictionary<string, TextureAtlasData> _pathTextureAtlasDataMap = new Dictionary<string, TextureAtlasData>();
  44. /**
  45. * @language zh_CN
  46. * 创建一个工厂。 (通常只需要一个全局工厂实例)
  47. * @param dataParser 龙骨数据解析器,如果不设置,则使用默认解析器。
  48. * @version DragonBones 3.0
  49. */
  50. public UnityFactory(DataParser dataParser = null) : base(dataParser)
  51. {
  52. }
  53. /**
  54. * @private
  55. */
  56. override protected TextureAtlasData _generateTextureAtlasData(TextureAtlasData textureAtlasData, object textureAtlas)
  57. {
  58. if (textureAtlasData != null)
  59. {
  60. if (textureAtlas != null)
  61. {
  62. var shader = Shader.Find(defaultShaderName);
  63. var material = new Material(shader);
  64. material.mainTexture = textureAtlas as Texture;
  65. (textureAtlasData as UnityTextureAtlasData).texture = material;
  66. (textureAtlasData as UnityTextureAtlasData)._disposeTexture = true;
  67. }
  68. else
  69. {
  70. (textureAtlasData as UnityTextureAtlasData).texture = textureAtlas as Material;
  71. }
  72. }
  73. else
  74. {
  75. textureAtlasData = BaseObject.BorrowObject<UnityTextureAtlasData>();
  76. }
  77. return textureAtlasData;
  78. }
  79. /**
  80. * @private
  81. */
  82. override protected Armature _generateArmature(BuildArmaturePackage dataPackage)
  83. {
  84. if (Application.isPlaying) //
  85. {
  86. if (_gameObject == null)
  87. {
  88. _gameObject = new GameObject("DragonBones Object", typeof(ClockHandler));
  89. _gameObject.isStatic = true;
  90. _gameObject.hideFlags = HideFlags.HideInHierarchy;
  91. }
  92. if (_eventManager == null)
  93. {
  94. _eventManager = _gameObject.AddComponent<UnityArmatureComponent>();
  95. }
  96. }
  97. var armature = BaseObject.BorrowObject<Armature>();
  98. var armatureDisplay = _armatureGameObject == null ? new GameObject(dataPackage.armature.name) : _armatureGameObject;
  99. var armatureComponent = armatureDisplay.GetComponent<UnityArmatureComponent>();
  100. if (armatureComponent == null)
  101. {
  102. armatureComponent = armatureDisplay.AddComponent<UnityArmatureComponent>();
  103. }
  104. armatureComponent._armature = armature;
  105. armature._init(
  106. dataPackage.armature, dataPackage.skin,
  107. armatureDisplay, armatureComponent, _eventManager
  108. );
  109. _armatureGameObject = null;
  110. return armature;
  111. }
  112. /**
  113. * @private
  114. */
  115. override protected Slot _generateSlot(BuildArmaturePackage dataPackage, SkinSlotData skinSlotData, Armature armature)
  116. {
  117. var slotData = skinSlotData.slot;
  118. var slot = BaseObject.BorrowObject<UnitySlot>();
  119. var displayList = new List<object>();
  120. DragonBones.ResizeList(displayList, skinSlotData.displays.Count, null);
  121. var armatureDisplay = armature.display as GameObject;
  122. var transform = armatureDisplay.transform.Find(skinSlotData.slot.name);
  123. var gameObject = transform == null ? null : transform.gameObject;
  124. if (gameObject == null)
  125. {
  126. gameObject = new GameObject(slotData.name);
  127. gameObject.AddComponent<MeshRenderer>();
  128. gameObject.AddComponent<MeshFilter>();
  129. }
  130. slot._init(
  131. skinSlotData,
  132. gameObject,
  133. gameObject
  134. );
  135. for (int i = 0, l = skinSlotData.displays.Count; i < l; ++i)
  136. {
  137. var displayData = skinSlotData.displays[i];
  138. switch (displayData.type)
  139. {
  140. case DisplayType.Image:
  141. if (displayData.texture == null)
  142. {
  143. displayData.texture = _getTextureData(dataPackage.dataName, displayData.path);
  144. }
  145. if (!string.IsNullOrEmpty(dataPackage.textureAtlasName))
  146. {
  147. slot._textureDatas[i] = _getTextureData(dataPackage.textureAtlasName, displayData.path);
  148. }
  149. displayList[i] = slot.rawDisplay;
  150. break;
  151. case DisplayType.Mesh:
  152. if (displayData.texture == null)
  153. {
  154. displayData.texture = _getTextureData(dataPackage.dataName, displayData.path);
  155. }
  156. if (!string.IsNullOrEmpty(dataPackage.textureAtlasName))
  157. {
  158. slot._textureDatas[i] = _getTextureData(dataPackage.textureAtlasName, displayData.path);
  159. }
  160. displayList[i] = slot.meshDisplay;
  161. break;
  162. case DisplayType.Armature:
  163. var childDisplayName = slotData.name + " (" + displayData.path + ")"; //
  164. var childTransform = armatureDisplay.transform.Find(childDisplayName);
  165. var childArmature = childTransform == null ?
  166. BuildArmature(displayData.path, dataPackage.dataName) :
  167. BuildArmatureComponent(displayData.path, dataPackage.dataName, null, dataPackage.textureAtlasName, childTransform.gameObject).armature;
  168. if (childArmature != null)
  169. {
  170. childArmature.inheritAnimation = displayData.inheritAnimation;
  171. if (!childArmature.inheritAnimation)
  172. {
  173. var actions = slotData.actions.Count > 0 ? slotData.actions : childArmature.armatureData.actions;
  174. if (actions.Count > 0)
  175. {
  176. foreach (var actionData in actions)
  177. {
  178. childArmature._bufferAction(actionData);
  179. }
  180. }
  181. else
  182. {
  183. childArmature.animation.Play();
  184. }
  185. }
  186. displayData.armature = childArmature.armatureData; //
  187. // Hide
  188. var childArmatureDisplay = childArmature.display as GameObject;
  189. childArmatureDisplay.name = childDisplayName;
  190. childArmatureDisplay.gameObject.hideFlags = HideFlags.HideInHierarchy;
  191. childArmatureDisplay.SetActive(false);
  192. }
  193. displayList[i] = childArmature;
  194. break;
  195. default:
  196. displayList[i] = null;
  197. break;
  198. }
  199. }
  200. slot._setDisplayList(displayList);
  201. return slot;
  202. }
  203. /**
  204. * @private
  205. */
  206. protected void _refreshTextureAtlas(UnityTextureAtlasData textureAtlasData)
  207. {
  208. if (textureAtlasData.texture == null)
  209. {
  210. var textureAtlas = Resources.Load<Texture2D>(textureAtlasData.imagePath);
  211. var shader = Shader.Find(defaultShaderName);
  212. var material = new Material(shader);
  213. material.mainTexture = textureAtlas;
  214. textureAtlasData.texture = material;
  215. textureAtlasData._disposeTexture = true;
  216. }
  217. }
  218. /**
  219. * @inheritDoc
  220. */
  221. public override void RemoveDragonBonesData(string name, bool disposeData = true)
  222. {
  223. var dragonBonesData = GetDragonBonesData(name);
  224. if (_pathDragonBonesDataMap.ContainsValue(dragonBonesData))
  225. {
  226. foreach (var pair in _pathDragonBonesDataMap)
  227. {
  228. if (pair.Value == dragonBonesData)
  229. {
  230. _pathDragonBonesDataMap.Remove(pair.Key);
  231. break;
  232. }
  233. }
  234. }
  235. base.RemoveDragonBonesData(name, disposeData);
  236. }
  237. /**
  238. * @inheritDoc
  239. */
  240. public override void RemoveTextureAtlasData(string name, bool disposeData = true)
  241. {
  242. var textureAtlasDataList = GetTextureAtlasData(name);
  243. if (textureAtlasDataList != null)
  244. {
  245. foreach (var textureAtlasData in textureAtlasDataList)
  246. {
  247. if (_pathTextureAtlasDataMap.ContainsValue(textureAtlasData))
  248. {
  249. foreach (var pair in _pathTextureAtlasDataMap)
  250. {
  251. if (pair.Value == textureAtlasData)
  252. {
  253. _pathTextureAtlasDataMap.Remove(pair.Key);
  254. break;
  255. }
  256. }
  257. }
  258. }
  259. }
  260. base.RemoveTextureAtlasData(name, disposeData);
  261. }
  262. /**
  263. * @inheritDoc
  264. */
  265. public override void Clear(bool disposeData = true)
  266. {
  267. base.Clear(disposeData);
  268. _pathDragonBonesDataMap.Clear();
  269. _pathTextureAtlasDataMap.Clear();
  270. }
  271. /**
  272. * @language zh_CN
  273. * 创建一个指定名称的骨架,并使用骨架的显示容器来更新骨架动画。
  274. * @param armatureName 骨架数据名称。
  275. * @param dragonBonesName 龙骨数据名称,如果未设置,将检索所有的龙骨数据,如果多个数据中包含同名的骨架数据,可能无法创建出准确的骨架。
  276. * @param skinName 皮肤名称,如果未设置,则使用默认皮肤。
  277. * @returns 骨架的显示容器。
  278. * @see DragonBones.UnityArmatureComponent
  279. * @version DragonBones 4.5
  280. */
  281. public UnityArmatureComponent BuildArmatureComponent(string armatureName, string dragonBonesName = null, string skinName = null, string textureAtlasName = null, GameObject gameObject = null)
  282. {
  283. _armatureGameObject = gameObject;
  284. var armature = BuildArmature(armatureName, dragonBonesName, skinName, textureAtlasName);
  285. if (armature != null)
  286. {
  287. _clock.Add(armature);
  288. var armatureDisplay = armature.display as GameObject;
  289. var armatureComponent = armatureDisplay.GetComponent<UnityArmatureComponent>();
  290. return armatureComponent;
  291. }
  292. return null;
  293. }
  294. /**
  295. * @language zh_CN
  296. * 获取带有指定贴图的显示对象。
  297. * @param textureName 指定的贴图名称。
  298. * @param textureAtlasName 指定的龙骨数据名称,如果未设置,将检索所有的龙骨数据。
  299. * @version DragonBones 3.0
  300. */
  301. public GameObject GetTextureDisplay(string textureName, string textureAtlasName = null)
  302. {
  303. /*var textureData = _getTextureData(textureAtlasName, textureName) as UnityTextureData;
  304. if (textureData != null)
  305. {
  306. if (textureData.texture == null)
  307. {
  308. var textureAtlasTexture = (textureData.parent as UnityTextureAtlasData).texture;
  309. var rect = new Rect(
  310. textureData.region.x,
  311. textureAtlasTexture.height - textureData.region.y - textureData.region.height,
  312. textureData.region.width,
  313. textureData.region.height
  314. );
  315. textureData.texture = Sprite.Create(textureAtlasTexture, rect, new Vector2(), 1.0f);
  316. }
  317. var gameObject = new GameObject();
  318. gameObject.AddComponent<SpriteRenderer>().sprite = textureData.texture;
  319. return gameObject;
  320. }*/
  321. return null;
  322. }
  323. /**
  324. * @language zh_CN
  325. * 获取全局声音事件管理器。
  326. * @version DragonBones 4.5
  327. */
  328. public IEventDispatcher<EventObject> soundEventManager
  329. {
  330. get { return _eventManager; }
  331. }
  332. /**
  333. * @language zh_CN
  334. * 加载、解析并添加龙骨数据。
  335. * @param path 龙骨数据在 Resources 中的路径。(其他形式的加载可自行扩展)
  336. * @param name 为数据提供一个名称,以便可以通过这个名称获取数据,如果未设置,则使用数据中的名称。
  337. * @param scale 为所有骨架设置一个缩放值。
  338. * @returns 龙骨数据
  339. * @see #ParseDragonBonesData()
  340. * @see #GetDragonBonesData()
  341. * @see #AddDragonBonesData()
  342. * @see #RemoveDragonBonesData()
  343. * @see DragonBones.DragonBonesData
  344. */
  345. public DragonBonesData LoadDragonBonesData(string path, string name = null, float scale = 0.01f)
  346. {
  347. var index = path.LastIndexOf("Resources");
  348. if (index > 0)
  349. {
  350. path = path.Substring(index + 10);
  351. }
  352. index = path.LastIndexOf(".");
  353. if (index > 0)
  354. {
  355. path = path.Substring(0, index);
  356. }
  357. if (_pathDragonBonesDataMap.ContainsKey(path))
  358. {
  359. return _pathDragonBonesDataMap[path];
  360. }
  361. var dragonBonesData = LoadDragonBonesData(Resources.Load<TextAsset>(path), name);
  362. if (dragonBonesData != null)
  363. {
  364. _pathDragonBonesDataMap[path] = dragonBonesData;
  365. }
  366. return dragonBonesData;
  367. }
  368. /**
  369. * @private
  370. */
  371. public DragonBonesData LoadDragonBonesData(TextAsset dragonBonesJSON, string name = null, float scale = 0.01f)
  372. {
  373. if (dragonBonesJSON == null)
  374. {
  375. return null;
  376. }
  377. if (!string.IsNullOrEmpty(name))
  378. {
  379. var existedData = GetDragonBonesData(name);
  380. if (existedData != null)
  381. {
  382. return existedData;
  383. }
  384. }
  385. return ParseDragonBonesData((Dictionary<string, object>)MiniJSON.Json.Deserialize(dragonBonesJSON.text), name, scale); // Unity default Scale Factor.
  386. }
  387. /**
  388. * @language zh_CN
  389. * 加载、解析并添加贴图集数据。
  390. * @param path 贴图集数据在 Resources 中的路径。(其他形式的加载可自行扩展,使用 factory.ParseTextureAtlasData(JSONObject, Material))
  391. * @param name 为数据指定一个名称,以便可以通过这个名称获取数据,如果未设置,则使用数据中的名称。
  392. * @param scale 为贴图集设置一个缩放值。
  393. * @returns 贴图集数据
  394. * @see #ParseTextureAtlasData()
  395. * @see #GetTextureAtlasData()
  396. * @see #AddTextureAtlasData()
  397. * @see #RemoveTextureAtlasData()
  398. * @see DragonBones.UnityTextureAtlasData
  399. */
  400. public UnityTextureAtlasData LoadTextureAtlasData(string path, string name = null, float scale = 0.0f)
  401. {
  402. var index = path.LastIndexOf("Resources");
  403. if (index > 0)
  404. {
  405. path = path.Substring(index + 10);
  406. }
  407. index = path.LastIndexOf(".");
  408. if (index > 0)
  409. {
  410. path = path.Substring(0, index);
  411. }
  412. UnityTextureAtlasData textureAtlasData = null;
  413. if (_pathTextureAtlasDataMap.ContainsKey(path))
  414. {
  415. textureAtlasData = _pathTextureAtlasDataMap[path] as UnityTextureAtlasData;
  416. _refreshTextureAtlas(textureAtlasData);
  417. }
  418. else
  419. {
  420. _textureAtlasPath = path;
  421. textureAtlasData = LoadTextureAtlasData(Resources.Load<TextAsset>(path), name, scale);
  422. if (textureAtlasData != null)
  423. {
  424. _pathTextureAtlasDataMap[path] = textureAtlasData;
  425. }
  426. }
  427. return textureAtlasData;
  428. }
  429. /**
  430. * @private
  431. */
  432. public UnityTextureAtlasData LoadTextureAtlasData(TextAsset textureAtlasJSON, string name = null, float scale = 0.0f)
  433. {
  434. if (textureAtlasJSON == null)
  435. {
  436. return null;
  437. }
  438. var textureAtlasData = ParseTextureAtlasData((Dictionary<string, object>)MiniJSON.Json.Deserialize(textureAtlasJSON.text), null, name, scale) as UnityTextureAtlasData;
  439. var path = _textureAtlasPath;
  440. var index = path.LastIndexOf("Resources");
  441. if (index > 0)
  442. {
  443. path = path.Substring(index + 10);
  444. }
  445. index = path.LastIndexOf("/");
  446. if (index > 0)
  447. {
  448. textureAtlasData.imagePath = path.Substring(0, index + 1) + textureAtlasData.imagePath;
  449. }
  450. index = textureAtlasData.imagePath.LastIndexOf(".");
  451. if (index > 0)
  452. {
  453. textureAtlasData.imagePath = textureAtlasData.imagePath.Substring(0, index);
  454. }
  455. _refreshTextureAtlas(textureAtlasData);
  456. return textureAtlasData;
  457. }
  458. /**
  459. * @private
  460. */
  461. public UnityTextureAtlasData LoadTextureAtlasData(TextAsset textureAtlasJSON, object textureAtlas = null, string name = null, float scale = 0.0f)
  462. {
  463. if (textureAtlasJSON == null)
  464. {
  465. return null;
  466. }
  467. var textureAtlasData = ParseTextureAtlasData((Dictionary<string, object>)MiniJSON.Json.Deserialize(textureAtlasJSON.text), textureAtlas, name, scale) as UnityTextureAtlasData;
  468. if (textureAtlas == null)
  469. {
  470. var path = _textureAtlasPath;
  471. var index = path.LastIndexOf("Resources");
  472. if (index > 0)
  473. {
  474. path = path.Substring(index + 10);
  475. }
  476. index = path.LastIndexOf("/");
  477. if (index > 0)
  478. {
  479. textureAtlasData.imagePath = path.Substring(0, index + 1) + textureAtlasData.imagePath;
  480. }
  481. index = textureAtlasData.imagePath.LastIndexOf(".");
  482. if (index > 0)
  483. {
  484. textureAtlasData.imagePath = textureAtlasData.imagePath.Substring(0, index);
  485. }
  486. _refreshTextureAtlas(textureAtlasData);
  487. }
  488. return textureAtlasData;
  489. }
  490. /**
  491. * @language zh_CN
  492. * 刷新贴图集数据中贴图。
  493. * @see #ParseTextureAtlasData()
  494. * @see #GetTextureAtlasData()
  495. * @see #AddTextureAtlasData()
  496. * @see #RemoveTextureAtlasData()
  497. * @see DragonBones.UnityTextureAtlasData
  498. */
  499. public void RefreshAllTextureAtlas()
  500. {
  501. foreach (var textureAtlasDatas in _textureAtlasDataMap.Values)
  502. {
  503. foreach (UnityTextureAtlasData textureAtlasData in textureAtlasDatas)
  504. {
  505. _refreshTextureAtlas(textureAtlasData);
  506. }
  507. }
  508. }
  509. }
  510. }