UIPackage.cs 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using UnityEngine;
  5. using FairyGUI.Utils;
  6. #if UNITY_EDITOR
  7. using UnityEditor;
  8. #endif
  9. namespace FairyGUI
  10. {
  11. /// <summary>
  12. /// A UI Package contains a description file and some texture, sound assets.
  13. /// </summary>
  14. public class UIPackage
  15. {
  16. /// <summary>
  17. /// Unload UIAssetBundle by FairyGUI system.
  18. /// if use AssetBundlesManager set value to false
  19. /// then unload UIAssetBundle by AssetBundlesManager
  20. /// </summary>
  21. public static bool unloadBundleByFGUI = true;
  22. /// <summary>
  23. /// The event is triggered when all reference to this package item dropped.
  24. /// </summary>
  25. public static event Action<PackageItem> onReleaseResource;
  26. /// <summary>
  27. /// Package id. It is generated by the Editor.
  28. /// </summary>
  29. public string id { get; private set; }
  30. /// <summary>
  31. /// Package name.
  32. /// </summary>
  33. public string name { get; private set; }
  34. /// <summary>
  35. /// Use this callback to provide resources to the package.
  36. /// </summary>
  37. /// <param name="name">Resource name without extension.</param>
  38. /// <param name="extension">Resource extension. e.g. '.png' '.wav'</param>
  39. /// <param name="type">Resource type. e.g. 'Texture' 'AudioClip'</param>
  40. /// <param name="destroyMethod">How to destroy this resource.</param>
  41. /// <returns></returns>
  42. public delegate object LoadResource(string name, string extension, System.Type type, out DestroyMethod destroyMethod);
  43. /// <summary>
  44. /// A async load resource callback. After loaded, you should call item.owner.SetItemAsset.
  45. /// </summary>
  46. /// <param name="name">Resource name without extension.</param>
  47. /// <param name="extension">Resource extension. e.g. '.png' '.wav'</param>
  48. /// <param name="type">Resource type. e.g. 'Texture' 'AudioClip'</param>
  49. /// <param name="item">Resource item object.</param>
  50. /// <returns></returns>
  51. public delegate void LoadResourceAsync(string name, string extension, System.Type type, PackageItem item);
  52. /// <summary>
  53. ///
  54. /// </summary>
  55. /// <param name="result"></param>
  56. public delegate void CreateObjectCallback(GObject result);
  57. List<PackageItem> _items;
  58. Dictionary<string, PackageItem> _itemsById;
  59. Dictionary<string, PackageItem> _itemsByName;
  60. Dictionary<string, string>[] _dependencies;
  61. string _assetPath;
  62. string[] _branches;
  63. internal int _branchIndex;
  64. AssetBundle _resBundle;
  65. string _customId;
  66. bool _fromBundle;
  67. LoadResource _loadFunc;
  68. LoadResourceAsync _loadAsyncFunc;
  69. class AtlasSprite
  70. {
  71. public PackageItem atlas;
  72. public Rect rect = new Rect();
  73. public Vector2 offset = new Vector2();
  74. public Vector2 originalSize = new Vector2();
  75. public bool rotated;
  76. }
  77. Dictionary<string, AtlasSprite> _sprites;
  78. static Dictionary<string, UIPackage> _packageInstById = new Dictionary<string, UIPackage>();
  79. static Dictionary<string, UIPackage> _packageInstByName = new Dictionary<string, UIPackage>();
  80. static List<UIPackage> _packageList = new List<UIPackage>();
  81. static string _branch;
  82. static Dictionary<string, string> _vars = new Dictionary<string, string>();
  83. internal static int _constructing;
  84. public const string URL_PREFIX = "ui://";
  85. #if UNITY_EDITOR
  86. static LoadResource _loadFromAssetsPath = (string name, string extension, System.Type type, out DestroyMethod destroyMethod) =>
  87. {
  88. destroyMethod = DestroyMethod.Unload;
  89. return AssetDatabase.LoadAssetAtPath(name + extension, type);
  90. };
  91. #endif
  92. static LoadResource _loadFromResourcesPath = (string name, string extension, System.Type type, out DestroyMethod destroyMethod) =>
  93. {
  94. destroyMethod = DestroyMethod.Unload;
  95. return Resources.Load(name, type);
  96. };
  97. public UIPackage()
  98. {
  99. _items = new List<PackageItem>();
  100. _itemsById = new Dictionary<string, PackageItem>();
  101. _itemsByName = new Dictionary<string, PackageItem>();
  102. _sprites = new Dictionary<string, AtlasSprite>();
  103. _branchIndex = -1;
  104. }
  105. /// <summary>
  106. ///
  107. /// </summary>
  108. public static string branch
  109. {
  110. get { return _branch; }
  111. set
  112. {
  113. _branch = value;
  114. bool empty = string.IsNullOrEmpty(_branch);
  115. var iter = _packageInstById.GetEnumerator();
  116. while (iter.MoveNext())
  117. {
  118. UIPackage pkg = iter.Current.Value;
  119. if (empty)
  120. pkg._branchIndex = -1;
  121. else if (pkg._branches != null)
  122. pkg._branchIndex = Array.IndexOf(pkg._branches, value);
  123. }
  124. iter.Dispose();
  125. }
  126. }
  127. /// <summary>
  128. ///
  129. /// </summary>
  130. public static string GetVar(string key)
  131. {
  132. string value;
  133. if (_vars.TryGetValue(key, out value))
  134. return value;
  135. else
  136. return null;
  137. }
  138. /// <summary>
  139. ///
  140. /// </summary>
  141. public static void SetVar(string key, string value)
  142. {
  143. if (value == null)
  144. _vars.Remove(key);
  145. else
  146. _vars[key] = value;
  147. }
  148. /// <summary>
  149. /// Return a UIPackage with a certain id.
  150. /// </summary>
  151. /// <param name="id">ID of the package.</param>
  152. /// <returns>UIPackage</returns>
  153. public static UIPackage GetById(string id)
  154. {
  155. UIPackage pkg;
  156. if (_packageInstById.TryGetValue(id, out pkg))
  157. return pkg;
  158. else
  159. return null;
  160. }
  161. /// <summary>
  162. /// Return a UIPackage with a certain name.
  163. /// </summary>
  164. /// <param name="name">Name of the package.</param>
  165. /// <returns>UIPackage</returns>
  166. public static UIPackage GetByName(string name)
  167. {
  168. UIPackage pkg;
  169. if (_packageInstByName.TryGetValue(name, out pkg))
  170. return pkg;
  171. else
  172. return null;
  173. }
  174. /// <summary>
  175. /// Add a UI package from assetbundle.
  176. /// </summary>
  177. /// <param name="bundle">A assetbundle.</param>
  178. /// <returns>UIPackage</returns>
  179. public static UIPackage AddPackage(AssetBundle bundle)
  180. {
  181. return AddPackage(bundle, bundle, null);
  182. }
  183. /// <summary>
  184. /// Add a UI package from two assetbundles. desc and res can be same.
  185. /// </summary>
  186. /// <param name="desc">A assetbunble contains description file.</param>
  187. /// <param name="res">A assetbundle contains resources.</param>
  188. /// <returns>UIPackage</returns>
  189. public static UIPackage AddPackage(AssetBundle desc, AssetBundle res)
  190. {
  191. return AddPackage(desc, res, null);
  192. }
  193. /// <summary>
  194. /// Add a UI package from two assetbundles with a optional main asset name.
  195. /// </summary>
  196. /// <param name="desc">A assetbunble contains description file.</param>
  197. /// <param name="res">A assetbundle contains resources.</param>
  198. /// <param name="mainAssetName">Main asset name. e.g. Basics_fui</param>
  199. /// <returns>UIPackage</returns>
  200. public static UIPackage AddPackage(AssetBundle desc, AssetBundle res, string mainAssetName)
  201. {
  202. byte[] source = null;
  203. if (!string.IsNullOrEmpty(mainAssetName))
  204. {
  205. TextAsset ta = desc.LoadAsset<TextAsset>(mainAssetName);
  206. if (ta != null)
  207. source = ta.bytes;
  208. }
  209. else
  210. {
  211. string[] names = desc.GetAllAssetNames();
  212. string searchPattern = "_fui";
  213. foreach (string n in names)
  214. {
  215. if (n.IndexOf(searchPattern) != -1)
  216. {
  217. TextAsset ta = desc.LoadAsset<TextAsset>(n);
  218. if (ta != null)
  219. {
  220. source = ta.bytes;
  221. mainAssetName = Path.GetFileNameWithoutExtension(n);
  222. break;
  223. }
  224. }
  225. }
  226. }
  227. if (source == null)
  228. throw new Exception("FairyGUI: no package found in this bundle.");
  229. if (unloadBundleByFGUI && desc != res)
  230. desc.Unload(true);
  231. ByteBuffer buffer = new ByteBuffer(source);
  232. UIPackage pkg = new UIPackage();
  233. pkg._resBundle = res;
  234. pkg._fromBundle = true;
  235. int pos = mainAssetName.IndexOf("_fui");
  236. if (pos != -1)
  237. mainAssetName = mainAssetName.Substring(0, pos);
  238. if (!pkg.LoadPackage(buffer, mainAssetName))
  239. return null;
  240. _packageInstById[pkg.id] = pkg;
  241. _packageInstByName[pkg.name] = pkg;
  242. _packageList.Add(pkg);
  243. return pkg;
  244. }
  245. /// <summary>
  246. /// Add a UI package from a path relative to Unity Resources path.
  247. /// </summary>
  248. /// <param name="descFilePath">Path relative to Unity Resources path.</param>
  249. /// <returns>UIPackage</returns>
  250. public static UIPackage AddPackage(string descFilePath)
  251. {
  252. if (descFilePath.StartsWith("Assets/"))
  253. {
  254. #if UNITY_EDITOR
  255. return AddPackage(descFilePath, _loadFromAssetsPath);
  256. #else
  257. Debug.LogWarning("FairyGUI: failed to load package in '" + descFilePath + "'");
  258. return null;
  259. #endif
  260. }
  261. else
  262. return AddPackage(descFilePath, _loadFromResourcesPath);
  263. }
  264. /// <summary>
  265. /// 使用自定义的加载方式载入一个包。
  266. /// </summary>
  267. /// <param name="assetPath">包资源路径。</param>
  268. /// <param name="loadFunc">载入函数</param>
  269. /// <returns></returns>
  270. public static UIPackage AddPackage(string assetPath, LoadResource loadFunc)
  271. {
  272. if (_packageInstById.ContainsKey(assetPath))
  273. return _packageInstById[assetPath];
  274. DestroyMethod dm;
  275. TextAsset asset = (TextAsset)loadFunc(assetPath + "_fui", ".bytes", typeof(TextAsset), out dm);
  276. if (asset == null)
  277. {
  278. if (Application.isPlaying)
  279. throw new Exception("FairyGUI: Cannot load ui package in '" + assetPath + "'");
  280. else
  281. Debug.LogWarning("FairyGUI: Cannot load ui package in '" + assetPath + "'");
  282. }
  283. ByteBuffer buffer = new ByteBuffer(asset.bytes);
  284. UIPackage pkg = new UIPackage();
  285. pkg._loadFunc = loadFunc;
  286. pkg._assetPath = assetPath;
  287. if (!pkg.LoadPackage(buffer, assetPath))
  288. return null;
  289. _packageInstById[pkg.id] = pkg;
  290. _packageInstByName[pkg.name] = pkg;
  291. _packageInstById[assetPath] = pkg;
  292. _packageList.Add(pkg);
  293. return pkg;
  294. }
  295. /// <summary>
  296. /// Load Package by custom load method.
  297. /// </summary>
  298. /// <param name="descData">Description file data</param>
  299. /// <param name="assetNamePrefix">Prefix of the resource file name. The file name would be in format of 'assetNamePrefix_resFileName'. It can be empty.</param>
  300. /// <param name="loadFunc">Load method</param>
  301. /// <returns></returns>
  302. public static UIPackage AddPackage(byte[] descData, string assetNamePrefix, LoadResource loadFunc)
  303. {
  304. ByteBuffer buffer = new ByteBuffer(descData);
  305. UIPackage pkg = new UIPackage();
  306. pkg._loadFunc = loadFunc;
  307. if (!pkg.LoadPackage(buffer, assetNamePrefix))
  308. return null;
  309. _packageInstById[pkg.id] = pkg;
  310. _packageInstByName[pkg.name] = pkg;
  311. _packageList.Add(pkg);
  312. return pkg;
  313. }
  314. /// <summary>
  315. /// Load Package async by custom load method.
  316. /// </summary>
  317. /// <param name="descData">Description file data</param>
  318. /// <param name="assetNamePrefix">refix of the resource file name. The file name would be in format of 'assetNamePrefix_resFileName'. It can be empty.</param>
  319. /// <param name="loadFunc">Load method</param>
  320. /// <returns></returns>
  321. public static UIPackage AddPackage(byte[] descData, string assetNamePrefix, LoadResourceAsync loadFunc)
  322. {
  323. ByteBuffer buffer = new ByteBuffer(descData);
  324. UIPackage pkg = new UIPackage();
  325. pkg._loadAsyncFunc = loadFunc;
  326. if (!pkg.LoadPackage(buffer, assetNamePrefix))
  327. return null;
  328. _packageInstById[pkg.id] = pkg;
  329. _packageInstByName[pkg.name] = pkg;
  330. _packageList.Add(pkg);
  331. return pkg;
  332. }
  333. /// <summary>
  334. /// Remove a package. All resources in this package will be disposed.
  335. /// </summary>
  336. /// <param name="packageIdOrName"></param>
  337. public static void RemovePackage(string packageIdOrName)
  338. {
  339. UIPackage pkg = null;
  340. if (!_packageInstById.TryGetValue(packageIdOrName, out pkg))
  341. {
  342. if (!_packageInstByName.TryGetValue(packageIdOrName, out pkg))
  343. throw new Exception("FairyGUI: '" + packageIdOrName + "' is not a valid package id or name.");
  344. }
  345. pkg.Dispose();
  346. _packageInstById.Remove(pkg.id);
  347. if (pkg._customId != null)
  348. _packageInstById.Remove(pkg._customId);
  349. if (pkg._assetPath != null)
  350. _packageInstById.Remove(pkg._assetPath);
  351. _packageInstByName.Remove(pkg.name);
  352. _packageList.Remove(pkg);
  353. }
  354. /// <summary>
  355. ///
  356. /// </summary>
  357. public static void RemoveAllPackages()
  358. {
  359. if (_packageInstById.Count > 0)
  360. {
  361. UIPackage[] pkgs = _packageList.ToArray();
  362. foreach (UIPackage pkg in pkgs)
  363. {
  364. pkg.Dispose();
  365. }
  366. }
  367. _packageList.Clear();
  368. _packageInstById.Clear();
  369. _packageInstByName.Clear();
  370. }
  371. /// <summary>
  372. ///
  373. /// </summary>
  374. /// <returns></returns>
  375. public static List<UIPackage> GetPackages()
  376. {
  377. return _packageList;
  378. }
  379. /// <summary>
  380. /// Create a UI object.
  381. /// </summary>
  382. /// <param name="pkgName">Package name.</param>
  383. /// <param name="resName">Resource name.</param>
  384. /// <returns>A UI object.</returns>
  385. public static GObject CreateObject(string pkgName, string resName)
  386. {
  387. UIPackage pkg = GetByName(pkgName);
  388. if (pkg != null)
  389. return pkg.CreateObject(resName);
  390. else
  391. return null;
  392. }
  393. /// <summary>
  394. /// Create a UI object.
  395. /// </summary>
  396. /// <param name="pkgName">Package name.</param>
  397. /// <param name="resName">Resource name.</param>
  398. /// <param name="userClass">Custom implementation of this object.</param>
  399. /// <returns>A UI object.</returns>
  400. public static GObject CreateObject(string pkgName, string resName, System.Type userClass)
  401. {
  402. UIPackage pkg = GetByName(pkgName);
  403. if (pkg != null)
  404. return pkg.CreateObject(resName, userClass);
  405. else
  406. return null;
  407. }
  408. /// <summary>
  409. /// Create a UI object.
  410. /// </summary>
  411. /// <param name="url">Resource url.</param>
  412. /// <returns>A UI object.</returns>
  413. public static GObject CreateObjectFromURL(string url)
  414. {
  415. PackageItem pi = GetItemByURL(url);
  416. if (pi != null)
  417. return pi.owner.CreateObject(pi, null);
  418. else
  419. return null;
  420. }
  421. /// <summary>
  422. /// Create a UI object.
  423. /// </summary>
  424. /// <param name="url">Resource url.</param>
  425. /// <param name="userClass">Custom implementation of this object.</param>
  426. /// <returns>A UI object.</returns>
  427. public static GObject CreateObjectFromURL(string url, System.Type userClass)
  428. {
  429. PackageItem pi = GetItemByURL(url);
  430. if (pi != null)
  431. return pi.owner.CreateObject(pi, userClass);
  432. else
  433. return null;
  434. }
  435. public static void CreateObjectAsync(string pkgName, string resName, CreateObjectCallback callback)
  436. {
  437. UIPackage pkg = GetByName(pkgName);
  438. if (pkg != null)
  439. pkg.CreateObjectAsync(resName, callback);
  440. else
  441. Debug.LogError("FairyGUI: package not found - " + pkgName);
  442. }
  443. public static void CreateObjectFromURL(string url, CreateObjectCallback callback)
  444. {
  445. PackageItem pi = GetItemByURL(url);
  446. if (pi != null)
  447. AsyncCreationHelper.CreateObject(pi, callback);
  448. else
  449. Debug.LogError("FairyGUI: resource not found - " + url);
  450. }
  451. /// <summary>
  452. /// Get a asset with a certain name.
  453. /// </summary>
  454. /// <param name="pkgName">Package name.</param>
  455. /// <param name="resName">Resource name.</param>
  456. /// <returns>If resource is atlas, returns NTexture; If resource is sound, returns AudioClip.</returns>
  457. public static object GetItemAsset(string pkgName, string resName)
  458. {
  459. UIPackage pkg = GetByName(pkgName);
  460. if (pkg != null)
  461. return pkg.GetItemAsset(resName);
  462. else
  463. return null;
  464. }
  465. /// <summary>
  466. /// Get a asset with a certain name.
  467. /// </summary>
  468. /// <param name="url">Resource url.</param>
  469. /// <returns>If resource is atlas, returns NTexture; If resource is sound, returns AudioClip.</returns>
  470. public static object GetItemAssetByURL(string url)
  471. {
  472. PackageItem item = GetItemByURL(url);
  473. if (item == null)
  474. return null;
  475. return item.owner.GetItemAsset(item);
  476. }
  477. /// <summary>
  478. /// Get url of an item in package.
  479. /// </summary>
  480. /// <param name="pkgName">Package name.</param>
  481. /// <param name="resName">Resource name.</param>
  482. /// <returns>Url.</returns>
  483. public static string GetItemURL(string pkgName, string resName)
  484. {
  485. UIPackage pkg = GetByName(pkgName);
  486. if (pkg == null)
  487. return null;
  488. PackageItem pi;
  489. if (!pkg._itemsByName.TryGetValue(resName, out pi))
  490. return null;
  491. return URL_PREFIX + pkg.id + pi.id;
  492. }
  493. public static PackageItem GetItemByURL(string url)
  494. {
  495. if (url == null)
  496. return null;
  497. int pos1 = url.IndexOf("//");
  498. if (pos1 == -1)
  499. return null;
  500. int pos2 = url.IndexOf('/', pos1 + 2);
  501. if (pos2 == -1)
  502. {
  503. if (url.Length > 13)
  504. {
  505. string pkgId = url.Substring(5, 8);
  506. UIPackage pkg = GetById(pkgId);
  507. if (pkg != null)
  508. {
  509. string srcId = url.Substring(13);
  510. return pkg.GetItem(srcId);
  511. }
  512. }
  513. }
  514. else
  515. {
  516. string pkgName = url.Substring(pos1 + 2, pos2 - pos1 - 2);
  517. UIPackage pkg = GetByName(pkgName);
  518. if (pkg != null)
  519. {
  520. string srcName = url.Substring(pos2 + 1);
  521. return pkg.GetItemByName(srcName);
  522. }
  523. }
  524. return null;
  525. }
  526. /// <summary>
  527. /// 将'ui://包名/组件名'转换为以内部id表达的url格式。如果传入的url本身就是内部id格式,则直接返回。
  528. /// 同时这个方法还带格式检测,如果传入不正确的url,会返回null。
  529. /// </summary>
  530. /// <param name="url"></param>
  531. /// <returns></returns>
  532. public static string NormalizeURL(string url)
  533. {
  534. if (url == null)
  535. return null;
  536. int pos1 = url.IndexOf("//");
  537. if (pos1 == -1)
  538. return null;
  539. int pos2 = url.IndexOf('/', pos1 + 2);
  540. if (pos2 == -1)
  541. return url;
  542. else
  543. {
  544. string pkgName = url.Substring(pos1 + 2, pos2 - pos1 - 2);
  545. string srcName = url.Substring(pos2 + 1);
  546. return GetItemURL(pkgName, srcName);
  547. }
  548. }
  549. /// <summary>
  550. /// Set strings source.
  551. /// </summary>
  552. /// <param name="source"></param>
  553. public static void SetStringsSource(XML source)
  554. {
  555. TranslationHelper.LoadFromXML(source);
  556. }
  557. /// <summary>
  558. ///
  559. /// </summary>
  560. public string assetPath
  561. {
  562. get { return _assetPath; }
  563. }
  564. /// <summary>
  565. /// Set a custom id for package, then you can use it in GetById.
  566. /// </summary>
  567. public string customId
  568. {
  569. get { return _customId; }
  570. set
  571. {
  572. if (_customId != null)
  573. _packageInstById.Remove(_customId);
  574. _customId = value;
  575. if (_customId != null)
  576. _packageInstById[_customId] = this;
  577. }
  578. }
  579. /// <summary>
  580. ///
  581. /// </summary>
  582. public AssetBundle resBundle
  583. {
  584. get { return _resBundle; }
  585. }
  586. /// <summary>
  587. /// 获得本包依赖的包的id列表
  588. /// </summary>
  589. public Dictionary<string, string>[] dependencies
  590. {
  591. get { return _dependencies; }
  592. }
  593. bool LoadPackage(ByteBuffer buffer, string assetNamePrefix)
  594. {
  595. if (buffer.ReadUint() != 0x46475549)
  596. {
  597. if (Application.isPlaying)
  598. throw new Exception("FairyGUI: old package format found in '" + assetNamePrefix + "'");
  599. else
  600. {
  601. Debug.LogWarning("FairyGUI: old package format found in '" + assetNamePrefix + "'");
  602. return false;
  603. }
  604. }
  605. buffer.version = buffer.ReadInt();
  606. bool ver2 = buffer.version >= 2;
  607. buffer.ReadBool(); //compressed
  608. id = buffer.ReadString();
  609. name = buffer.ReadString();
  610. UIPackage existingPkg;
  611. if (_packageInstById.TryGetValue(id, out existingPkg))
  612. {
  613. if (name != existingPkg.name)
  614. Debug.LogWarning("FairyGUI: Package conflicts, '" + name + "' and '" + existingPkg.name + "'");
  615. #if UNITY_EDITOR
  616. //maybe multiple pkgs in different folder, pefer the one in resources
  617. if (Application.isEditor)
  618. {
  619. if (existingPkg._loadFunc == _loadFromAssetsPath) //old one is outside resources path
  620. existingPkg.Dispose(); //replace the existing
  621. else if (existingPkg._loadFunc == _loadFromResourcesPath && _loadFunc == _loadFromResourcesPath
  622. && _assetPath.Length < existingPkg._assetPath.Length) //both in resources path, pefer short path
  623. existingPkg.Dispose(); //replace the existing
  624. else //keep the existing
  625. return false;
  626. }
  627. #endif
  628. }
  629. buffer.Skip(20);
  630. int indexTablePos = buffer.position;
  631. int cnt;
  632. buffer.Seek(indexTablePos, 4);
  633. cnt = buffer.ReadInt();
  634. string[] stringTable = new string[cnt];
  635. for (int i = 0; i < cnt; i++)
  636. stringTable[i] = buffer.ReadString();
  637. buffer.stringTable = stringTable;
  638. if (buffer.Seek(indexTablePos, 5))
  639. {
  640. cnt = buffer.ReadInt();
  641. for (int i = 0; i < cnt; i++)
  642. {
  643. int index = buffer.ReadUshort();
  644. int len = buffer.ReadInt();
  645. stringTable[index] = buffer.ReadString(len);
  646. }
  647. }
  648. buffer.Seek(indexTablePos, 0);
  649. cnt = buffer.ReadShort();
  650. _dependencies = new Dictionary<string, string>[cnt];
  651. for (int i = 0; i < cnt; i++)
  652. {
  653. Dictionary<string, string> kv = new Dictionary<string, string>();
  654. kv.Add("id", buffer.ReadS());
  655. kv.Add("name", buffer.ReadS());
  656. _dependencies[i] = kv;
  657. }
  658. bool branchIncluded = false;
  659. if (ver2)
  660. {
  661. cnt = buffer.ReadShort();
  662. if (cnt > 0)
  663. {
  664. _branches = buffer.ReadSArray(cnt);
  665. if (!string.IsNullOrEmpty(_branch))
  666. _branchIndex = Array.IndexOf(_branches, _branch);
  667. }
  668. branchIncluded = cnt > 0;
  669. }
  670. buffer.Seek(indexTablePos, 1);
  671. PackageItem pi;
  672. string assetPath;
  673. if (assetNamePrefix.Length > 0)
  674. {
  675. assetPath = Path.GetDirectoryName(assetNamePrefix);
  676. if (assetPath.Length > 0)
  677. assetPath += "/";
  678. assetNamePrefix = assetNamePrefix + "_";
  679. }
  680. else
  681. assetPath = string.Empty;
  682. cnt = buffer.ReadShort();
  683. for (int i = 0; i < cnt; i++)
  684. {
  685. int nextPos = buffer.ReadInt();
  686. nextPos += buffer.position;
  687. pi = new PackageItem();
  688. pi.owner = this;
  689. pi.type = (PackageItemType)buffer.ReadByte();
  690. pi.id = buffer.ReadS();
  691. pi.name = buffer.ReadS();
  692. buffer.ReadS(); //path
  693. pi.file = buffer.ReadS();
  694. pi.exported = buffer.ReadBool();
  695. pi.width = buffer.ReadInt();
  696. pi.height = buffer.ReadInt();
  697. switch (pi.type)
  698. {
  699. case PackageItemType.Image:
  700. {
  701. pi.objectType = ObjectType.Image;
  702. int scaleOption = buffer.ReadByte();
  703. if (scaleOption == 1)
  704. {
  705. Rect rect = new Rect();
  706. rect.x = buffer.ReadInt();
  707. rect.y = buffer.ReadInt();
  708. rect.width = buffer.ReadInt();
  709. rect.height = buffer.ReadInt();
  710. pi.scale9Grid = rect;
  711. pi.tileGridIndice = buffer.ReadInt();
  712. }
  713. else if (scaleOption == 2)
  714. pi.scaleByTile = true;
  715. buffer.ReadBool(); //smoothing
  716. break;
  717. }
  718. case PackageItemType.MovieClip:
  719. {
  720. buffer.ReadBool(); //smoothing
  721. pi.objectType = ObjectType.MovieClip;
  722. pi.rawData = buffer.ReadBuffer();
  723. break;
  724. }
  725. case PackageItemType.Font:
  726. {
  727. pi.rawData = buffer.ReadBuffer();
  728. break;
  729. }
  730. case PackageItemType.Component:
  731. {
  732. int extension = buffer.ReadByte();
  733. if (extension > 0)
  734. pi.objectType = (ObjectType)extension;
  735. else
  736. pi.objectType = ObjectType.Component;
  737. pi.rawData = buffer.ReadBuffer();
  738. UIObjectFactory.ResolvePackageItemExtension(pi);
  739. break;
  740. }
  741. case PackageItemType.Atlas:
  742. case PackageItemType.Sound:
  743. case PackageItemType.Misc:
  744. {
  745. pi.file = assetNamePrefix + pi.file;
  746. break;
  747. }
  748. case PackageItemType.Spine:
  749. case PackageItemType.DragoneBones:
  750. {
  751. pi.file = assetPath + pi.file;
  752. pi.skeletonAnchor.x = buffer.ReadFloat();
  753. pi.skeletonAnchor.y = buffer.ReadFloat();
  754. break;
  755. }
  756. }
  757. if (ver2)
  758. {
  759. string str = buffer.ReadS();//branch
  760. if (str != null)
  761. pi.name = str + "/" + pi.name;
  762. int branchCnt = buffer.ReadByte();
  763. if (branchCnt > 0)
  764. {
  765. if (branchIncluded)
  766. pi.branches = buffer.ReadSArray(branchCnt);
  767. else
  768. _itemsById[buffer.ReadS()] = pi;
  769. }
  770. int highResCnt = buffer.ReadByte();
  771. if (highResCnt > 0)
  772. pi.highResolution = buffer.ReadSArray(highResCnt);
  773. }
  774. _items.Add(pi);
  775. _itemsById[pi.id] = pi;
  776. if (pi.name != null)
  777. _itemsByName[pi.name] = pi;
  778. buffer.position = nextPos;
  779. }
  780. buffer.Seek(indexTablePos, 2);
  781. cnt = buffer.ReadShort();
  782. for (int i = 0; i < cnt; i++)
  783. {
  784. int nextPos = buffer.ReadUshort();
  785. nextPos += buffer.position;
  786. string itemId = buffer.ReadS();
  787. pi = _itemsById[buffer.ReadS()];
  788. AtlasSprite sprite = new AtlasSprite();
  789. sprite.atlas = pi;
  790. sprite.rect.x = buffer.ReadInt();
  791. sprite.rect.y = buffer.ReadInt();
  792. sprite.rect.width = buffer.ReadInt();
  793. sprite.rect.height = buffer.ReadInt();
  794. sprite.rotated = buffer.ReadBool();
  795. if (ver2 && buffer.ReadBool())
  796. {
  797. sprite.offset.x = buffer.ReadInt();
  798. sprite.offset.y = buffer.ReadInt();
  799. sprite.originalSize.x = buffer.ReadInt();
  800. sprite.originalSize.y = buffer.ReadInt();
  801. }
  802. else if (sprite.rotated)
  803. {
  804. sprite.originalSize.x = sprite.rect.height;
  805. sprite.originalSize.y = sprite.rect.width;
  806. }
  807. else
  808. {
  809. sprite.originalSize.x = sprite.rect.width;
  810. sprite.originalSize.y = sprite.rect.height;
  811. }
  812. _sprites[itemId] = sprite;
  813. buffer.position = nextPos;
  814. }
  815. if (buffer.Seek(indexTablePos, 3))
  816. {
  817. cnt = buffer.ReadShort();
  818. for (int i = 0; i < cnt; i++)
  819. {
  820. int nextPos = buffer.ReadInt();
  821. nextPos += buffer.position;
  822. if (_itemsById.TryGetValue(buffer.ReadS(), out pi))
  823. {
  824. if (pi.type == PackageItemType.Image)
  825. {
  826. pi.pixelHitTestData = new PixelHitTestData();
  827. pi.pixelHitTestData.Load(buffer);
  828. }
  829. }
  830. buffer.position = nextPos;
  831. }
  832. }
  833. if (!Application.isPlaying)
  834. _items.Sort(ComparePackageItem);
  835. return true;
  836. }
  837. static int ComparePackageItem(PackageItem p1, PackageItem p2)
  838. {
  839. if (p1.name != null && p2.name != null)
  840. return p1.name.CompareTo(p2.name);
  841. else
  842. return 0;
  843. }
  844. /// <summary>
  845. ///
  846. /// </summary>
  847. public void LoadAllAssets()
  848. {
  849. int cnt = _items.Count;
  850. for (int i = 0; i < cnt; i++)
  851. GetItemAsset(_items[i]);
  852. }
  853. /// <summary>
  854. ///
  855. /// </summary>
  856. public void UnloadAssets()
  857. {
  858. int cnt = _items.Count;
  859. for (int i = 0; i < cnt; i++)
  860. {
  861. PackageItem pi = _items[i];
  862. if (pi.type == PackageItemType.Atlas)
  863. {
  864. if (pi.texture != null)
  865. pi.texture.Unload();
  866. }
  867. else if (pi.type == PackageItemType.Sound)
  868. {
  869. if (pi.audioClip != null)
  870. pi.audioClip.Unload();
  871. }
  872. }
  873. if (unloadBundleByFGUI &&
  874. _resBundle != null)
  875. {
  876. _resBundle.Unload(true);
  877. _resBundle = null;
  878. }
  879. }
  880. /// <summary>
  881. ///
  882. /// </summary>
  883. public void ReloadAssets()
  884. {
  885. if (_fromBundle)
  886. throw new Exception("FairyGUI: new bundle must be passed to this function");
  887. ReloadAssets(null);
  888. }
  889. /// <summary>
  890. ///
  891. /// </summary>
  892. public void ReloadAssets(AssetBundle resBundle)
  893. {
  894. _resBundle = resBundle;
  895. _fromBundle = _resBundle != null;
  896. int cnt = _items.Count;
  897. for (int i = 0; i < cnt; i++)
  898. {
  899. PackageItem pi = _items[i];
  900. if (pi.type == PackageItemType.Atlas)
  901. {
  902. if (pi.texture != null && pi.texture.nativeTexture == null)
  903. LoadAtlas(pi);
  904. }
  905. else if (pi.type == PackageItemType.Sound)
  906. {
  907. if (pi.audioClip != null && pi.audioClip.nativeClip == null)
  908. LoadSound(pi);
  909. }
  910. }
  911. }
  912. void Dispose()
  913. {
  914. int cnt = _items.Count;
  915. for (int i = 0; i < cnt; i++)
  916. {
  917. PackageItem pi = _items[i];
  918. if (pi.type == PackageItemType.Atlas)
  919. {
  920. if (pi.texture != null)
  921. {
  922. pi.texture.Dispose();
  923. pi.texture = null;
  924. }
  925. }
  926. else if (pi.type == PackageItemType.Sound)
  927. {
  928. if (pi.audioClip != null)
  929. {
  930. pi.audioClip.Unload();
  931. pi.audioClip = null;
  932. }
  933. }
  934. }
  935. _items.Clear();
  936. if (unloadBundleByFGUI &&
  937. _resBundle != null)
  938. {
  939. _resBundle.Unload(true);
  940. _resBundle = null;
  941. }
  942. }
  943. /// <summary>
  944. ///
  945. /// </summary>
  946. /// <param name="resName"></param>
  947. /// <returns></returns>
  948. public GObject CreateObject(string resName)
  949. {
  950. PackageItem pi;
  951. if (!_itemsByName.TryGetValue(resName, out pi))
  952. {
  953. Debug.LogError("FairyGUI: resource not found - " + resName + " in " + this.name);
  954. return null;
  955. }
  956. return CreateObject(pi, null);
  957. }
  958. /// <summary>
  959. ///
  960. /// </summary>
  961. /// <param name="resName"></param>
  962. /// <param name="userClass"></param>
  963. /// <returns></returns>
  964. public GObject CreateObject(string resName, System.Type userClass)
  965. {
  966. PackageItem pi;
  967. if (!_itemsByName.TryGetValue(resName, out pi))
  968. {
  969. Debug.LogError("FairyGUI: resource not found - " + resName + " in " + this.name);
  970. return null;
  971. }
  972. return CreateObject(pi, userClass);
  973. }
  974. public void CreateObjectAsync(string resName, CreateObjectCallback callback)
  975. {
  976. PackageItem pi;
  977. if (!_itemsByName.TryGetValue(resName, out pi))
  978. {
  979. Debug.LogError("FairyGUI: resource not found - " + resName + " in " + this.name);
  980. return;
  981. }
  982. AsyncCreationHelper.CreateObject(pi, callback);
  983. }
  984. GObject CreateObject(PackageItem item, System.Type userClass)
  985. {
  986. Stats.LatestObjectCreation = 0;
  987. Stats.LatestGraphicsCreation = 0;
  988. GetItemAsset(item);
  989. GObject g = UIObjectFactory.NewObject(item, userClass);
  990. if (g == null)
  991. return null;
  992. _constructing++;
  993. g.ConstructFromResource();
  994. _constructing--;
  995. return g;
  996. }
  997. /// <summary>
  998. ///
  999. /// </summary>
  1000. /// <param name="resName"></param>
  1001. /// <returns></returns>
  1002. public object GetItemAsset(string resName)
  1003. {
  1004. PackageItem pi;
  1005. if (!_itemsByName.TryGetValue(resName, out pi))
  1006. {
  1007. Debug.LogError("FairyGUI: Resource not found - " + resName + " in " + this.name);
  1008. return null;
  1009. }
  1010. return GetItemAsset(pi);
  1011. }
  1012. public List<PackageItem> GetItems()
  1013. {
  1014. return _items;
  1015. }
  1016. public PackageItem GetItem(string itemId)
  1017. {
  1018. PackageItem pi;
  1019. if (_itemsById.TryGetValue(itemId, out pi))
  1020. return pi;
  1021. else
  1022. return null;
  1023. }
  1024. public PackageItem GetItemByName(string itemName)
  1025. {
  1026. PackageItem pi;
  1027. if (_itemsByName.TryGetValue(itemName, out pi))
  1028. return pi;
  1029. else
  1030. return null;
  1031. }
  1032. public object GetItemAsset(PackageItem item)
  1033. {
  1034. switch (item.type)
  1035. {
  1036. case PackageItemType.Image:
  1037. if (item.texture == null)
  1038. LoadImage(item);
  1039. return item.texture;
  1040. case PackageItemType.Atlas:
  1041. if (item.texture == null)
  1042. LoadAtlas(item);
  1043. return item.texture;
  1044. case PackageItemType.Sound:
  1045. if (item.audioClip == null)
  1046. LoadSound(item);
  1047. return item.audioClip;
  1048. case PackageItemType.Font:
  1049. if (item.bitmapFont == null)
  1050. LoadFont(item);
  1051. return item.bitmapFont;
  1052. case PackageItemType.MovieClip:
  1053. if (item.frames == null)
  1054. LoadMovieClip(item);
  1055. return item.frames;
  1056. case PackageItemType.Component:
  1057. return item.rawData;
  1058. case PackageItemType.Misc:
  1059. return LoadBinary(item);
  1060. case PackageItemType.Spine:
  1061. if (item.skeletonAsset == null)
  1062. LoadSpine(item);
  1063. return item.skeletonAsset;
  1064. case PackageItemType.DragoneBones:
  1065. if (item.skeletonAsset == null)
  1066. LoadDragonBones(item);
  1067. return item.skeletonAsset;
  1068. default:
  1069. return null;
  1070. }
  1071. }
  1072. /// <summary>
  1073. ///
  1074. /// </summary>
  1075. /// <param name="item"></param>
  1076. /// <param name="asset"></param>
  1077. /// <param name="destroyMethod"></param>
  1078. public void SetItemAsset(PackageItem item, object asset, DestroyMethod destroyMethod)
  1079. {
  1080. switch (item.type)
  1081. {
  1082. case PackageItemType.Atlas:
  1083. if (item.texture == null)
  1084. item.texture = new NTexture(null, new Rect(0, 0, item.width, item.height));
  1085. item.texture.Reload((Texture)asset, null);
  1086. item.texture.destroyMethod = destroyMethod;
  1087. break;
  1088. case PackageItemType.Sound:
  1089. if (item.audioClip == null)
  1090. item.audioClip = new NAudioClip(null);
  1091. item.audioClip.Reload((AudioClip)asset);
  1092. item.audioClip.destroyMethod = destroyMethod;
  1093. break;
  1094. case PackageItemType.Spine:
  1095. #if FAIRYGUI_SPINE
  1096. item.skeletonAsset = (Spine.Unity.SkeletonDataAsset)asset;
  1097. #endif
  1098. break;
  1099. case PackageItemType.DragoneBones:
  1100. #if FAIRYGUI_DRAGONBONES
  1101. item.skeletonAsset = (DragonBones.UnityDragonBonesData)asset;
  1102. #endif
  1103. break;
  1104. }
  1105. }
  1106. void LoadAtlas(PackageItem item)
  1107. {
  1108. string ext = Path.GetExtension(item.file);
  1109. string fileName = item.file.Substring(0, item.file.Length - ext.Length);
  1110. if (_loadAsyncFunc != null)
  1111. {
  1112. _loadAsyncFunc(fileName, ext, typeof(Texture), item);
  1113. if (item.texture == null)
  1114. item.texture = new NTexture(null, new Rect(0, 0, item.width, item.height));
  1115. item.texture.destroyMethod = DestroyMethod.None;
  1116. }
  1117. else
  1118. {
  1119. Texture tex = null;
  1120. Texture alphaTex = null;
  1121. DestroyMethod dm;
  1122. if (_fromBundle)
  1123. {
  1124. if (_resBundle != null)
  1125. tex = _resBundle.LoadAsset<Texture>(fileName);
  1126. else
  1127. Debug.LogWarning("FairyGUI: bundle already unloaded.");
  1128. dm = DestroyMethod.None;
  1129. }
  1130. else
  1131. tex = (Texture)_loadFunc(fileName, ext, typeof(Texture), out dm);
  1132. if (tex == null)
  1133. Debug.LogWarning("FairyGUI: texture '" + item.file + "' not found in " + this.name);
  1134. else if (!(tex is Texture2D))
  1135. {
  1136. Debug.LogWarning("FairyGUI: settings for '" + item.file + "' is wrong! Correct values are: (Texture Type=Default, Texture Shape=2D)");
  1137. tex = null;
  1138. }
  1139. else
  1140. {
  1141. if (((Texture2D)tex).mipmapCount > 1)
  1142. Debug.LogWarning("FairyGUI: settings for '" + item.file + "' is wrong! Correct values are: (Generate Mip Maps=unchecked)");
  1143. }
  1144. if (tex != null)
  1145. {
  1146. fileName = fileName + "!a";
  1147. if (_fromBundle)
  1148. {
  1149. if (_resBundle != null)
  1150. alphaTex = _resBundle.LoadAsset<Texture2D>(fileName);
  1151. }
  1152. else
  1153. alphaTex = (Texture2D)_loadFunc(fileName, ext, typeof(Texture2D), out dm);
  1154. }
  1155. if (tex == null)
  1156. {
  1157. tex = NTexture.CreateEmptyTexture();
  1158. dm = DestroyMethod.Destroy;
  1159. }
  1160. if (item.texture == null)
  1161. {
  1162. item.texture = new NTexture(tex, alphaTex, (float)tex.width / item.width, (float)tex.height / item.height);
  1163. item.texture.onRelease += (NTexture t) =>
  1164. {
  1165. if (onReleaseResource != null)
  1166. onReleaseResource(item);
  1167. };
  1168. }
  1169. else
  1170. item.texture.Reload(tex, alphaTex);
  1171. item.texture.destroyMethod = dm;
  1172. }
  1173. }
  1174. void LoadImage(PackageItem item)
  1175. {
  1176. AtlasSprite sprite;
  1177. if (_sprites.TryGetValue(item.id, out sprite))
  1178. {
  1179. NTexture atlas = (NTexture)GetItemAsset(sprite.atlas);
  1180. if (atlas.width == sprite.rect.width && atlas.height == sprite.rect.height)
  1181. item.texture = atlas;
  1182. else
  1183. item.texture = new NTexture(atlas, sprite.rect, sprite.rotated, sprite.originalSize, sprite.offset);
  1184. }
  1185. else
  1186. item.texture = NTexture.Empty;
  1187. }
  1188. void LoadSound(PackageItem item)
  1189. {
  1190. string ext = Path.GetExtension(item.file);
  1191. string fileName = item.file.Substring(0, item.file.Length - ext.Length);
  1192. if (_loadAsyncFunc != null)
  1193. {
  1194. _loadAsyncFunc(fileName, ext, typeof(AudioClip), item);
  1195. if (item.audioClip == null)
  1196. item.audioClip = new NAudioClip(null);
  1197. item.audioClip.destroyMethod = DestroyMethod.None;
  1198. }
  1199. else
  1200. {
  1201. AudioClip audioClip = null;
  1202. DestroyMethod dm;
  1203. if (_fromBundle)
  1204. {
  1205. if (_resBundle != null)
  1206. audioClip = _resBundle.LoadAsset<AudioClip>(fileName);
  1207. dm = DestroyMethod.None;
  1208. }
  1209. else
  1210. {
  1211. audioClip = (AudioClip)_loadFunc(fileName, ext, typeof(AudioClip), out dm);
  1212. }
  1213. if (item.audioClip == null)
  1214. item.audioClip = new NAudioClip(audioClip);
  1215. else
  1216. item.audioClip.Reload(audioClip);
  1217. item.audioClip.destroyMethod = dm;
  1218. }
  1219. }
  1220. byte[] LoadBinary(PackageItem item)
  1221. {
  1222. string ext = Path.GetExtension(item.file);
  1223. string fileName = item.file.Substring(0, item.file.Length - ext.Length);
  1224. TextAsset ta;
  1225. if (_resBundle != null)
  1226. {
  1227. ta = _resBundle.LoadAsset<TextAsset>(fileName);
  1228. if (ta != null)
  1229. return ta.bytes;
  1230. else
  1231. return null;
  1232. }
  1233. else
  1234. {
  1235. DestroyMethod dm;
  1236. object ret = _loadFunc(fileName, ext, typeof(TextAsset), out dm);
  1237. if (ret == null)
  1238. return null;
  1239. if (ret is byte[])
  1240. return (byte[])ret;
  1241. else
  1242. return ((TextAsset)ret).bytes;
  1243. }
  1244. }
  1245. void LoadMovieClip(PackageItem item)
  1246. {
  1247. ByteBuffer buffer = item.rawData;
  1248. buffer.Seek(0, 0);
  1249. item.interval = buffer.ReadInt() / 1000f;
  1250. item.swing = buffer.ReadBool();
  1251. item.repeatDelay = buffer.ReadInt() / 1000f;
  1252. buffer.Seek(0, 1);
  1253. int frameCount = buffer.ReadShort();
  1254. item.frames = new MovieClip.Frame[frameCount];
  1255. string spriteId;
  1256. MovieClip.Frame frame;
  1257. AtlasSprite sprite;
  1258. Rect frameRect = new Rect();
  1259. for (int i = 0; i < frameCount; i++)
  1260. {
  1261. int nextPos = buffer.ReadUshort();
  1262. nextPos += buffer.position;
  1263. frame = new MovieClip.Frame();
  1264. frameRect.x = buffer.ReadInt();
  1265. frameRect.y = buffer.ReadInt();
  1266. frameRect.width = buffer.ReadInt();
  1267. frameRect.height = buffer.ReadInt();
  1268. frame.addDelay = buffer.ReadInt() / 1000f;
  1269. spriteId = buffer.ReadS();
  1270. if (spriteId != null && _sprites.TryGetValue(spriteId, out sprite))
  1271. {
  1272. frame.texture = new NTexture((NTexture)GetItemAsset(sprite.atlas), sprite.rect, sprite.rotated,
  1273. new Vector2(item.width, item.height), frameRect.position);
  1274. }
  1275. item.frames[i] = frame;
  1276. buffer.position = nextPos;
  1277. }
  1278. }
  1279. void LoadFont(PackageItem item)
  1280. {
  1281. BitmapFont font = new BitmapFont();
  1282. font.name = URL_PREFIX + this.id + item.id;
  1283. item.bitmapFont = font;
  1284. ByteBuffer buffer = item.rawData;
  1285. buffer.Seek(0, 0);
  1286. bool ttf = buffer.ReadBool();
  1287. font.canTint = buffer.ReadBool();
  1288. font.resizable = buffer.ReadBool();
  1289. font.hasChannel = buffer.ReadBool();
  1290. int fontSize = buffer.ReadInt();
  1291. int xadvance = buffer.ReadInt();
  1292. int lineHeight = buffer.ReadInt();
  1293. float texScaleX = 1;
  1294. float texScaleY = 1;
  1295. int bgX;
  1296. int bgY;
  1297. int bgWidth;
  1298. int bgHeight;
  1299. NTexture mainTexture = null;
  1300. AtlasSprite mainSprite = null;
  1301. if (ttf && _sprites.TryGetValue(item.id, out mainSprite))
  1302. {
  1303. mainTexture = (NTexture)GetItemAsset(mainSprite.atlas);
  1304. texScaleX = mainTexture.root.uvRect.width / mainTexture.width;
  1305. texScaleY = mainTexture.root.uvRect.height / mainTexture.height;
  1306. }
  1307. buffer.Seek(0, 1);
  1308. BitmapFont.BMGlyph bg;
  1309. int cnt = buffer.ReadInt();
  1310. for (int i = 0; i < cnt; i++)
  1311. {
  1312. int nextPos = buffer.ReadUshort();
  1313. nextPos += buffer.position;
  1314. bg = new BitmapFont.BMGlyph();
  1315. char ch = buffer.ReadChar();
  1316. font.AddChar(ch, bg);
  1317. string img = buffer.ReadS();
  1318. int bx = buffer.ReadInt();
  1319. int by = buffer.ReadInt();
  1320. bgX = buffer.ReadInt();
  1321. bgY = buffer.ReadInt();
  1322. bgWidth = buffer.ReadInt();
  1323. bgHeight = buffer.ReadInt();
  1324. bg.advance = buffer.ReadInt();
  1325. bg.channel = buffer.ReadByte();
  1326. //The texture channel where the character image is found (1 = blue, 2 = green, 4 = red, 8 = alpha, 15-all).
  1327. if (bg.channel == 1)
  1328. bg.channel = 2;
  1329. else if (bg.channel == 2)
  1330. bg.channel = 1;
  1331. else if (bg.channel == 4)
  1332. bg.channel = 0;
  1333. else if (bg.channel == 8)
  1334. bg.channel = 3;
  1335. if (ttf)
  1336. {
  1337. if (mainSprite.rotated)
  1338. {
  1339. bg.uv[0] = new Vector2((float)(by + bgHeight + mainSprite.rect.x) * texScaleX,
  1340. 1 - (float)(mainSprite.rect.yMax - bx) * texScaleY);
  1341. bg.uv[1] = new Vector2(bg.uv[0].x - (float)bgHeight * texScaleX, bg.uv[0].y);
  1342. bg.uv[2] = new Vector2(bg.uv[1].x, bg.uv[0].y + (float)bgWidth * texScaleY);
  1343. bg.uv[3] = new Vector2(bg.uv[0].x, bg.uv[2].y);
  1344. }
  1345. else
  1346. {
  1347. bg.uv[0] = new Vector2((float)(bx + mainSprite.rect.x) * texScaleX,
  1348. 1 - (float)(by + bgHeight + mainSprite.rect.y) * texScaleY);
  1349. bg.uv[1] = new Vector2(bg.uv[0].x, bg.uv[0].y + (float)bgHeight * texScaleY);
  1350. bg.uv[2] = new Vector2(bg.uv[0].x + (float)bgWidth * texScaleX, bg.uv[1].y);
  1351. bg.uv[3] = new Vector2(bg.uv[2].x, bg.uv[0].y);
  1352. }
  1353. bg.lineHeight = lineHeight;
  1354. bg.x = bgX;
  1355. bg.y = bgY;
  1356. bg.width = bgWidth;
  1357. bg.height = bgHeight;
  1358. }
  1359. else
  1360. {
  1361. PackageItem charImg;
  1362. if (_itemsById.TryGetValue(img, out charImg))
  1363. {
  1364. charImg = charImg.getBranch();
  1365. bgWidth = charImg.width;
  1366. bgHeight = charImg.height;
  1367. charImg = charImg.getHighResolution();
  1368. GetItemAsset(charImg);
  1369. charImg.texture.GetUV(bg.uv);
  1370. texScaleX = (float)bgWidth / charImg.width;
  1371. texScaleY = (float)bgHeight / charImg.height;
  1372. bg.x = bgX + charImg.texture.offset.x * texScaleX;
  1373. bg.y = bgY + charImg.texture.offset.y * texScaleY;
  1374. bg.width = charImg.texture.width * texScaleX;
  1375. bg.height = charImg.texture.height * texScaleY;
  1376. if (mainTexture == null)
  1377. mainTexture = charImg.texture.root;
  1378. }
  1379. if (fontSize == 0)
  1380. fontSize = bgHeight;
  1381. if (bg.advance == 0)
  1382. {
  1383. if (xadvance == 0)
  1384. bg.advance = bgX + bgWidth;
  1385. else
  1386. bg.advance = xadvance;
  1387. }
  1388. bg.lineHeight = bgY < 0 ? bgHeight : (bgY + bgHeight);
  1389. if (bg.lineHeight < fontSize)
  1390. bg.lineHeight = fontSize;
  1391. }
  1392. buffer.position = nextPos;
  1393. }
  1394. font.size = fontSize;
  1395. font.mainTexture = mainTexture;
  1396. if (!font.hasChannel)
  1397. font.shader = ShaderConfig.imageShader;
  1398. }
  1399. void LoadSpine(PackageItem item)
  1400. {
  1401. #if FAIRYGUI_SPINE
  1402. string ext = Path.GetExtension(item.file);
  1403. string fileName = item.file.Substring(0, item.file.Length - ext.Length);
  1404. int index = fileName.LastIndexOf(".skel");
  1405. if (index > 0)
  1406. fileName = fileName.Substring(0, index);
  1407. Spine.Unity.SkeletonDataAsset asset;
  1408. if (_resBundle != null)
  1409. asset = _resBundle.LoadAsset<Spine.Unity.SkeletonDataAsset>(fileName + "_SkeletonData");
  1410. else
  1411. {
  1412. DestroyMethod dm;
  1413. asset = (Spine.Unity.SkeletonDataAsset)_loadFunc(fileName + "_SkeletonData", ".asset", typeof(Spine.Unity.SkeletonDataAsset), out dm);
  1414. }
  1415. if (asset == null)
  1416. Debug.LogWarning("FairyGUI: Failed to load " + fileName);
  1417. item.skeletonAsset = asset;
  1418. #else
  1419. Debug.LogWarning("To enable Spine support, add script define symbol: FAIRYGUI_SPINE");
  1420. #endif
  1421. }
  1422. void LoadDragonBones(PackageItem item)
  1423. {
  1424. #if FAIRYGUI_DRAGONBONES
  1425. string ext = Path.GetExtension(item.file);
  1426. string fileName = item.file.Substring(0, item.file.Length - ext.Length);
  1427. int index = fileName.LastIndexOf("_ske");
  1428. if (index > 0)
  1429. fileName = fileName.Substring(0, index);
  1430. index = fileName.LastIndexOf(".dbbin");
  1431. if (index > 0)
  1432. fileName = fileName.Substring(0, index);
  1433. DragonBones.UnityDragonBonesData asset;
  1434. if (_resBundle != null)
  1435. asset = _resBundle.LoadAsset<DragonBones.UnityDragonBonesData>(fileName + "_Data");
  1436. else
  1437. {
  1438. DestroyMethod dm;
  1439. asset = (DragonBones.UnityDragonBonesData)_loadFunc(fileName + "_Data", ".asset", typeof(DragonBones.UnityDragonBonesData), out dm);
  1440. }
  1441. if (asset != null)
  1442. {
  1443. foreach (var atlas in asset.textureAtlas)
  1444. {
  1445. if (atlas.material == null)
  1446. {
  1447. atlas.material = new Material(ShaderConfig.GetShader(ShaderConfig.imageShader));
  1448. atlas.material.mainTexture = atlas.texture;
  1449. }
  1450. }
  1451. item.skeletonAsset = DragonBones.UnityFactory.factory.LoadData(asset);
  1452. }
  1453. else
  1454. Debug.LogWarning("FairyGUI: Failed to load " + fileName);
  1455. #else
  1456. Debug.LogWarning("To enable DragonBones support, add script define symbol: FAIRYGUI_DRAGONBONES");
  1457. #endif
  1458. }
  1459. }
  1460. }