using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Text; using System.Threading; using UnityEngine; using UnityEngine.EventSystems; using LitJson; public static class QGlobalFun { private static readonly char[] replaceChars = new char[] { ' ', '(', ')' }; /// /// 是否有网络 /// /// public static bool IsNotNetwork(){ return Application.internetReachability== NetworkReachability.NotReachable; } public static bool IsWifiNetwork(){ return Application.internetReachability == NetworkReachability.ReachableViaLocalAreaNetwork; } public static bool IsReachableViaCarrierDataNetwork(){ return Application.internetReachability == NetworkReachability.ReachableViaCarrierDataNetwork; } /// /// 写入路径 /// /// public static string GetWritePath(){ switch (Application.platform) { case RuntimePlatform.OSXEditor: return Application.dataPath.Replace("/Assets", "") + "/Data/"; case RuntimePlatform.IPhonePlayer: return Application.persistentDataPath + "/"; case RuntimePlatform.WindowsEditor: return Application.dataPath.ToString().Replace("/Assets", "") + "/Data/"; case RuntimePlatform.WindowsPlayer: var path = Application.dataPath.ToString().Replace("/Assets", "") + "/Data/"; QFileOperation.CreateDirctory(path); return path; case RuntimePlatform.Android: return Application.persistentDataPath + "/"; default: return Application.persistentDataPath + "/"; } } public static string GetInsidePath(){ switch (Application.platform) { case RuntimePlatform.OSXEditor: return "file://" + Application.dataPath + "/StreamingAssets/"; case RuntimePlatform.IPhonePlayer: return Application.streamingAssetsPath + "/"; case RuntimePlatform.WindowsEditor: return "file://" + Application.dataPath + "/StreamingAssets/"; case RuntimePlatform.WindowsPlayer: return "file://" + Application.dataPath + "/StreamingAssets/"; case RuntimePlatform.Android: return Application.dataPath + "!/Assets/"; default: return Application.dataPath + "!/Assets/"; } } public static string GetPlatform(){ switch (Application.platform) { case RuntimePlatform.OSXEditor: return "window"; case RuntimePlatform.IPhonePlayer: return "ios"; case RuntimePlatform.WindowsEditor: return "window"; case RuntimePlatform.WindowsPlayer: return "window"; case RuntimePlatform.Android: return "android"; default: return "android"; } } public static string GetDeviceCode() { return SystemInfo.deviceUniqueIdentifier; } public static bool IsLengthZero(this string target) { return target.Length == 0; } public static string GetString(string value) { StringBuilder sb = new StringBuilder(value); foreach (var error in replaceChars) { sb.Replace(error, '_'); } return sb.ToString(); } public static string GetMoudleString(string value) { StringBuilder sb = new StringBuilder(value); foreach (var error in replaceChars) { sb.Replace(error, '_'); } return sb + "Moudle"; } public static T IsComponent(this GameObject go) where T : Component { T com = go.GetComponent(); if (com == null) com = go.AddComponent(); return com; } public static T IsComponent(this Transform target) where T : Component { T com =target.GetComponent(); if (com == null) com = target.gameObject.AddComponent(); return com; } public static string GetFirstUpper(string value) { return char.ToUpper(value[0]) + value.Substring(1); } public static string[] GetComponentsName(Transform t) { var coms = t.GetComponents(); if (coms == null) return null; List types = new List(); for (int i = 0; i < coms.Length; i++) { if (coms[i] == null) continue; types.Add(coms[i].GetType().Name); } return types.ToArray(); } public static string GetGameObjectPath(Transform target, Transform parent) { return GetFindPath(target, parent).Remove(0, 1); } public static Assembly GetAssembly() { Assembly[] AssbyCustmList = System.AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < AssbyCustmList.Length; i++) { string assbyName = AssbyCustmList[i].GetName().Name; if (assbyName == "Assembly-CSharp") { return AssbyCustmList[i]; } } return null; } public static string[] GetStringList(string target, int max=10000) { if (target.Length < max) return new string[] {target }; int count = target.Length / max; var array = new string[count+1]; for(int i = 0; i < count; i++) { array[i] = target.Substring(i * max, max)+"\n"; } array[count] = target.Substring(count * max, target.Length%max); return array; } public static T GetInstance(this string instanceName, params object[] param) { return (T)Assembly.Load(Assembly.GetAssembly(typeof(T)).GetName().Name).CreateInstance(typeof(T).Namespace + "." + instanceName, true, BindingFlags.CreateInstance, null, param, Thread.CurrentThread.CurrentCulture, null); } public static string GetFind(Transform target) { if(target.parent == null) { if(target == null) return string.Empty; return target.name; } return GetFind(target.parent) + "/" + target.name; } public static Transform GetParent(this string value){ var index = value.LastIndexOf('/'); return GameObject.Find(value.Remove(index, value.Length - index)).transform; } public static void AddVector3(this JsonData target, string name, Vector3Double value) { target[name] = new JsonData(); target[name]["x"] = value.x; target[name]["y"] = value.y; target[name]["z"] = value.z; } private static string GetFindPath(Transform target, Transform parent) { if (target == parent) return string.Empty; return GetFindPath(target.parent, parent) + "/" + target.name; } #region QGlobalFunction 迁移 public static readonly Vector2 Vector2Center = new Vector2(0.5f, 0.5f); public static readonly Vector3 Vector3Center = new Vector3(0.5f, 0.5f, 0.5f); public static Transform[] GetTransforms(this Transform transform){ List list = new List(); foreach(Transform item in transform){ list.Add(item); if(item.childCount>0){ list.AddRange( item.GetTransforms()); } } return list.ToArray(); } public static Sprite ToSprite(this Texture2D value) { return Sprite.Create(value, new Rect(0, 0, value.width, value.height), Vector2.zero, 1f); } public static bool IsPointerOverLayer(int layer) { PointerEventData pointerData = new PointerEventData(EventSystem.current); pointerData.position = Input.mousePosition; var results = new List(); EventSystem.current.RaycastAll(pointerData, results); //if (tag.Length != 0) /*{ for (int j = 0; j < results.Count; j++) { if (results[j].gameObject.layer == layer) return false; } }*/ return results.Count > 0 && results[0].gameObject.layer == layer; } public static float Distance(this float a, float b) { return Mathf.Abs(a) - Mathf.Abs(b); } /// /// 2D旋转矩阵 /// /// /// /// public static Matrix4x4 Rotate2D(this Matrix4x4 mat, float angle) { angle = angle * Mathf.Deg2Rad; mat.m00 = Mathf.Cos(angle); mat.m01 = Mathf.Sin(angle); mat.m10 = -Mathf.Sin(angle); mat.m11 = Mathf.Cos(angle); return mat; } /// /// UV旋转 /// /// /// /// /// public static Mesh RotateUV(this Mesh mesh, float angle, int channelIndex = 0) { List uvs = new List(mesh.uv); var mat = Rotate2D(new Matrix4x4(), angle); for (int i = 0; i < uvs.Count; i++) { Vector2 uv = uvs[i] - Vector2Center; uv = (mat * uv); uv += Vector2Center; uvs[i] = uv; } mesh.SetUVs(channelIndex, uvs); return mesh; } /// /// 纹理分割 /// /// /// /// public static Texture2D TextureClipRect(Texture2D target, RectInt rect) { var width = rect.width; var height = rect.height; if (rect.x + rect.width >= target.width) width = target.width - rect.x; if (rect.y + rect.height >= target.height) height = target.height - rect.y; var result = new Texture2D(width, height); var data = target.GetPixels(rect.x, rect.y, width, height); result.SetPixels(data); result.Apply(); return result; } /// /// 绘制矩形 /// /// /// /// /// public static void DrawRect(Texture2D target, ref Texture2D result, RectInt rect, Color color) { var data = target.GetPixels(); var width = target.width; var offsetWidth = rect.width - rect.x; var offsetHeight = rect.height - rect.y; if (offsetWidth >= offsetHeight) { offsetWidth = rect.x + rect.width; offsetHeight = rect.y + rect.height; if (offsetWidth > width) offsetWidth = width; if (offsetHeight > target.height) offsetHeight = target.height; for (int y = rect.y; y < offsetHeight; y++) { for (int x = rect.x; x < offsetWidth; x++) { data[y * width + x] = color; } } } else { offsetWidth = rect.x + rect.width; offsetHeight = rect.y + rect.height; if (offsetWidth > width) offsetWidth = width; if (offsetHeight > target.height) offsetHeight = target.height; for (int x = rect.x; x < offsetWidth; x++) { for (int y = rect.y; y < offsetHeight; y++) { data[y * width + x] = color; } } } result.SetPixels(data); result.Apply(); } /// /// 绘制矩形 /// /// /// /// /// public static void DrawRect(Texture2D target, ref Texture2D result, RectInt rect, float coefficient) { var data = target.GetPixels(); var width = target.width; var offsetWidth = rect.width - rect.x; var offsetHeight = rect.height - rect.y; Color color; var w = rect.x + rect.width; var h = rect.y + rect.height; if (w > width) w = width; if (h > target.height) h = target.height; if (offsetWidth >= offsetHeight) { offsetWidth = rect.x + rect.width; offsetHeight = rect.y + rect.height; if (offsetWidth > width) offsetWidth = width; if (offsetHeight > target.height) offsetHeight = target.height; for (int y = rect.y; y < h; y++) { for (int x = rect.x; x < w; x++) { color = data[y * width + x]; data[y * width + x] = new Color(color.r * coefficient, color.g * coefficient, color.b * coefficient, color.a); } } } else { offsetWidth = rect.x + rect.width; offsetHeight = rect.y + rect.height; if (offsetWidth > width) offsetWidth = width; if (offsetHeight > target.height) offsetHeight = target.height; for (int x = rect.x; x < w; x++) { for (int y = rect.y; y < h; y++) { color = data[y * width + x]; data[y * width + x] = new Color(color.r * coefficient, color.g * coefficient, color.b * coefficient, color.a); } } } result.SetPixels(data); result.Apply(); } /// /// 交换值 /// /// /// public static void Swap(ref T a, ref T b) { var tmp = a; a = b; b = tmp; } /// /// 绘制直角三角形 /// /// /// /// /// /// /// public static void DrawRightAngleTriangle(Texture2D target, ref Texture2D result, Color color, Vector2Int p1, Vector2Int p2, Vector2Int p3) { var data = target.GetPixels(); var width = target.width; #region 确定 p3 if (p1.y < p2.y) Swap(ref p1, ref p2); if (p2.y < p3.y) Swap(ref p2, ref p3); #endregion #region 确定 p2 if (p1.x < p2.x) Swap(ref p1, ref p2); #endregion int count = 0; Vector2Int[] pos = null; if (p1.x == p3.x) { if (p2.y == p3.y) { pos = GetBLinePoints(p2, p1); } else { pos = GetBLinePoints(p2, p3); } Debug.Log(p1 + "" + p2 + p3); for (int i = 0; i < pos.Length; i++) { count = p1.x - pos[i].x; while (count-- != 0) { data[pos[i].y * width + pos[i].x + count] = color; } } } else { if (p1.y == p3.y) pos = GetBLinePoints(p1, p2); else pos = GetBLinePoints(p1, p3); for (int i = 0; i < pos.Length; i++) { count = pos[i].x - p2.x; while (count-- != 0) { data[pos[i].y * width + count + p2.x] = color; } } } result.SetPixels(data); result.Apply(); } public static void DrawRightAngleTriangleTest(Texture2D target, ref Texture2D result) { var center = target.height / 2; DrawRightAngleTriangle(target, ref result, Color.green, new Vector2Int(0, 0), new Vector2Int(0, center), new Vector2Int(target.width, center)); DrawRightAngleTriangle(result, ref result, Color.blue, new Vector2Int(0, 0), new Vector2Int(target.width - 1, 0), new Vector2Int(target.width - 1, center)); DrawRightAngleTriangle(result, ref result, Color.red, new Vector2Int(0, center + 1), new Vector2Int(0, target.height - 1), new Vector2Int(target.width, target.height - 1)); DrawRightAngleTriangle(result, ref result, Color.black, new Vector2Int(0, center + 1), new Vector2Int(target.width - 1, center + 1), new Vector2Int(target.width - 1, target.height - 1)); } /// /// 绘制直角三角形 /// /// /// /// 系数 /// /// /// public static void DrawRightAngleTriangle(Texture2D target, ref Texture2D result, float coefficient, Vector2Int p1, Vector2Int p2, Vector2Int p3) { var data = target.GetPixels(); var width = target.width; #region 确定 p3 if (p1.y < p2.y) Swap(ref p1, ref p2); if (p2.y < p3.y) Swap(ref p2, ref p3); #endregion #region 确定 p2 if (p1.x < p2.x) Swap(ref p1, ref p2); #endregion int count = 0; Vector2Int[] pos = null; Color color; int index; if (p1.x == p3.x) { if (p2.y == p3.y) { pos = GetBLinePoints(p2, p1); } else { pos = GetBLinePoints(p2, p3); } for (int i = 0; i < pos.Length; i++) { count = p1.x - pos[i].x; while (count-- != 0) { index = pos[i].y * width + pos[i].x + count; color = data[index]; data[index] = new Color(color.r * coefficient, color.g * coefficient, color.b * coefficient, color.a); } } } else { if (p1.y == p3.y) pos = GetBLinePoints(p1, p2); else pos = GetBLinePoints(p1, p3); for (int i = 0; i < pos.Length; i++) { count = pos[i].x - p2.x; while (count-- != 0) { index = pos[i].y * width + count + p2.x; color = data[index]; data[index] = new Color(color.r * coefficient, color.g * coefficient, color.b * coefficient, color.a); } } } result.SetPixels(data); result.Apply(); } /// /// 获得直线坐标 /// /// /// /// public static Vector2Int[] GetBLinePoints(Vector2Int point0, Vector2Int point1) { var points = new List(); int x0 = (int)point0.x; int y0 = (int)point0.y; int x1 = (int)point1.x; int y1 = (int)point1.y; var dx = Mathf.Abs(x1 - x0); var dy = Mathf.Abs(y1 - y0); var sx = (x0 < x1) ? 1 : -1; var sy = (y0 < y1) ? 1 : -1; var err = dx - dy; int err2; while (true) { points.Add(new Vector2Int(x0, y0)); if ((x0 == x1) && (y0 == y1)) { break; } err2 = 2 * err; if (err2 + dy > 0) { x0 += sx; err -= dy; } if (err2 - dx < 0) { y0 += sy; err += dx; } } return points.ToArray(); } /// /// 绘制直线 /// /// /// /// /// /// public static void DrawBLine(ref Color[] result, int width, Color color, Vector2 point0, Vector2 point1) { int x0 = (int)point0.x; int y0 = (int)point0.y; int x1 = (int)point1.x; int y1 = (int)point1.y; var dx = Mathf.Abs(x1 - x0); var dy = Mathf.Abs(y1 - y0); var sx = (x0 < x1) ? 1 : -1; var sy = (y0 < y1) ? 1 : -1; var err = dx - dy; int err2; while (true) { result[x0 + y0 * width] = color; if ((x0 == x1) && (y0 == y1)) { break; } err2 = 2 * err; if (err2 + dy > 0) { x0 += sx; err -= dy; } if (err2 - dx < 0) { y0 += sy; err += dx; } } } #endregion }