| using System.Collections; | 
| using System.Collections.Generic; | 
| using UnityEngine; | 
| using UnityEngine.UI; | 
| using UnityEngine.EventSystems; | 
|   | 
|   | 
|   | 
| public static class UIUtility | 
| { | 
|   | 
|     public static GameObject CreateWidget(string _sourceName, string _name) | 
|     { | 
|         var prefab = UILoader.LoadPrefab(_sourceName); | 
|         if (prefab == null) | 
|         { | 
|             return null; | 
|         } | 
|   | 
|         var instance = GameObject.Instantiate(prefab); | 
|         instance.name = string.IsNullOrEmpty(_name) ? _sourceName : _name; | 
|         return instance; | 
|     } | 
|   | 
|     public static T GetComponent<T>(this Transform transform, string path) where T : Component | 
|     { | 
|         if (transform == null || string.IsNullOrEmpty(path)) | 
|         { | 
|             return null; | 
|         } | 
|   | 
|         var _child = transform.Find(path); | 
|         if (_child == null) | 
|         { | 
|             return null; | 
|         } | 
|         else | 
|         { | 
|             return _child.GetComponent<T>(); | 
|         } | 
|     } | 
|   | 
|     public static T GetComponent<T>(this Component component, string path) where T : Component | 
|     { | 
|         if (component == null || string.IsNullOrEmpty(path)) | 
|         { | 
|             return null; | 
|         } | 
|   | 
|         var _child = component.transform.Find(path); | 
|         if (_child == null) | 
|         { | 
|             return null; | 
|         } | 
|         else | 
|         { | 
|             return _child.GetComponent<T>(); | 
|         } | 
|     } | 
|   | 
|     public static T GetComponent<T>(this GameObject gameObject, string path) where T : Component | 
|     { | 
|         if (gameObject == null || string.IsNullOrEmpty(path)) | 
|         { | 
|             return null; | 
|         } | 
|   | 
|         var _child = gameObject.transform.Find(path); | 
|         if (_child == null) | 
|         { | 
|             return null; | 
|         } | 
|         else | 
|         { | 
|             return _child.GetComponent<T>(); | 
|         } | 
|     } | 
|   | 
|     public static Vector2 GetMaxWorldPosition(this RectTransform _rectTransform) | 
|     { | 
|         Vector3[] cornors = new Vector3[4]; | 
|         _rectTransform.GetWorldCorners(cornors); | 
|         return cornors[2]; | 
|     } | 
|   | 
|     public static Vector2 GetMinWorldPosition(this RectTransform _rectTransform) | 
|     { | 
|         Vector3[] cornors = new Vector3[4]; | 
|         _rectTransform.GetWorldCorners(cornors); | 
|         return cornors[0]; | 
|     } | 
|   | 
|     public static Vector2 GetMaxReferencePosition(this RectTransform _rectTransform, Transform _reference) | 
|     { | 
|         Vector2 max; | 
|         var offsetY = (1 - _rectTransform.pivot.y) * _rectTransform.rect.height; | 
|         var offsetX = (1 - _rectTransform.pivot.x) * _rectTransform.rect.width; | 
|         max = _rectTransform.TransformPoint(offsetX, offsetY, 0); | 
|         max = _reference.InverseTransformVector(max); | 
|         return max; | 
|     } | 
|   | 
|     public static Vector2 GetMinReferencePosition(this RectTransform _rectTransform, Transform _reference) | 
|     { | 
|         Vector2 min; | 
|         var offsetY = -_rectTransform.pivot.y * _rectTransform.rect.height; | 
|         var offsetX = -_rectTransform.pivot.x * _rectTransform.rect.width; | 
|         min = _rectTransform.TransformPoint(offsetX, offsetY, 0); | 
|         min = _reference.InverseTransformVector(min); | 
|   | 
|         return min; | 
|     } | 
|   | 
|     public static int RayCrossingCount(Vector2 p, List<Vector3> vertices) | 
|     { | 
|         var crossNum = 0; | 
|         for (int i = 0, count = vertices.Count; i < count; i++) | 
|         { | 
|             var v1 = vertices[i]; | 
|             var v2 = vertices[(i + 1) % count]; | 
|   | 
|             if (((v1.y <= p.y) && (v2.y > p.y)) | 
|                 || ((v1.y > p.y) && (v2.y <= p.y))) | 
|             { | 
|                 if (p.x < v1.x + (p.y - v1.y) / (v2.y - v1.y) * (v2.x - v1.x)) | 
|                 { | 
|                     crossNum += 1; | 
|                 } | 
|             } | 
|         } | 
|   | 
|         return crossNum; | 
|     } | 
|   | 
|     public static UIVertex PackageUIVertex(Vector3 _position, Vector2 _uv0, Color _color) | 
|     { | 
|         var vertex = new UIVertex(); | 
|         vertex.position = _position; | 
|         vertex.uv0 = _uv0; | 
|         vertex.color = _color; | 
|   | 
|         return vertex; | 
|     } | 
|   | 
|     public static UIVertex PackageUIVertexUV1(Vector3 _position, Vector2 _uv1, Color _color) | 
|     { | 
|         var vertex = new UIVertex(); | 
|         vertex.position = _position; | 
|         vertex.uv1 = _uv1; | 
|         vertex.color = _color; | 
|   | 
|         return vertex; | 
|     } | 
|   | 
|     public static Vector3 ClampWorldPosition(RectTransform _area, PointerEventData _data) | 
|     { | 
|         if (_area == null || _data == null) | 
|         { | 
|             return Vector3.zero; | 
|         } | 
|         else | 
|         { | 
|             var worldMousePos = Vector3.zero; | 
|             if (RectTransformUtility.ScreenPointToWorldPointInRectangle(_area, _data.position, _data.pressEventCamera, out worldMousePos)) | 
|             { | 
|                 return worldMousePos; | 
|             } | 
|             else | 
|             { | 
|                 return _data.pointerCurrentRaycast.worldPosition; | 
|             } | 
|         } | 
|     } | 
|   | 
|     public static bool RectTransformContain(RectTransform _area, RectTransform _test) | 
|     { | 
|         if (_area == null || _test == null) | 
|         { | 
|             return false; | 
|         } | 
|   | 
|         var worldcornersA = new Vector3[4]; | 
|         _area.GetWorldCorners(worldcornersA); | 
|         var worldcornersB = new Vector3[4]; | 
|         _test.GetWorldCorners(worldcornersB); | 
|   | 
|         var a = new Quadrangle(worldcornersA[0].x, worldcornersA[0].y, worldcornersA[2].x, worldcornersA[2].y); | 
|         var b = new Quadrangle(worldcornersB[0].x, worldcornersB[0].y, worldcornersB[2].x, worldcornersB[2].y); | 
|   | 
|         if (a.minX > b.maxX || a.maxX < b.minX || a.minY > b.maxY || a.maxY < b.minY) | 
|         { | 
|             return false; | 
|         } | 
|         else | 
|         { | 
|             return true; | 
|         } | 
|     } | 
|   | 
|     public static bool IsPointerOverGameObject() | 
|     { | 
|         if (EventSystem.current == null) | 
|         { | 
|             return false; | 
|         } | 
|   | 
|         var eventData = new PointerEventData(EventSystem.current); | 
|         eventData.pressPosition = Input.mousePosition; | 
|         eventData.position = Input.mousePosition; | 
|   | 
|         var list = new List<RaycastResult>(); | 
|         EventSystem.current.RaycastAll(eventData, list); | 
|   | 
|         return list.Count > 0; | 
|     } | 
|   | 
|     struct Quadrangle | 
|     { | 
|         public float minX; | 
|         public float minY; | 
|         public float maxX; | 
|         public float maxY; | 
|   | 
|         public Quadrangle(float _minX, float _minY, float _maxX, float _maxY) | 
|         { | 
|             this.minX = _minX; | 
|             this.minY = _minY; | 
|             this.maxX = _maxX; | 
|             this.maxY = _maxY; | 
|         } | 
|     } | 
|   | 
|   | 
|     public static Vector2 GetEdge(List<UIVertex> _vertexs, int _axis) | 
|     { | 
|   | 
|         if (_vertexs == null || _vertexs.Count == 0) | 
|         { | 
|             Debug.Log("非法顶点数据"); | 
|             return Vector2.zero; | 
|         } | 
|   | 
|         if (_axis != 0 && _axis != 1) | 
|         { | 
|             Debug.Log("非法轴"); | 
|             return Vector2.zero; | 
|         } | 
|   | 
|         var count = _vertexs.Count; | 
|         var min = _vertexs[0].position[_axis]; | 
|         var max = _vertexs[0].position[_axis]; | 
|   | 
|         for (int i = 1; i < count; i++) | 
|         { | 
|             if (_vertexs[i].position[_axis] < min) | 
|             { | 
|                 min = _vertexs[i].position[_axis]; | 
|             } | 
|             else if (_vertexs[i].position[_axis] > max) | 
|             { | 
|                 max = _vertexs[i].position[_axis]; | 
|             } | 
|         } | 
|   | 
|         return new Vector2(min, max); | 
|     } | 
|   | 
|     public static void AddQuad(VertexHelper vertexHelper, Vector3[] quadPositions, Color32 color, Vector2[] quadUVs) | 
|     { | 
|         if (quadPositions == null || quadPositions.Length < 4) | 
|         { | 
|             Debug.Log("非法顶点数组"); | 
|             return; | 
|         } | 
|   | 
|         if (quadUVs == null || quadUVs.Length < 4) | 
|         { | 
|             Debug.Log("非法UV数组"); | 
|             return; | 
|         } | 
|   | 
|         var currentVertCount = vertexHelper.currentVertCount; | 
|         for (var i = 0; i < 4; i++) | 
|         { | 
|             vertexHelper.AddVert(quadPositions[i], color, quadUVs[i]); | 
|         } | 
|         vertexHelper.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2); | 
|         vertexHelper.AddTriangle(currentVertCount + 2, currentVertCount + 3, currentVertCount); | 
|     } | 
|   | 
|     public static void AddTriangle(VertexHelper vertexHelper, Vector3[] positions, Color32 color, Vector2[] uvs) | 
|     { | 
|         if (positions == null || positions.Length < 3) | 
|         { | 
|             Debug.Log("非法顶点数组"); | 
|             return; | 
|         } | 
|   | 
|         if (uvs == null || uvs.Length < 3) | 
|         { | 
|             Debug.Log("非法UV数组"); | 
|             return; | 
|         } | 
|   | 
|         var currentVertCount = vertexHelper.currentVertCount; | 
|         for (var i = 0; i < 3; i++) | 
|         { | 
|             vertexHelper.AddVert(positions[i], color, uvs[i]); | 
|         } | 
|         vertexHelper.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2); | 
|     } | 
|   | 
|   | 
|     public static void GetParents(Transform _transform, ref List<Transform> _parents) | 
|     { | 
|         if (_transform == null || _parents == null) | 
|         { | 
|             return; | 
|         } | 
|   | 
|         if (_transform.parent != null) | 
|         { | 
|             _parents.Insert(0, _transform.parent); | 
|   | 
|             GetParents(_transform.parent, ref _parents); | 
|         } | 
|     } | 
|   | 
|     public static string GetUIElementRelativePath(Transform _root, Transform _transform) | 
|     { | 
|         List<Transform> parents = new List<Transform>() { _transform }; | 
|         GetParents(_transform, ref parents); | 
|   | 
|         if (parents.Contains(_root)) | 
|         { | 
|             parents.Remove(_root); | 
|         } | 
|   | 
|         var names = new string[parents.Count]; | 
|         for (int i = 0; i < names.Length; i++) | 
|         { | 
|             names[i] = parents[i].gameObject.name; | 
|         } | 
|   | 
|         return string.Join("/", names); | 
|     } | 
| } |