Unity 框架

FunctionExtend.cs 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. using Newtonsoft.Json;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Reflection;
  7. using System.Text;
  8. using System.Text.RegularExpressions;
  9. using UnityEngine;
  10. using UnityEngine.Events;
  11. using UnityEngine.EventSystems;
  12. namespace TFramework
  13. {
  14. /// <summary>
  15. /// 函数扩展类
  16. /// </summary>
  17. public static class FunctionExtend
  18. {
  19. #region 对象
  20. /// <summary>
  21. /// 设置游戏对象激活状态
  22. /// </summary>
  23. /// <typeparam name="T"></typeparam>
  24. /// <param name="game"></param>
  25. /// <param name="value"></param>
  26. public static GameObject SetActive<T>(this T game, bool value) where T : Component
  27. {
  28. game.gameObject.SetActive(value);
  29. return game.gameObject;
  30. }
  31. /// <summary>
  32. /// 给物体添加交互事件 点击 拖拽...
  33. /// </summary>
  34. /// <param name="obj">物体对象</param>
  35. /// <param name="ev">交互类型</param>
  36. /// <param name="action">事件</param>
  37. public static void AddTriggerListener<T>(this T obj, EventTriggerType ev, UnityAction<BaseEventData> action) where T : Component
  38. {
  39. EventTrigger trigger = obj.GetComponent<EventTrigger>() ?? obj.gameObject.AddComponent<EventTrigger>();
  40. trigger.triggers = trigger.triggers ?? new List<EventTrigger.Entry>();
  41. foreach (var item in trigger.triggers)
  42. {
  43. if (item.eventID == ev)
  44. {
  45. item.callback.AddListener(action);
  46. return;
  47. }
  48. }
  49. EventTrigger.Entry entry = new EventTrigger.Entry();
  50. entry.eventID = ev;
  51. entry.callback.AddListener(action);
  52. trigger.triggers.Add(entry);
  53. }
  54. /// <summary>
  55. /// 移除物体交互事件
  56. /// </summary>
  57. /// <param name="obj">物体对象</param>
  58. /// <param name="ev">交互类型</param>
  59. /// <param name="action">事件</param>
  60. public static void RemoveTriggerListener<T>(this T obj, EventTriggerType ev, UnityAction<BaseEventData> action) where T : Component
  61. {
  62. EventTrigger trigger = obj.GetComponent<EventTrigger>();
  63. if (trigger == null)
  64. return;
  65. if (trigger.triggers == null || trigger.triggers.Count == 0)
  66. return;
  67. foreach (var item in trigger.triggers)
  68. {
  69. if (item.eventID == ev)
  70. item.callback.RemoveListener(action);
  71. }
  72. }
  73. /// <summary>
  74. /// 克隆
  75. /// </summary>
  76. /// <typeparam name="T"></typeparam>
  77. /// <param name="clone"></param>
  78. /// <param name="parent"></param>
  79. /// <param name="isUI"></param>
  80. /// <returns></returns>
  81. public static T Clone<T>(this T clone, Transform parent=null, bool isUI = false) where T : UnityEngine.Object
  82. {
  83. UnityEngine.Object obj;
  84. if (parent != null)
  85. obj = GameObject.Instantiate(clone, parent);
  86. else
  87. obj = GameObject.Instantiate(clone);
  88. if (isUI)
  89. {
  90. UIBehaviour[] uis = (obj as Component).GetComponentsInChildren<UIBehaviour>(true);
  91. for (int i = 0; i < uis.Length; i++)
  92. uis[i].ResetID();
  93. }
  94. return obj as T;
  95. }
  96. /// <summary>
  97. /// 根据名字查找对应类型子游戏对象
  98. /// </summary>
  99. /// <typeparam name="T"></typeparam>
  100. /// <param name="game"></param>
  101. /// <param name="n"></param>
  102. /// <returns></returns>
  103. public static T GetChildComponent<T>(this GameObject game, string n) where T : UnityEngine.Object
  104. {
  105. Transform t = game.transform.Find(n);
  106. return t != null ? t.GetComponent<T>() : null;
  107. }
  108. /// <summary>
  109. /// 根据名字查找对应类型子游戏对象
  110. /// </summary>
  111. /// <typeparam name="T"></typeparam>
  112. /// <param name="game"></param>
  113. /// <param name="n"></param>
  114. /// <returns></returns>
  115. public static T GetChildComponent<T>(this Component game, string n) where T : UnityEngine.Object
  116. {
  117. Transform t = game.transform.Find(n);
  118. return t != null ? t.GetComponent<T>() : null;
  119. }
  120. /// <summary>
  121. /// 查找第一个名字含有指定字符的子物体
  122. /// </summary>
  123. /// <typeparam name="T"></typeparam>
  124. /// <param name="game"></param>
  125. /// <param name="n"></param>
  126. /// <returns></returns>
  127. public static T GetContainStrChildComponent<T>(this GameObject game, string n) where T : UnityEngine.Object
  128. {
  129. return game.GetComponentsInChildren<T>(true).First(p => p.name.Contains(n));
  130. }
  131. #endregion
  132. #region 反射
  133. /// <summary>
  134. /// 从当前类型中获取所有字段
  135. /// </summary>
  136. /// <param name="type">类型</param>
  137. /// <param name="filter">字段筛选器</param>
  138. /// <returns>所有字段集合</returns>
  139. public static List<FieldInfo> GetFields(this Type type, TFunc<FieldInfo, bool> filter)
  140. {
  141. List<FieldInfo> fields = new List<FieldInfo>();
  142. FieldInfo[] infos = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
  143. for (int i = 0; i < infos.Length; i++)
  144. {
  145. if (filter(infos[i]))
  146. {
  147. fields.Add(infos[i]);
  148. }
  149. }
  150. return fields;
  151. }
  152. /// <summary>
  153. /// 从当前类型中获取所有属性
  154. /// </summary>
  155. /// <param name="type">类型</param>
  156. /// <param name="filter">属性筛选器</param>
  157. /// <returns>所有属性集合</returns>
  158. public static List<PropertyInfo> GetProperties(this Type type, TFunc<PropertyInfo, bool> filter)
  159. {
  160. List<PropertyInfo> properties = new List<PropertyInfo>();
  161. PropertyInfo[] infos = type.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
  162. for (int i = 0; i < infos.Length; i++)
  163. {
  164. if (filter(infos[i]))
  165. {
  166. properties.Add(infos[i]);
  167. }
  168. }
  169. return properties;
  170. }
  171. /// <summary>
  172. /// 从当前类型中获取所有方法
  173. /// </summary>
  174. /// <param name="type">类型</param>
  175. /// <param name="filter">方法筛选器</param>
  176. /// <returns>所有方法集合</returns>
  177. public static List<MethodInfo> GetMethods(this Type type, TFunc<MethodInfo, bool> filter)
  178. {
  179. List<MethodInfo> methods = new List<MethodInfo>();
  180. MethodInfo[] infos = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
  181. for (int i = 0; i < infos.Length; i++)
  182. {
  183. if (filter(infos[i]))
  184. {
  185. methods.Add(infos[i]);
  186. }
  187. }
  188. return methods;
  189. }
  190. /// <summary>
  191. /// 从当前类型中获取所有成员
  192. /// </summary>
  193. /// <param name="type"></param>
  194. /// <param name="filter"></param>
  195. /// <returns></returns>
  196. public static List<MemberInfo> GetMembers(this Type type,TFunc<MemberInfo,bool> filter)
  197. {
  198. List<MemberInfo> memberInfos = new List<MemberInfo>();
  199. MemberInfo[] infos = type.GetMembers(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
  200. for (int i = 0; i < infos.Length; i++)
  201. {
  202. if (filter(infos[i]))
  203. {
  204. memberInfos.Add(infos[i]);
  205. }
  206. }
  207. return memberInfos;
  208. }
  209. #endregion
  210. #region 集合
  211. public static bool Contains<T>(this T[] array, T item) => Array.Exists(array, p => p.Equals(item));
  212. public static T Find<T>(this T[] array, Predicate<T> match) => Array.Find(array, match);
  213. /// <summary>
  214. /// 根据Key获取Value
  215. /// </summary>
  216. /// <typeparam name="Tkey"></typeparam>
  217. /// <typeparam name="Tvalue"></typeparam>
  218. /// <param name="dict">获取值的字典</param>
  219. /// <param name="key">键值</param>
  220. /// <returns></returns>
  221. public static Tvalue TryGet<Tkey, Tvalue>(this Dictionary<Tkey, Tvalue> dict, Tkey key)
  222. {
  223. Tvalue value;
  224. dict.TryGetValue(key, out value);
  225. return value;
  226. }
  227. /// <summary>
  228. /// 打乱列表顺序
  229. /// </summary>
  230. /// <typeparam name="T"></typeparam>
  231. /// <param name="list"></param>
  232. public static void OutOfOrder<T>(this List<T> list)
  233. {
  234. T t = default;
  235. for (int i = 0; i < list.Count; i++)
  236. {
  237. int index = UnityEngine.Random.Range(0, list.Count);
  238. t = list[index];
  239. list[index] = list[i];
  240. list[i] = t;
  241. }
  242. }
  243. /// <summary>
  244. /// 替换列表元素的位置
  245. /// </summary>
  246. /// <typeparam name="T">类型</typeparam>
  247. /// <param name="list">列表</param>
  248. /// <param name="index1">需替换位置元素下标</param>
  249. /// <param name="index2">需替换位置元素下标</param>
  250. public static void Swap<T>(this List<T> list, int index1, int index2)
  251. {
  252. if (index1 >= list.Count || index2 >= list.Count || index1 < 0 || index2 < 0) return;
  253. T temp1 = list[index1];
  254. list[index1] = list[index2];
  255. list[index2] = temp1;
  256. }
  257. #endregion
  258. #region 字符串
  259. public static string StrUnescape(this string str) => Regex.Unescape(str);
  260. private static string pattern = @"(\d*\.|[0-9]+)[0-9]+";
  261. /// <summary>
  262. /// 获取字符串中所有数值
  263. /// </summary>
  264. /// <param name="str"></param>
  265. /// <returns></returns>
  266. public static List<float> GetStrAllNumValue(this string str)
  267. {
  268. List<float> values = new List<float>();
  269. Regex regex = new Regex(pattern);
  270. MatchCollection matchs = regex.Matches(str);
  271. foreach (Match item in matchs)
  272. {
  273. if (float.TryParse(item.Groups[0].Value, out float v))
  274. values.Add(v);
  275. }
  276. return values;
  277. }
  278. /// <summary>
  279. /// Json字符串转object
  280. /// </summary>
  281. /// <typeparam name="T"></typeparam>
  282. /// <param name="jsonStr"></param>
  283. /// <returns></returns>
  284. public static T JsonStrToObject<T>(this string jsonStr)
  285. {
  286. return JsonConvert.DeserializeObject<T>(jsonStr);
  287. }
  288. /// <summary>
  289. /// 泛型转Json字符串
  290. /// </summary>
  291. /// <typeparam name="T"></typeparam>
  292. /// <param name="obj"></param>
  293. /// <returns></returns>
  294. public static string ObjectToJsonStr<T>(this T obj)
  295. {
  296. return Regex.Unescape(JsonConvert.SerializeObject(obj));
  297. }
  298. #endregion
  299. #region 数学
  300. /// <summary>
  301. /// 除法运算(避免Nan)
  302. /// </summary>
  303. /// <param name="dividend">被除数</param>
  304. /// <param name="divisor">除数</param>
  305. /// <returns>商</returns>
  306. public static float Divide(this float dividend, float divisor)
  307. {
  308. if (divisor == 0)
  309. return dividend;
  310. else
  311. return dividend / divisor;
  312. }
  313. #endregion
  314. public static Vector2 Clamp(this Vector2 v2, float min, float max)
  315. {
  316. Vector2 vect2 = Vector2.zero;
  317. vect2.x = Mathf.Clamp(v2.x, min, max);
  318. vect2.y = Mathf.Clamp(v2.y, min, max);
  319. return vect2;
  320. }
  321. #region 音频
  322. /// <summary>
  323. ///AudioClip转wave格式文件byte数组
  324. /// </summary>
  325. /// <param name="clip"></param>
  326. /// <returns></returns>
  327. public static byte[] ClipToBytes(this AudioClip clip)
  328. {
  329. byte[] buffer = GetRealAudio(ref clip);
  330. return GetHeaderBytes(buffer, clip).Concat(buffer).ToArray();
  331. }
  332. public static AudioClip BytesToAudioClip(this byte[] wavFileData)
  333. {
  334. int channels = BitConverter.ToInt16(wavFileData, 22);
  335. int sampleRate = BitConverter.ToInt32(wavFileData, 24);
  336. byte[] data = new byte[wavFileData.Length - 44];
  337. Array.Copy(wavFileData, 44, data, 0, wavFileData.Length - 44);
  338. float[] _clipData = BytesToFloat(data);
  339. AudioClip clip = AudioClip.Create("audioClip", _clipData.Length, channels, sampleRate, false);
  340. clip.SetData(_clipData, 0);
  341. return clip;
  342. }
  343. /// <summary>
  344. /// 获取录音头部 wave格式
  345. /// </summary>
  346. /// <param name="data"></param>
  347. /// <param name="clip"></param>
  348. /// <returns></returns>
  349. private static byte[] GetHeaderBytes(byte[] data, AudioClip clip)
  350. {
  351. byte[] buffer = new byte[44];
  352. int hz = clip.frequency;
  353. int channels = clip.channels;
  354. int samples = clip.samples;
  355. int index = 0;
  356. Byte[] riff = Encoding.UTF8.GetBytes("RIFF");
  357. for (int i = 0; i < 4; i++)
  358. {
  359. buffer[index] = riff[i];
  360. index += 1;
  361. }
  362. Byte[] chunkSize = BitConverter.GetBytes(data.Length - 8);
  363. for (int i = 0; i < 4; i++)
  364. {
  365. buffer[index] = chunkSize[i];
  366. index += 1;
  367. }
  368. Byte[] wave = Encoding.UTF8.GetBytes("WAVE");
  369. for (int i = 0; i < 4; i++)
  370. {
  371. buffer[index] = wave[i];
  372. index += 1;
  373. }
  374. Byte[] fmt = Encoding.UTF8.GetBytes("fmt ");
  375. for (int i = 0; i < 4; i++)
  376. {
  377. buffer[index] = fmt[i];
  378. index += 1;
  379. }
  380. Byte[] subChunk1 = BitConverter.GetBytes(16);
  381. for (int i = 0; i < 4; i++)
  382. {
  383. buffer[index] = subChunk1[i];
  384. index += 1;
  385. }
  386. UInt16 one = 1;
  387. Byte[] audioFormat = BitConverter.GetBytes(one);
  388. for (int i = 0; i < 2; i++)
  389. {
  390. buffer[index] = audioFormat[i];
  391. index += 1;
  392. }
  393. Byte[] numChannels = BitConverter.GetBytes(channels);
  394. for (int i = 0; i < 2; i++)
  395. {
  396. buffer[index] = numChannels[i];
  397. index += 1;
  398. }
  399. Byte[] sampleRate = BitConverter.GetBytes(hz);
  400. for (int i = 0; i < 4; i++)
  401. {
  402. buffer[index] = sampleRate[i];
  403. index += 1;
  404. }
  405. Byte[] byteRate = BitConverter.GetBytes(hz * channels * 2);
  406. for (int i = 0; i < 4; i++)
  407. {
  408. buffer[index] = byteRate[i];
  409. index += 1;
  410. }
  411. UInt16 blockAlign = (ushort)(channels * 2);
  412. byte[] blockAlignBytes = BitConverter.GetBytes(blockAlign);
  413. for (int i = 0; i < 2; i++)
  414. {
  415. buffer[index] = blockAlignBytes[i];
  416. index += 1;
  417. }
  418. UInt16 bps = 16;
  419. Byte[] bitsPerSample = BitConverter.GetBytes(bps);
  420. for (int i = 0; i < 2; i++)
  421. {
  422. buffer[index] = bitsPerSample[i];
  423. index += 1;
  424. }
  425. Byte[] datastring = System.Text.Encoding.UTF8.GetBytes("data");
  426. for (int i = 0; i < 4; i++)
  427. {
  428. buffer[index] = datastring[i];
  429. index += 1;
  430. }
  431. Byte[] subChunk2 = BitConverter.GetBytes(samples * channels * 2);
  432. for (int i = 0; i < 4; i++)
  433. {
  434. buffer[index] = subChunk2[i];
  435. index += 1;
  436. }
  437. return buffer;
  438. }
  439. /// <summary>
  440. /// 获取真正大小的录音
  441. /// </summary>
  442. /// <param name="recordedClip"></param>
  443. /// <returns></returns>
  444. private static byte[] GetRealAudio(ref AudioClip recordedClip)
  445. {
  446. int position = Microphone.GetPosition(null);
  447. if (position <= 0 || position > recordedClip.samples)
  448. {
  449. position = recordedClip.samples;
  450. }
  451. float[] soundata = new float[position * recordedClip.channels];
  452. recordedClip.GetData(soundata, 0);
  453. recordedClip = AudioClip.Create(recordedClip.name, position,
  454. recordedClip.channels, recordedClip.frequency, false);
  455. recordedClip.SetData(soundata, 0);
  456. int rescaleFactor = 32767;
  457. byte[] outData = new byte[soundata.Length * 2];
  458. for (int i = 0; i < soundata.Length; i++)
  459. {
  460. short temshort = (short)(soundata[i] * rescaleFactor);
  461. byte[] temdata = BitConverter.GetBytes(temshort);
  462. outData[i * 2] = temdata[0];
  463. outData[i * 2 + 1] = temdata[1];
  464. }
  465. return outData;
  466. }
  467. private static float[] BytesToFloat(byte[] data)
  468. {
  469. float[] sounddata = new float[data.Length / 2];
  470. for (int i = 0; i < sounddata.Length; i++)
  471. {
  472. sounddata[i] = ByteToFloat(data[i * 2], data[i * 2 + 1]);
  473. }
  474. return sounddata;
  475. }
  476. private static float ByteToFloat(byte firstByte, byte secondByte)
  477. {
  478. short s;
  479. if (BitConverter.IsLittleEndian)
  480. s = (short)((secondByte << 8) | firstByte);
  481. else
  482. s = (short)((firstByte << 8) | secondByte);
  483. return s / 32768.0F;
  484. }
  485. #endregion
  486. }
  487. }