Unity 框架

GlobalTool.cs 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Reflection;
  6. using System.Runtime.InteropServices;
  7. using System.Runtime.Serialization.Formatters.Binary;
  8. using System.Text;
  9. using UnityEngine;
  10. using UnityEngine.EventSystems;
  11. namespace TFramework
  12. {
  13. public static class GlobalTool
  14. {
  15. /// <summary>
  16. /// 当前鼠标是否停留在UGUI控件上
  17. /// </summary>
  18. /// <returns>是否</returns>
  19. public static bool IsPointerOverUGUI()
  20. {
  21. if (EventSystem.current)
  22. {
  23. #if UNITY_ANDROID && !UNITY_EDITOR
  24. if (Input.touchCount > 0)
  25. {
  26. return EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId);
  27. }
  28. else
  29. {
  30. return false;
  31. }
  32. #else
  33. return EventSystem.current.IsPointerOverGameObject();
  34. #endif
  35. }
  36. else
  37. {
  38. return false;
  39. }
  40. }
  41. #region 反射
  42. private static HashSet<string> RunTimeAssemblies = new HashSet<string>()
  43. {
  44. "Assembly-CSharp","UnityEngine", "UnityEngine.CoreModule", "UnityEngine.UI", "UnityEngine.PhysicsModule","UnityEngine.EventSystems","TMPro",
  45. "UnityEngine.Events","TFramework.RunTime","KeMingVR"
  46. };
  47. /// <summary>
  48. /// 从当前程序域实例化对象
  49. /// </summary>
  50. /// <typeparam name="T"></typeparam>
  51. /// <param name="fullName"></param>
  52. /// <returns></returns>
  53. public static T CretaInstanceToCurrentDomain<T>(string fullName)where T:class
  54. {
  55. foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
  56. foreach (var type in assembly.GetTypes())
  57. if (typeof(T).IsAssignableFrom(type))//判断type是否是其派生类
  58. if (type.IsClass && type.FullName == fullName)
  59. return assembly.CreateInstance(type.FullName) as T;
  60. return null;
  61. }
  62. /// <summary>
  63. /// 从当前程序域获取指定名Type
  64. /// </summary>
  65. /// <param name="typeFullName"></param>
  66. /// <returns></returns>
  67. public static Type GetTypeToCurrentDomain(string typeFullName)
  68. {
  69. Type type = null;
  70. foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
  71. {
  72. type = assembly.GetType(typeFullName)?? assembly.GetTypes().Find(p=>p.Name==typeFullName);
  73. if (type != null)
  74. return type;
  75. }
  76. return type;
  77. }
  78. /// <summary>
  79. /// 获取运行时当前程序域所有类型
  80. /// </summary>
  81. /// <returns></returns>
  82. public static List<Type> GetTypesInRunTimeAssemblies()
  83. {
  84. List<Type> types = new List<Type>();
  85. Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies();
  86. for (int i = 0; i < assemblys.Length; i++)
  87. {
  88. if (RunTimeAssemblies.Contains(assemblys[i].GetName().Name))
  89. {
  90. types.AddRange(assemblys[i].GetTypes());
  91. }
  92. }
  93. return types;
  94. }
  95. /// <summary>
  96. /// 获取运行时当前程序域所有满足条件类型
  97. /// </summary>
  98. /// <param name="filter">筛选条件</param>
  99. /// <returns></returns>
  100. public static List<Type> GetTypesInRunTimeAssemblies(TFunc<Type, bool> filter)
  101. {
  102. List<Type> types = new List<Type>();
  103. Assembly[] assemblys = AppDomain.CurrentDomain.GetAssemblies();
  104. for (int i = 0; i < assemblys.Length; i++)
  105. {
  106. if (RunTimeAssemblies.Contains(assemblys[i].GetName().Name))
  107. {
  108. Type[] ts = assemblys[i].GetTypes();
  109. foreach (var t in ts)
  110. {
  111. if (filter(t))
  112. {
  113. types.Add(t);
  114. }
  115. }
  116. }
  117. }
  118. return types;
  119. }
  120. #endregion
  121. #region byte[]转换
  122. /// <summary>
  123. /// 将对象转换为byte数组
  124. /// </summary>
  125. /// <param name="obj">被转换对象</param>
  126. /// <returns>转换后byte数组</returns>
  127. public static byte[] Object2Bytes(object obj)
  128. {
  129. byte[] buff = obj != null ? new byte[Marshal.SizeOf(obj)] : new byte[0];
  130. if(obj!=null)
  131. {
  132. IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buff, 0);
  133. Marshal.StructureToPtr(obj, ptr, true);
  134. }
  135. return buff;
  136. }
  137. /// <summary>
  138. /// 将byte数组转换成对象
  139. /// </summary>
  140. /// <param name="buff">被转换byte数组</param>
  141. /// <param name="typ">转换成的类名</param>
  142. /// <returns>转换完成后的对象</returns>
  143. public static object Bytes2Object(byte[] buff, Type type)
  144. {
  145. IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buff, 0);
  146. return Marshal.PtrToStructure(ptr, type);
  147. }
  148. public static Texture2D Bytes2Texture2D(byte[] buff)
  149. {
  150. Texture2D texture2D = new Texture2D(512, 512);
  151. texture2D.LoadImage(buff);
  152. return texture2D;
  153. }
  154. /// <summary>
  155. /// 将字节数转换为最合适的存储单位表示
  156. /// </summary>
  157. /// <param name="bytes">要转换的字节数</param>
  158. /// <returns>带有单位的字符串表示,如"1KB"、"2.5MB"等</returns>
  159. public static string CalculateStorageSize(long bytes)
  160. {
  161. // 定义单位换算系数
  162. const long kb = 1024;
  163. const long mb = kb * 1024;
  164. const long gb = mb * 1024;
  165. // 根据数值大小选择合适的单位
  166. if (bytes >= gb)
  167. {
  168. double value = (double)bytes / gb;
  169. // 如果是整数则不显示小数
  170. return value % 1 == 0 ? $"{(long)value}G" : $"{value:F1}G";
  171. }
  172. else if (bytes >= mb)
  173. {
  174. double value = (double)bytes / mb;
  175. return value % 1 == 0 ? $"{(long)value}M" : $"{value:F1}M";
  176. }
  177. else if (bytes >= kb)
  178. {
  179. double value = (double)bytes / kb;
  180. return value % 1 == 0 ? $"{(long)value}K" : $"{value:F1}K";
  181. }
  182. else
  183. {
  184. // 小于1KB的情况直接返回字节数
  185. return $"{bytes}B";
  186. }
  187. }
  188. #endregion
  189. #region 截屏
  190. /// <summary>
  191. /// 截取全屏
  192. /// </summary>
  193. /// <param name="superSize">分辨率的增加倍数</param>
  194. /// <param name="onCaptureOverEvent">截取完成事件</param>
  195. public static void CaptureScreenshot(int superSize,TAction<Texture2D> onCaptureOverEvent)
  196. {
  197. Main.Instance.StartCoroutine(RecordFrame(superSize, onCaptureOverEvent));
  198. }
  199. private static IEnumerator RecordFrame(int superSize, TAction<Texture2D> onCaptureOverEvent)
  200. {
  201. yield return YieldWaitTool.YieldWaitForEndOfFrame();
  202. onCaptureOverEvent?.Invoke(ScreenCapture.CaptureScreenshotAsTexture(superSize));
  203. }
  204. /// <summary>
  205. /// 截取指定相机拍摄区域
  206. /// </summary>
  207. /// <param name="camera">截图相机</param>
  208. /// <param name="rect">截取区域</param>
  209. /// <returns></returns>
  210. public static Texture2D CameraCapture(Camera camera,Rect rect)
  211. {
  212. RenderTexture render = new RenderTexture((int)rect.width, (int)rect.height, -1);
  213. camera.targetTexture = render;
  214. camera.Render();
  215. RenderTexture currentRT = RenderTexture.active;
  216. RenderTexture.active = render;
  217. Texture2D tex = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.ARGB32, false);
  218. tex.ReadPixels(rect, 0, 0);
  219. tex.Apply();
  220. camera.targetTexture = null;
  221. RenderTexture.active = currentRT; ;
  222. GameObject.Destroy(render);
  223. return tex;
  224. }
  225. /// <summary>
  226. /// 截取屏幕指定区域
  227. /// </summary>
  228. /// <param name="rect">截取区域</param>
  229. /// <param name="onCaptureOverEvent">截取完毕事件</param>
  230. public static void ScreenCaptureRect(Rect rect, TAction<Texture2D> onCaptureOverEvent)
  231. {
  232. Main.Instance.StartCoroutine(RecordFrame(rect, onCaptureOverEvent));
  233. }
  234. private static IEnumerator RecordFrame(Rect rect, TAction<Texture2D> onCaptureOverEvent)
  235. {
  236. yield return YieldWaitTool.YieldWaitForEndOfFrame();
  237. Texture2D tex = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.ARGB32, false);
  238. tex.ReadPixels(rect, 0, 0);
  239. tex.Apply();
  240. onCaptureOverEvent?.Invoke(tex);
  241. }
  242. #endregion
  243. #region 贴图转换
  244. public static Sprite Texture2DToSprite(Texture2D texture2D) =>
  245. Sprite.Create(texture2D, new Rect(0, 0, texture2D.width, texture2D.height), Vector2.zero);
  246. public static Sprite TextureToSprite(Texture texture)
  247. {
  248. Texture2D texture2D = TextureToTexture2D(texture);
  249. return Texture2DToSprite(texture2D);
  250. }
  251. public static Texture2D TextureToTexture2D(Texture texture)
  252. {
  253. RenderTexture renderTexture = RenderTexture.GetTemporary(texture.width, texture.height, 32);
  254. Graphics.Blit(texture, renderTexture);
  255. Texture2D texture2D = RenderTextureToTexture2D(renderTexture);
  256. RenderTexture.ReleaseTemporary(renderTexture);
  257. return texture2D;
  258. }
  259. public static Texture2D RenderTextureToTexture2D(RenderTexture renderTexture)
  260. {
  261. RenderTexture currentRT = RenderTexture.active;
  262. RenderTexture.active = renderTexture;
  263. Rect rect = new Rect(0, 0, renderTexture.width, renderTexture.height);
  264. Texture2D texture2D = new Texture2D(renderTexture.width, renderTexture.height);
  265. texture2D.ReadPixels(rect, 0, 0);
  266. texture2D.Apply();
  267. RenderTexture.active = currentRT;
  268. return texture2D;
  269. }
  270. #endregion
  271. #region GameObject
  272. #endregion
  273. }
  274. }