4using System.Collections.Generic;
12 [RequireComponent(typeof(RectTransform))]
13 [RequireComponent(typeof(Graphic))]
14 [DisallowMultipleComponent]
15 [AddComponentMenu(
"UI/Effects/Extensions/Curly UI Graphic")]
31 [Tooltip(
"Set true to make the curve/morph to work. Set false to quickly see the original UI.")]
42 [Tooltip(
"Set true to dynamically change the curve according to the dynamic change of the UI layout")]
53 [Tooltip(
"Pick a higher resolution to improve the quality of the curved graphic.")]
74 [Tooltip(
"Put in the Graphic you want to curve/morph here.")]
84 [Tooltip(
"Put in the reference Graphic that will be used to tune the bezier curves. Think button image and text.")]
95 [Tooltip(
"Do not touch this unless you are sure what you are doing. The curves are (re)generated automatically.")]
127 public Vector3_Array2D[] EDITOR_RefCurvesControlRatioPoints
148 protected void solveDoubleEquationWithVector(
float _x_1,
float _y_1,
float _x_2,
float _y_2, Vector3 _constant_1, Vector3 _contant_2, out Vector3 _x, out Vector3 _y)
153 if (Mathf.Abs(_x_1) > Mathf.Abs(_x_2))
155 f = _constant_1 * _x_2 / _x_1;
156 g = _y_1 * _x_2 / _x_1;
157 _y = (_contant_2 - f) / (_y_2 - g);
159 _x = (f - g * _y) / _x_2;
161 _x = (_constant_1 - _y_1 * _y) / _x_1;
165 f = _contant_2 * _x_1 / _x_2;
166 g = _y_2 * _x_1 / _x_2;
167 _x = (_constant_1 - f) / (_y_1 - g);
169 _y = (f - g * _x) / _x_1;
171 _y = (_contant_2 - _y_2 * _x) / _x_2;
178 UIVertex tmpUIVertex =
new UIVertex();
180 tmpUIVertex.position = Vector3.Lerp(_a.position, _b.position, _time);
181 tmpUIVertex.normal = Vector3.Lerp(_a.normal, _b.normal, _time);
182 tmpUIVertex.tangent = Vector3.Lerp(_a.tangent, _b.tangent, _time);
183 tmpUIVertex.uv0 = Vector2.Lerp(_a.uv0, _b.uv0, _time);
184 tmpUIVertex.uv1 = Vector2.Lerp(_a.uv1, _b.uv1, _time);
185 tmpUIVertex.color =
Color.Lerp(_a.color, _b.color, _time);
193 protected UIVertex
uiVertexBerp(UIVertex v_bottomLeft, UIVertex v_topLeft, UIVertex v_topRight, UIVertex v_bottomRight,
float _xTime,
float _yTime)
195 UIVertex topX =
uiVertexLerp(v_topLeft, v_topRight, _xTime);
196 UIVertex bottomX =
uiVertexLerp(v_bottomLeft, v_bottomRight, _xTime);
202 UIVertex v_bottomLeft = _quads[_thisQuadIdx];
203 UIVertex v_topLeft = _quads[_thisQuadIdx + 1];
204 UIVertex v_topRight = _quads[_thisQuadIdx + 2];
205 UIVertex v_bottomRight = _quads[_thisQuadIdx + 3];
209 int heightQuadEdgeNum = Mathf.Max(1, Mathf.CeilToInt((v_topLeft.position - v_bottomLeft.position).magnitude / quadSize));
210 int widthQuadEdgeNum = Mathf.Max(1, Mathf.CeilToInt((v_topRight.position - v_topLeft.position).magnitude / quadSize));
214 for (
int x = 0; x < widthQuadEdgeNum; x++)
216 for (
int y = 0; y < heightQuadEdgeNum; y++, quadIdx++)
218 _quads.Add(
new UIVertex());
219 _quads.Add(
new UIVertex());
220 _quads.Add(
new UIVertex());
221 _quads.Add(
new UIVertex());
223 float xRatio = (float)x / widthQuadEdgeNum;
224 float yRatio = (float)y / heightQuadEdgeNum;
225 float xPlusOneRatio = (float)(x + 1) / widthQuadEdgeNum;
226 float yPlusOneRatio = (float)(y + 1) / heightQuadEdgeNum;
228 _quads[_quads.Count - 4] =
uiVertexBerp(v_bottomLeft, v_topLeft, v_topRight, v_bottomRight, xRatio, yRatio);
229 _quads[_quads.Count - 3] =
uiVertexBerp(v_bottomLeft, v_topLeft, v_topRight, v_bottomRight, xRatio, yPlusOneRatio);
230 _quads[_quads.Count - 2] =
uiVertexBerp(v_bottomLeft, v_topLeft, v_topRight, v_bottomRight, xPlusOneRatio, yPlusOneRatio);
231 _quads[_quads.Count - 1] =
uiVertexBerp(v_bottomLeft, v_topLeft, v_topRight, v_bottomRight, xPlusOneRatio, yRatio);
239 for (
int v = 0; v < _verts.Count; v += 6)
250 for (
int q = 0; q < oriQuadNum; q++)
293 for (
int c = 0; c <
refCurves.Length; c++)
307 Undo.RecordObject(
this,
"Move Point");
310 Vector3 ratioPoint = controlPoints[p];
349 #region Configurations
358 rectTrans = GetComponent<RectTransform>();
363 bool isCurvesReady =
true;
365 for (
int c = 0; c < 2; c++)
367 isCurvesReady = isCurvesReady &
refCurves[c] !=
null;
370 isCurvesReady = isCurvesReady &
refCurves.Length == 2;
376 for (
int c = 0; c < 2; c++)
380 GameObject go =
new GameObject();
381 go.transform.SetParent(transform);
382 go.transform.localPosition = Vector3.zero;
383 go.transform.localEulerAngles = Vector3.zero;
387 go.name =
"BottomRefCurve";
391 go.name =
"TopRefCurve";
411 for (
int c = 0; c <
refCurves.Length; c++)
422 for (
int c = 0; c < 2; c++)
430 for (
int c = 0; c <
refCurves.Length; c++)
452 controlPoints[p].z = 0;
462 Vector3 posDeltaBetweenBottomLeftCorner =
rectTrans.localPosition;
468 Vector3 bottomLeftPosRatio =
new Vector3(posDeltaBetweenBottomLeftCorner.x /
refCUIGraphic.
RectTrans.rect.width, posDeltaBetweenBottomLeftCorner.y /
refCUIGraphic.
RectTrans.rect.height, posDeltaBetweenBottomLeftCorner.z);
478 for (
int c = 0; c <
refCurves.Length; c++)
482 float yTime = c == 0 ? bottomLeftPosRatio.y : topRightPosRatio.y;
487 float quarter = 0.25f,
488 threeQuarter = 0.75f;
493 float x_1 = 3 * threeQuarter * threeQuarter * quarter,
494 y_1 = 3 * threeQuarter * quarter * quarter,
495 x_2 = 3 * quarter * quarter * threeQuarter,
496 y_2 = 3 * quarter * threeQuarter * threeQuarter;
498 Vector3 contant_1 = quarterPoint - Mathf.Pow(threeQuarter, 3) * leftPoint - Mathf.Pow(quarter, 3) * rightPoint,
499 contant_2 = threeQuaterPoint - Mathf.Pow(quarter, 3) * leftPoint - Mathf.Pow(threeQuarter, 3) * rightPoint,
518 using (VertexHelper vh =
new VertexHelper(_mesh))
532 List<UIVertex> vertexList =
new List<UIVertex>();
533 _vh.GetUIVertexStream(vertexList);
538 _vh.AddUIVertexTriangleStream(vertexList);
553 for (
int index = 0; index < _verts.Count; index++)
555 var uiVertex = _verts[index];
564 uiVertex.position.x = pos.x;
565 uiVertex.position.y = pos.y;
566 uiVertex.position.z = pos.z;
568 _verts[index] = uiVertex;
576 for (
int c = 0; c <
refCurves.Length; c++)
581 Undo.RecordObject(curve,
"Move Rect");
Assume to be a cubic bezier curve at the moment.
static readonly int CubicBezierCurvePtNum
Vector3 GetTangent(float _time)
Vector3 GetPoint(float _time)
call this to get a sample
void tessellateQuad(List< UIVertex > _quads, int _thisQuadIdx)
readonly static int topCurveIdx
override void OnRectTransformDimensionsChange()
Vector3_Array2D[] refCurvesControlRatioPoints
bool isCurved
Describing the properties of this object.
UIVertex uiVertexLerp(UIVertex _a, UIVertex _b, float _time)
virtual void ReportSet()
Check, prepare and set everything needed.
Vector3 GetBCurveSandwichSpacePoint(float _xTime, float _yTime)
void solveDoubleEquationWithVector(float _x_1, float _y_1, float _x_2, float _y_2, Vector3 _constant_1, Vector3 _contant_2, out Vector3 _x, out Vector3 _y)
void ReferenceCUIForBCurves()
CUIBezierCurve[] refCurves
Vector3_Array2D[] RefCurvesControlRatioPoints
CUIBezierCurve[] RefCurves
readonly static int bottomCurveIdx
void UpdateCurveControlPointPositions()
RectTransform rectTrans
Reference to other objects that are needed by this object.
virtual void modifyVertices(List< UIVertex > _verts)
void tessellateGraphic(List< UIVertex > _verts)
UIVertex uiVertexBerp(UIVertex v_bottomLeft, UIVertex v_topLeft, UIVertex v_topRight, UIVertex v_bottomRight, float _xTime, float _yTime)
Bilinear Interpolation
override void ModifyMesh(VertexHelper _vh)
Vector3 GetBCurveSandwichSpaceTangent(float _xTime, float _yTime)
List< UIVertex > reuse_quads
void FixTextToRectTrans()
override void ModifyMesh(Mesh _mesh)
Credit Erdener Gonenc - @PixelEnvision.