MyImage.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using Fort23.Core;
  7. using Fort23.Mono;
  8. using Fort23.UTool;
  9. #if UNITY_EDITOR
  10. using System.IO;
  11. using UnityEditor;
  12. #endif
  13. using UnityEngine.Experimental.Rendering;
  14. using UnityEngine.Serialization;
  15. using UnityEngine.U2D;
  16. using UnityEngine.UI.PackgTool;
  17. namespace UnityEngine.UI
  18. {
  19. /// <summary>
  20. /// Image is a textured element in the UI hierarchy.
  21. /// </summary>
  22. [RequireComponent(typeof(CanvasRenderer))]
  23. [AddComponentMenu("GameObject/UI/MyImage", 12)]
  24. /// <summary>
  25. /// Displays a Sprite inside the UI System.
  26. /// </summary>
  27. public class MyImage : Image
  28. {
  29. public string icon_name
  30. {
  31. get { return _icon_name; }
  32. set
  33. {
  34. _icon_name = value;
  35. ReashUI();
  36. }
  37. }
  38. #if UNITY_EDITOR
  39. [MenuItem("GameObject/UI/图集UI", false, 1)]
  40. static public void AddImage(MenuCommand menuCommand)
  41. {
  42. GameObject parent = menuCommand.context as GameObject;
  43. if (parent == null)
  44. {
  45. return;
  46. }
  47. GameObject go = new GameObject("myImage");
  48. go.AddComponent<MyImage>();
  49. go.transform.SetParent(parent.transform);
  50. Selection.activeGameObject = go;
  51. }
  52. #endif
  53. // private Sprite _packSprite;
  54. //
  55. // public Sprite GetPackSprite
  56. // {
  57. // get { return _packSprite; }
  58. // }
  59. [SerializeField] private string _icon_name;
  60. [SerializeField] public bool isNotLoadDeftIcon;
  61. [SerializeField] public SpriteAtlas CurrSpriteAtlas;
  62. #if UNITY_EDITOR
  63. [SerializeField] public PackInfo packInfo;
  64. #endif
  65. private UILoadSpriteHand _uiLoadSpriteHand;
  66. public float imageH;
  67. public System.Action onSpriteAlter;
  68. protected override void Awake()
  69. {
  70. if (Application.isPlaying && isNotLoadDeftIcon)
  71. {
  72. return;
  73. }
  74. if (!string.IsNullOrEmpty(_icon_name))
  75. {
  76. icon_name = _icon_name;
  77. }
  78. }
  79. protected override void OnDestroy()
  80. {
  81. if (_uiLoadSpriteHand != null)
  82. {
  83. _uiLoadSpriteHand.ReleaseUI();
  84. _uiLoadSpriteHand = null;
  85. }
  86. base.OnDestroy();
  87. }
  88. public void ReashUI()
  89. {
  90. if (CurrSpriteAtlas != null && !string.IsNullOrEmpty(_icon_name))
  91. {
  92. Sprite loadSprite = CurrSpriteAtlas.GetSprite(_icon_name);
  93. if (loadSprite == null)
  94. {
  95. if (Application.isPlaying)
  96. {
  97. SpriteAtlas spriteAtlas = UGUIPackManager.Instance.GetSpriteAtlas(_icon_name);
  98. if (spriteAtlas != null)
  99. {
  100. loadSprite = spriteAtlas.GetSprite(_icon_name);
  101. }
  102. if (loadSprite == null)
  103. {
  104. enabled = false;
  105. UGUIIamgeTool.Load(_icon_name, delegate(UILoadSpriteHand sprite1)
  106. {
  107. enabled = true;
  108. if (Application.isPlaying)
  109. {
  110. if (_uiLoadSpriteHand != null)
  111. {
  112. _uiLoadSpriteHand.ReleaseUI();
  113. }
  114. }
  115. _uiLoadSpriteHand = sprite1;
  116. if (sprite1 == null)
  117. {
  118. SetSprite(null);
  119. }
  120. else
  121. {
  122. SetSprite(sprite1.GetSprite());
  123. }
  124. });
  125. }
  126. else
  127. {
  128. SetSprite(loadSprite);
  129. }
  130. }
  131. }
  132. else
  133. {
  134. SetSprite(loadSprite);
  135. }
  136. }
  137. else if (!string.IsNullOrEmpty(_icon_name) && sprite == null)
  138. {
  139. if (Application.isPlaying)
  140. {
  141. enabled = false;
  142. UGUIIamgeTool.Load(_icon_name, delegate(UILoadSpriteHand sprite1)
  143. {
  144. enabled = true;
  145. if (_uiLoadSpriteHand != null)
  146. {
  147. _uiLoadSpriteHand.ReleaseUI();
  148. }
  149. _uiLoadSpriteHand = sprite1;
  150. if (sprite1 == null)
  151. {
  152. SetSprite(null);
  153. }
  154. else
  155. {
  156. SetSprite(sprite1.GetSprite());
  157. }
  158. });
  159. }
  160. }
  161. else if (!string.IsNullOrEmpty(_icon_name))
  162. {
  163. if (Application.isPlaying)
  164. {
  165. enabled = false;
  166. UGUIIamgeTool.Load(_icon_name, delegate(UILoadSpriteHand sprite1)
  167. {
  168. enabled = true;
  169. if (sprite1 != null)
  170. {
  171. Sprite sp = sprite1.GetSprite();
  172. if (sp != null)
  173. {
  174. if (!sp.name.Equals(_icon_name))
  175. {
  176. sprite1.ReleaseUI();
  177. return;
  178. }
  179. }
  180. }
  181. if (_uiLoadSpriteHand != null)
  182. {
  183. _uiLoadSpriteHand.ReleaseUI();
  184. }
  185. _uiLoadSpriteHand = sprite1;
  186. if (sprite1 == null)
  187. {
  188. SetSprite(null);
  189. }
  190. else
  191. {
  192. SetSprite(sprite1.GetSprite());
  193. }
  194. });
  195. }
  196. }
  197. }
  198. private void SetSprite(Sprite sprite)
  199. {
  200. this.sprite = sprite;
  201. if (sprite != null)
  202. {
  203. onSpriteAlter?.Invoke();
  204. }
  205. }
  206. /// <summary>
  207. /// 是否置灰
  208. /// </summary>
  209. public bool IsGray
  210. {
  211. get { return _isGray; }
  212. set
  213. {
  214. if (!_isGray.Equals(value))
  215. {
  216. _isGray = value;
  217. if (_isGray)
  218. {
  219. base.material = UIManager.Instance.uiGray;
  220. }
  221. else
  222. {
  223. if (base.material != null)
  224. {
  225. base.material = null;
  226. }
  227. base.material = defaultMaterial;
  228. }
  229. }
  230. }
  231. }
  232. private bool _isGray;
  233. public override void GraphicUpdateComplete()
  234. {
  235. SetPack();
  236. }
  237. #if UNITY_EDITOR
  238. [ContextMenu("重新设置图片")]
  239. public void SetPackEditor()
  240. {
  241. if (packInfo != null && CurrSpriteAtlas != null)
  242. {
  243. string assetName = icon_name;
  244. if (string.IsNullOrEmpty(icon_name) && sprite != null)
  245. {
  246. assetName = sprite.name;
  247. }
  248. var loadSprite = CurrSpriteAtlas.GetSprite(assetName);
  249. bool isoK = loadSprite != null;
  250. if (isoK)
  251. {
  252. SetSprite(loadSprite);
  253. }
  254. }
  255. }
  256. [ContextMenu("自动匹配图集")]
  257. public void CompareSpritesInAtlas()
  258. {
  259. if (sprite == null)
  260. return;
  261. string targetPath = AssetDatabase.GetAssetPath(sprite);
  262. if (string.IsNullOrEmpty(targetPath))
  263. {
  264. LogTool.Error("无法获取目标 Sprite 的源文件路径");
  265. return;
  266. }
  267. string relativePath = targetPath.Substring("Assets/".Length);
  268. string absolutePath = Path.Combine(Application.dataPath, relativePath);
  269. string targetMD5 = MD5Helper.FileMD5(absolutePath);
  270. foreach (var allPackgInfo in UGUICacheInfo.uguiPackDB.allPackgInfos)
  271. {
  272. string path = Application.dataPath + allPackgInfo.PackageJsonPath;
  273. string jsonPath = File.ReadAllText(path);
  274. TextrueJson textrueJson = JsonUtility.FromJson<TextrueJson>(jsonPath);
  275. for (int i = 0; i < textrueJson.newTextureJson.Count; i++)
  276. {
  277. string texturePath = "Art/UIAssets" + textrueJson.newTextureJson[i].filePath;
  278. texturePath = Path.Combine(Application.dataPath, texturePath);
  279. string spriteMD5 = MD5Helper.FileMD5(texturePath);
  280. if (spriteMD5 == targetMD5)
  281. {
  282. LogTool.Log(
  283. $"找到匹配的 Sprite: {textrueJson.newTextureJson[i].textrueName},所在图集: {allPackgInfo.packName},源文件: {targetPath}");
  284. packInfo = allPackgInfo;
  285. CurrSpriteAtlas = UGUICacheInfo.GetSpriteAtlas(allPackgInfo.packName);
  286. icon_name = textrueJson.newTextureJson[i].textrueName;
  287. ReashUI();
  288. return;
  289. }
  290. }
  291. }
  292. LogTool.Log("未找到任何匹配的 Sprite");
  293. }
  294. #endif
  295. private void SetPack()
  296. {
  297. #if UNITY_EDITOR
  298. if (!Application.isPlaying)
  299. {
  300. bool isoK = false;
  301. if (packInfo != null && CurrSpriteAtlas != null)
  302. {
  303. string assetName = icon_name;
  304. if (string.IsNullOrEmpty(icon_name) && sprite != null)
  305. {
  306. assetName = sprite.name;
  307. }
  308. isoK = CurrSpriteAtlas.GetSprite(assetName) != null;
  309. if (!isoK) //没在在图集里面找到图片了,需要去其他地方查找(删除图集)
  310. {
  311. SpriteAtlas newAtlas = UGUICacheInfo.GetSpriteAtlas(assetName);
  312. if (newAtlas != null)
  313. {
  314. CurrSpriteAtlas = newAtlas;
  315. icon_name = assetName;
  316. }
  317. else
  318. {
  319. sprite = null;
  320. }
  321. }
  322. else if (string.IsNullOrEmpty(icon_name) || sprite == null)
  323. {
  324. icon_name = assetName;
  325. }
  326. }
  327. else if (CurrSpriteAtlas == null && packInfo != null && !string.IsNullOrEmpty(packInfo.packgJsonPath) &&
  328. sprite != null) //没有图集 但是由功能管理器添加的UI (添加图集)
  329. {
  330. string name = sprite.name;
  331. SpriteAtlas newAtlas = UGUICacheInfo.GetSpriteAtlas(name);
  332. if (newAtlas != null)
  333. {
  334. CurrSpriteAtlas = newAtlas;
  335. icon_name = _icon_name;
  336. }
  337. }
  338. }
  339. #endif
  340. }
  341. public enum GradientDirection
  342. {
  343. Vertical,
  344. Horizontal
  345. }
  346. [SerializeField] private bool useGradient = false;
  347. [SerializeField] private Color topOrLeftColor = Color.white;
  348. [SerializeField] private Color bottomOrRightColor = Color.black;
  349. [SerializeField] private GradientDirection direction = GradientDirection.Vertical;
  350. public bool UseGradient
  351. {
  352. get => useGradient;
  353. set
  354. {
  355. useGradient = value;
  356. SetVerticesDirty();
  357. }
  358. }
  359. public Color TopOrLeftColor
  360. {
  361. get => topOrLeftColor;
  362. set
  363. {
  364. topOrLeftColor = value;
  365. SetVerticesDirty();
  366. }
  367. }
  368. public Color BottomOrRightColor
  369. {
  370. get => bottomOrRightColor;
  371. set
  372. {
  373. bottomOrRightColor = value;
  374. SetVerticesDirty();
  375. }
  376. }
  377. public GradientDirection Direction
  378. {
  379. get => direction;
  380. set
  381. {
  382. direction = value;
  383. SetVerticesDirty();
  384. }
  385. }
  386. protected override void OnPopulateMesh(VertexHelper vh)
  387. {
  388. base.OnPopulateMesh(vh);
  389. List<UIVertex> verts = new List<UIVertex>();
  390. vh.GetUIVertexStream(verts);
  391. if (imageH <= 0)
  392. {
  393. float minY = 11111;
  394. float maxY = -111111;
  395. for (int i = 0; i < verts.Count; i++)
  396. {
  397. UIVertex vertex = verts[i];
  398. float y = vertex.position.y;
  399. if (y < minY)
  400. {
  401. minY = y;
  402. }
  403. if (y > maxY)
  404. {
  405. maxY = y;
  406. }
  407. }
  408. imageH = maxY - minY;
  409. }
  410. if (!useGradient || vh.currentVertCount == 0)
  411. return;
  412. for (int i = 0; i < verts.Count; i += 6)
  413. {
  414. ApplyGradientToQuad(verts, i);
  415. }
  416. vh.Clear();
  417. vh.AddUIVertexTriangleStream(verts);
  418. }
  419. private void ApplyGradientToQuad(List<UIVertex> verts, int startIndex)
  420. {
  421. if (startIndex + 5 >= verts.Count)
  422. return;
  423. float top = verts[startIndex].position.y;
  424. float bottom = verts[startIndex].position.y;
  425. float left = verts[startIndex].position.x;
  426. float right = verts[startIndex].position.x;
  427. for (int i = 1; i < 6; i++)
  428. {
  429. var pos = verts[startIndex + i].position;
  430. top = Mathf.Max(top, pos.y);
  431. bottom = Mathf.Min(bottom, pos.y);
  432. left = Mathf.Min(left, pos.x);
  433. right = Mathf.Max(right, pos.x);
  434. }
  435. for (int i = 0; i < 6; i++)
  436. {
  437. var vert = verts[startIndex + i];
  438. var pos = vert.position;
  439. float t = direction == GradientDirection.Vertical
  440. ? Mathf.InverseLerp(bottom, top, pos.y)
  441. : Mathf.InverseLerp(left, right, pos.x);
  442. Color gradientColor = Color.Lerp(bottomOrRightColor, topOrLeftColor, t);
  443. gradientColor.r *= color.r;
  444. gradientColor.g *= color.g;
  445. gradientColor.b *= color.b;
  446. gradientColor.a *= color.a;
  447. vert.color = gradientColor;
  448. verts[startIndex + i] = vert;
  449. }
  450. }
  451. }
  452. }