-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
Copy pathRectTransformUtility.cs
175 lines (142 loc) · 6.01 KB
/
RectTransformUtility.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
namespace UnityEngine
{
public sealed partial class RectTransformUtility
{
private static readonly Vector3[] s_Corners = new Vector3[4];
private RectTransformUtility() {}
public static bool RectangleContainsScreenPoint(RectTransform rect, Vector2 screenPoint)
{
return RectangleContainsScreenPoint(rect, screenPoint, null);
}
public static bool RectangleContainsScreenPoint(RectTransform rect, Vector2 screenPoint, Camera cam)
{
return RectangleContainsScreenPoint(rect, screenPoint, cam, Vector4.zero);
}
public static bool RectangleContainsScreenPoint(RectTransform rect, Vector2 screenPoint, Camera cam, Vector4 offset)
{
return PointInRectangle(screenPoint, rect, cam, offset);
}
public static bool ScreenPointToWorldPointInRectangle(RectTransform rect, Vector2 screenPoint, Camera cam, out Vector3 worldPoint)
{
worldPoint = Vector2.zero;
Ray ray = ScreenPointToRay(cam, screenPoint);
var plane = new Plane(rect.rotation * Vector3.back, rect.position);
float dist = 0;
float dot = Vector3.Dot(Vector3.Normalize(rect.position - ray.origin), plane.normal);
if (dot != 0 && !plane.Raycast(ray, out dist))
return false;
worldPoint = ray.GetPoint(dist);
return true;
}
public static bool ScreenPointToLocalPointInRectangle(RectTransform rect, Vector2 screenPoint, Camera cam, out Vector2 localPoint)
{
localPoint = Vector2.zero;
Vector3 worldPoint;
if (ScreenPointToWorldPointInRectangle(rect, screenPoint, cam, out worldPoint))
{
localPoint = rect.InverseTransformPoint(worldPoint);
return true;
}
return false;
}
public static Ray ScreenPointToRay(Camera cam, Vector2 screenPos)
{
if (cam != null)
return cam.ScreenPointToRay(screenPos);
Vector3 pos = screenPos;
pos.z -= 100f;
return new Ray(pos, Vector3.forward);
}
public static Vector2 WorldToScreenPoint(Camera cam, Vector3 worldPoint)
{
if (cam == null)
return new Vector2(worldPoint.x, worldPoint.y);
return cam.WorldToScreenPoint(worldPoint);
}
public static Bounds CalculateRelativeRectTransformBounds(Transform root, Transform child)
{
RectTransform[] rects = child.GetComponentsInChildren<RectTransform>(false);
if (rects.Length > 0)
{
Vector3 vMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
Vector3 vMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);
Matrix4x4 toLocal = root.worldToLocalMatrix;
for (int i = 0, imax = rects.Length; i < imax; i++)
{
rects[i].GetWorldCorners(s_Corners);
for (int j = 0; j < 4; j++)
{
Vector3 v = toLocal.MultiplyPoint3x4(s_Corners[j]);
vMin = Vector3.Min(v, vMin);
vMax = Vector3.Max(v, vMax);
}
}
Bounds b = new Bounds(vMin, Vector3.zero);
b.Encapsulate(vMax);
return b;
}
return new Bounds(Vector3.zero, Vector3.zero);
}
public static Bounds CalculateRelativeRectTransformBounds(Transform trans)
{
return CalculateRelativeRectTransformBounds(trans, trans);
}
public static void FlipLayoutOnAxis(RectTransform rect, int axis, bool keepPositioning, bool recursive)
{
if (rect == null)
return;
if (recursive)
{
for (int i = 0; i < rect.childCount; i++)
{
RectTransform childRect = rect.GetChild(i) as RectTransform;
if (childRect != null)
FlipLayoutOnAxis(childRect, axis, false, true);
}
}
Vector2 pivot = rect.pivot;
pivot[axis] = 1.0f - pivot[axis];
rect.pivot = pivot;
if (keepPositioning)
return;
Vector2 anchoredPosition = rect.anchoredPosition;
anchoredPosition[axis] = -anchoredPosition[axis];
rect.anchoredPosition = anchoredPosition;
Vector2 anchorMin = rect.anchorMin;
Vector2 anchorMax = rect.anchorMax;
float temp = anchorMin[axis];
anchorMin[axis] = 1 - anchorMax[axis];
anchorMax[axis] = 1 - temp;
rect.anchorMin = anchorMin;
rect.anchorMax = anchorMax;
}
public static void FlipLayoutAxes(RectTransform rect, bool keepPositioning, bool recursive)
{
if (rect == null)
return;
if (recursive)
{
for (int i = 0; i < rect.childCount; i++)
{
RectTransform childRect = rect.GetChild(i) as RectTransform;
if (childRect != null)
FlipLayoutAxes(childRect, false, true);
}
}
rect.pivot = GetTransposed(rect.pivot);
rect.sizeDelta = GetTransposed(rect.sizeDelta);
if (keepPositioning)
return;
rect.anchoredPosition = GetTransposed(rect.anchoredPosition);
rect.anchorMin = GetTransposed(rect.anchorMin);
rect.anchorMax = GetTransposed(rect.anchorMax);
}
private static Vector2 GetTransposed(Vector2 input)
{
return new Vector2(input.y, input.x);
}
}
}