mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 15:27:38 +02:00
Editor stuff
This commit is contained in:
@ -0,0 +1,116 @@
|
||||
/// Credit Titinious (https://github.com/Titinious)
|
||||
/// Sourced from - https://github.com/Titinious/CurlyUI
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Assume to be a cubic bezier curve at the moment.
|
||||
/// </summary>
|
||||
public class CUIBezierCurve : MonoBehaviour
|
||||
{
|
||||
public readonly static int CubicBezierCurvePtNum = 4;
|
||||
|
||||
#region Descriptions
|
||||
|
||||
[SerializeField]
|
||||
protected Vector3[] controlPoints;
|
||||
|
||||
public Vector3[] ControlPoints
|
||||
{
|
||||
get
|
||||
{
|
||||
return controlPoints;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// Reserve for editor only
|
||||
/// </summary>
|
||||
public Vector3[] EDITOR_ControlPoints
|
||||
{
|
||||
set
|
||||
{
|
||||
controlPoints = value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected void OnValidate()
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
#endif
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
|
||||
if (OnRefresh != null)
|
||||
OnRefresh();
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region Services
|
||||
|
||||
/// <summary>
|
||||
/// call this to get a sample
|
||||
/// </summary>
|
||||
/// <param name="_time"></param>
|
||||
/// <returns>sample returned by said time</returns>
|
||||
public Vector3 GetPoint(float _time)
|
||||
{
|
||||
float oneMinusTime = 1 - _time;
|
||||
|
||||
return oneMinusTime * oneMinusTime * oneMinusTime * controlPoints[0] +
|
||||
3 * oneMinusTime * oneMinusTime * _time * controlPoints[1] +
|
||||
3 * oneMinusTime * _time * _time * controlPoints[2] +
|
||||
_time * _time * _time * controlPoints[3];
|
||||
}
|
||||
|
||||
public Vector3 GetTangent(float _time)
|
||||
{
|
||||
float oneMinusTime = 1 - _time;
|
||||
|
||||
return 3 * oneMinusTime * oneMinusTime * (controlPoints[1] - controlPoints[0]) +
|
||||
6 * oneMinusTime * _time * (controlPoints[2] - controlPoints[1]) +
|
||||
3 * _time * _time * (controlPoints[3] - controlPoints[2]);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Configurations
|
||||
|
||||
public void ReportSet()
|
||||
{
|
||||
if (controlPoints == null)
|
||||
{
|
||||
controlPoints = new Vector3[CUIBezierCurve.CubicBezierCurvePtNum];
|
||||
controlPoints[0] = new Vector3(0, 0, 0);
|
||||
controlPoints[1] = new Vector3(0, 1, 0);
|
||||
controlPoints[2] = new Vector3(1, 1, 0);
|
||||
controlPoints[3] = new Vector3(1, 0, 0);
|
||||
}
|
||||
|
||||
bool isPointsReady = true;
|
||||
|
||||
isPointsReady = isPointsReady & controlPoints.Length == CUIBezierCurve.CubicBezierCurvePtNum;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Services
|
||||
|
||||
public System.Action OnRefresh;
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 983a3e151cd916d4faf111dc86266574
|
||||
timeCreated: 1485671878
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,617 @@
|
||||
/// Credit Titinious (https://github.com/Titinious)
|
||||
/// Sourced from - https://github.com/Titinious/CurlyUI
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[RequireComponent(typeof(Graphic))]
|
||||
[DisallowMultipleComponent]
|
||||
[AddComponentMenu("UI/Effects/Extensions/Curly UI Graphic")]
|
||||
public class CUIGraphic : BaseMeshEffect
|
||||
{
|
||||
// Describing the properties that are shared by all objects of this class
|
||||
#region Nature
|
||||
|
||||
readonly public static int bottomCurveIdx = 0;
|
||||
readonly public static int topCurveIdx = 1;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Describing the properties of this object.
|
||||
/// </summary>
|
||||
#region Description
|
||||
|
||||
[Tooltip("Set true to make the curve/morph to work. Set false to quickly see the original UI.")]
|
||||
[SerializeField]
|
||||
protected bool isCurved = true;
|
||||
public bool IsCurved
|
||||
{
|
||||
get
|
||||
{
|
||||
return isCurved;
|
||||
}
|
||||
}
|
||||
|
||||
[Tooltip("Set true to dynamically change the curve according to the dynamic change of the UI layout")]
|
||||
[SerializeField]
|
||||
protected bool isLockWithRatio = true;
|
||||
public bool IsLockWithRatio
|
||||
{
|
||||
get
|
||||
{
|
||||
return isLockWithRatio;
|
||||
}
|
||||
}
|
||||
|
||||
[Tooltip("Pick a higher resolution to improve the quality of the curved graphic.")]
|
||||
[SerializeField]
|
||||
[Range(0.01f, 30.0f)]
|
||||
protected float resolution = 5.0f;
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Reference to other objects that are needed by this object.
|
||||
/// </summary>
|
||||
#region Links
|
||||
|
||||
protected RectTransform rectTrans;
|
||||
public RectTransform RectTrans
|
||||
{
|
||||
get
|
||||
{
|
||||
return rectTrans;
|
||||
}
|
||||
}
|
||||
|
||||
[Tooltip("Put in the Graphic you want to curve/morph here.")]
|
||||
[SerializeField]
|
||||
protected Graphic uiGraphic;
|
||||
public Graphic UIGraphic
|
||||
{
|
||||
get
|
||||
{
|
||||
return uiGraphic;
|
||||
}
|
||||
}
|
||||
[Tooltip("Put in the reference Graphic that will be used to tune the bezier curves. Think button image and text.")]
|
||||
[SerializeField]
|
||||
protected CUIGraphic refCUIGraphic;
|
||||
public CUIGraphic RefCUIGraphic
|
||||
{
|
||||
get
|
||||
{
|
||||
return refCUIGraphic;
|
||||
}
|
||||
}
|
||||
|
||||
[Tooltip("Do not touch this unless you are sure what you are doing. The curves are (re)generated automatically.")]
|
||||
[SerializeField]
|
||||
protected CUIBezierCurve[] refCurves;
|
||||
public CUIBezierCurve[] RefCurves
|
||||
{
|
||||
get
|
||||
{
|
||||
return refCurves;
|
||||
}
|
||||
}
|
||||
|
||||
[HideInInspector]
|
||||
[SerializeField]
|
||||
protected Vector3_Array2D[] refCurvesControlRatioPoints;
|
||||
public Vector3_Array2D[] RefCurvesControlRatioPoints
|
||||
{
|
||||
get
|
||||
{
|
||||
return refCurvesControlRatioPoints;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public CUIBezierCurve[] EDITOR_RefCurves
|
||||
{
|
||||
set
|
||||
{
|
||||
refCurves = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3_Array2D[] EDITOR_RefCurvesControlRatioPoints
|
||||
{
|
||||
set
|
||||
{
|
||||
refCurvesControlRatioPoints = value;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
// Methods that are used often.
|
||||
#region Reuse
|
||||
|
||||
protected List<UIVertex> reuse_quads = new List<UIVertex>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Action
|
||||
|
||||
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)
|
||||
{
|
||||
Vector3 f;
|
||||
float g;
|
||||
|
||||
if (Mathf.Abs(_x_1) > Mathf.Abs(_x_2))
|
||||
{
|
||||
f = _constant_1 * _x_2 / _x_1;
|
||||
g = _y_1 * _x_2 / _x_1;
|
||||
_y = (_contant_2 - f) / (_y_2 - g);
|
||||
if (_x_2 != 0)
|
||||
_x = (f - g * _y) / _x_2;
|
||||
else
|
||||
_x = (_constant_1 - _y_1 * _y) / _x_1;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = _contant_2 * _x_1 / _x_2;
|
||||
g = _y_2 * _x_1 / _x_2;
|
||||
_x = (_constant_1 - f) / (_y_1 - g);
|
||||
if (_x_1 != 0)
|
||||
_y = (f - g * _x) / _x_1;
|
||||
else
|
||||
_y = (_contant_2 - _y_2 * _x) / _x_2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected UIVertex uiVertexLerp(UIVertex _a, UIVertex _b, float _time)
|
||||
{
|
||||
UIVertex tmpUIVertex = new UIVertex();
|
||||
|
||||
tmpUIVertex.position = Vector3.Lerp(_a.position, _b.position, _time);
|
||||
tmpUIVertex.normal = Vector3.Lerp(_a.normal, _b.normal, _time);
|
||||
tmpUIVertex.tangent = Vector3.Lerp(_a.tangent, _b.tangent, _time);
|
||||
tmpUIVertex.uv0 = Vector2.Lerp(_a.uv0, _b.uv0, _time);
|
||||
tmpUIVertex.uv1 = Vector2.Lerp(_a.uv1, _b.uv1, _time);
|
||||
tmpUIVertex.color = Color.Lerp(_a.color, _b.color, _time);
|
||||
|
||||
return tmpUIVertex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Bilinear Interpolation
|
||||
/// </summary>
|
||||
protected UIVertex uiVertexBerp(UIVertex v_bottomLeft, UIVertex v_topLeft, UIVertex v_topRight, UIVertex v_bottomRight, float _xTime, float _yTime)
|
||||
{
|
||||
UIVertex topX = uiVertexLerp(v_topLeft, v_topRight, _xTime);
|
||||
UIVertex bottomX = uiVertexLerp(v_bottomLeft, v_bottomRight, _xTime);
|
||||
return uiVertexLerp(bottomX, topX, _yTime);
|
||||
}
|
||||
|
||||
protected void tessellateQuad(List<UIVertex> _quads, int _thisQuadIdx)
|
||||
{
|
||||
UIVertex v_bottomLeft = _quads[_thisQuadIdx];
|
||||
UIVertex v_topLeft = _quads[_thisQuadIdx + 1];
|
||||
UIVertex v_topRight = _quads[_thisQuadIdx + 2];
|
||||
UIVertex v_bottomRight = _quads[_thisQuadIdx + 3];
|
||||
|
||||
float quadSize = 100.0f / resolution;
|
||||
|
||||
int heightQuadEdgeNum = Mathf.Max(1, Mathf.CeilToInt((v_topLeft.position - v_bottomLeft.position).magnitude / quadSize));
|
||||
int widthQuadEdgeNum = Mathf.Max(1, Mathf.CeilToInt((v_topRight.position - v_topLeft.position).magnitude / quadSize));
|
||||
|
||||
int quadIdx = 0;
|
||||
|
||||
for (int x = 0; x < widthQuadEdgeNum; x++)
|
||||
{
|
||||
for (int y = 0; y < heightQuadEdgeNum; y++, quadIdx++)
|
||||
{
|
||||
_quads.Add(new UIVertex());
|
||||
_quads.Add(new UIVertex());
|
||||
_quads.Add(new UIVertex());
|
||||
_quads.Add(new UIVertex());
|
||||
|
||||
float xRatio = (float)x / widthQuadEdgeNum;
|
||||
float yRatio = (float)y / heightQuadEdgeNum;
|
||||
float xPlusOneRatio = (float)(x + 1) / widthQuadEdgeNum;
|
||||
float yPlusOneRatio = (float)(y + 1) / heightQuadEdgeNum;
|
||||
|
||||
_quads[_quads.Count - 4] = uiVertexBerp(v_bottomLeft, v_topLeft, v_topRight, v_bottomRight, xRatio, yRatio);
|
||||
_quads[_quads.Count - 3] = uiVertexBerp(v_bottomLeft, v_topLeft, v_topRight, v_bottomRight, xRatio, yPlusOneRatio);
|
||||
_quads[_quads.Count - 2] = uiVertexBerp(v_bottomLeft, v_topLeft, v_topRight, v_bottomRight, xPlusOneRatio, yPlusOneRatio);
|
||||
_quads[_quads.Count - 1] = uiVertexBerp(v_bottomLeft, v_topLeft, v_topRight, v_bottomRight, xPlusOneRatio, yRatio);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void tessellateGraphic(List<UIVertex> _verts)
|
||||
{
|
||||
for (int v = 0; v < _verts.Count; v += 6)
|
||||
{
|
||||
reuse_quads.Add(_verts[v]); // bottom left
|
||||
reuse_quads.Add(_verts[v + 1]); // top left
|
||||
reuse_quads.Add(_verts[v + 2]); // top right
|
||||
// verts[3] is redundant, top right
|
||||
reuse_quads.Add(_verts[v + 4]); // bottom right
|
||||
// verts[5] is redundant, bottom left
|
||||
}
|
||||
|
||||
int oriQuadNum = reuse_quads.Count / 4;
|
||||
for (int q = 0; q < oriQuadNum; q++)
|
||||
{
|
||||
tessellateQuad(reuse_quads, q * 4);
|
||||
}
|
||||
|
||||
// remove original quads
|
||||
reuse_quads.RemoveRange(0, oriQuadNum * 4);
|
||||
|
||||
_verts.Clear();
|
||||
|
||||
// process new quads and turn them into triangles
|
||||
for (int q = 0; q < reuse_quads.Count; q += 4)
|
||||
{
|
||||
_verts.Add(reuse_quads[q]);
|
||||
_verts.Add(reuse_quads[q + 1]);
|
||||
_verts.Add(reuse_quads[q + 2]);
|
||||
_verts.Add(reuse_quads[q + 2]);
|
||||
_verts.Add(reuse_quads[q + 3]);
|
||||
_verts.Add(reuse_quads[q]);
|
||||
}
|
||||
|
||||
reuse_quads.Clear();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// Events are for handling reoccurring function calls that react to the changes of the environment.
|
||||
#region Events
|
||||
|
||||
protected override void OnRectTransformDimensionsChange()
|
||||
{
|
||||
if (isLockWithRatio)
|
||||
{
|
||||
UpdateCurveControlPointPositions();
|
||||
}
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
ReportSet();
|
||||
|
||||
// we use local position as the true value. Ratio position follows it, so it should be updated when refresh
|
||||
|
||||
for (int c = 0; c < refCurves.Length; c++)
|
||||
{
|
||||
|
||||
CUIBezierCurve curve = refCurves[c];
|
||||
|
||||
if (curve.ControlPoints != null)
|
||||
{
|
||||
|
||||
Vector3[] controlPoints = curve.ControlPoints;
|
||||
|
||||
for (int p = 0; p < CUIBezierCurve.CubicBezierCurvePtNum; p++)
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
Undo.RecordObject(this, "Move Point");
|
||||
#endif
|
||||
|
||||
Vector3 ratioPoint = controlPoints[p];
|
||||
|
||||
ratioPoint.x = (ratioPoint.x + rectTrans.rect.width * rectTrans.pivot.x) / rectTrans.rect.width;
|
||||
ratioPoint.y = (ratioPoint.y + rectTrans.rect.height * rectTrans.pivot.y) / rectTrans.rect.height;
|
||||
|
||||
refCurvesControlRatioPoints[c][p] = ratioPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//uiText.SetAllDirty();
|
||||
// need this to refresh the UI text, SetAllDirty does not seem to work for all cases
|
||||
if (uiGraphic != null)
|
||||
{
|
||||
uiGraphic.enabled = false;
|
||||
uiGraphic.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// Methods that change the behaviour of the object.
|
||||
#region Flash-Phase
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
OnRectTransformDimensionsChange();
|
||||
|
||||
}
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
OnRectTransformDimensionsChange();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Configurations
|
||||
|
||||
/// <summary>
|
||||
/// Check, prepare and set everything needed.
|
||||
/// </summary>
|
||||
public virtual void ReportSet()
|
||||
{
|
||||
|
||||
if (rectTrans == null)
|
||||
rectTrans = GetComponent<RectTransform>();
|
||||
|
||||
if (refCurves == null)
|
||||
refCurves = new CUIBezierCurve[2];
|
||||
|
||||
bool isCurvesReady = true;
|
||||
|
||||
for (int c = 0; c < 2; c++)
|
||||
{
|
||||
isCurvesReady = isCurvesReady & refCurves[c] != null;
|
||||
}
|
||||
|
||||
isCurvesReady = isCurvesReady & refCurves.Length == 2;
|
||||
|
||||
if (!isCurvesReady)
|
||||
{
|
||||
CUIBezierCurve[] curves = refCurves;
|
||||
|
||||
for (int c = 0; c < 2; c++)
|
||||
{
|
||||
if (refCurves[c] == null)
|
||||
{
|
||||
GameObject go = new GameObject();
|
||||
go.transform.SetParent(transform);
|
||||
go.transform.localPosition = Vector3.zero;
|
||||
go.transform.localEulerAngles = Vector3.zero;
|
||||
|
||||
if (c == 0)
|
||||
{
|
||||
go.name = "BottomRefCurve";
|
||||
}
|
||||
else
|
||||
{
|
||||
go.name = "TopRefCurve";
|
||||
}
|
||||
|
||||
curves[c] = go.AddComponent<CUIBezierCurve>();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
curves[c] = refCurves[c];
|
||||
}
|
||||
curves[c].ReportSet();
|
||||
}
|
||||
|
||||
refCurves = curves;
|
||||
}
|
||||
|
||||
if (refCurvesControlRatioPoints == null)
|
||||
{
|
||||
refCurvesControlRatioPoints = new Vector3_Array2D[refCurves.Length];
|
||||
|
||||
for (int c = 0; c < refCurves.Length; c++)
|
||||
{
|
||||
{
|
||||
refCurvesControlRatioPoints[c].array = new Vector3[refCurves[c].ControlPoints.Length];
|
||||
}
|
||||
}
|
||||
|
||||
FixTextToRectTrans();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
for (int c = 0; c < 2; c++)
|
||||
{
|
||||
refCurves[c].OnRefresh = Refresh;
|
||||
}
|
||||
}
|
||||
|
||||
public void FixTextToRectTrans()
|
||||
{
|
||||
for (int c = 0; c < refCurves.Length; c++)
|
||||
{
|
||||
CUIBezierCurve curve = refCurves[c];
|
||||
|
||||
for (int p = 0; p < CUIBezierCurve.CubicBezierCurvePtNum; p++)
|
||||
{
|
||||
if (curve.ControlPoints != null)
|
||||
{
|
||||
Vector3[] controlPoints = curve.ControlPoints;
|
||||
|
||||
if (c == 0)
|
||||
{
|
||||
controlPoints[p].y = -rectTrans.rect.height * rectTrans.pivot.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
controlPoints[p].y = rectTrans.rect.height - rectTrans.rect.height * rectTrans.pivot.y;
|
||||
}
|
||||
|
||||
controlPoints[p].x = rectTrans.rect.width * p / (CUIBezierCurve.CubicBezierCurvePtNum - 1);
|
||||
controlPoints[p].x -= rectTrans.rect.width * rectTrans.pivot.x;
|
||||
|
||||
controlPoints[p].z = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ReferenceCUIForBCurves()
|
||||
{
|
||||
// compute the position ratio of this rect transform in perspective of reference rect transform
|
||||
|
||||
Vector3 posDeltaBetweenBottomLeftCorner = rectTrans.localPosition;// Difference between pivot
|
||||
|
||||
posDeltaBetweenBottomLeftCorner.x += -rectTrans.rect.width * rectTrans.pivot.x + (refCUIGraphic.rectTrans.rect.width * refCUIGraphic.rectTrans.pivot.x);
|
||||
posDeltaBetweenBottomLeftCorner.y += -rectTrans.rect.height * rectTrans.pivot.y + (refCUIGraphic.rectTrans.rect.height * refCUIGraphic.rectTrans.pivot.y);
|
||||
//posDeltaBetweenBottomLeftCorner.z = rectTrans.localPosition.z;
|
||||
|
||||
Vector3 bottomLeftPosRatio = new Vector3(posDeltaBetweenBottomLeftCorner.x / refCUIGraphic.RectTrans.rect.width, posDeltaBetweenBottomLeftCorner.y / refCUIGraphic.RectTrans.rect.height, posDeltaBetweenBottomLeftCorner.z);
|
||||
Vector3 topRightPosRatio = new Vector3((posDeltaBetweenBottomLeftCorner.x + rectTrans.rect.width) / refCUIGraphic.RectTrans.rect.width, (posDeltaBetweenBottomLeftCorner.y + rectTrans.rect.height) / refCUIGraphic.RectTrans.rect.height, posDeltaBetweenBottomLeftCorner.z);
|
||||
|
||||
refCurves[0].ControlPoints[0] = refCUIGraphic.GetBCurveSandwichSpacePoint(bottomLeftPosRatio.x, bottomLeftPosRatio.y) - rectTrans.localPosition;
|
||||
refCurves[0].ControlPoints[3] = refCUIGraphic.GetBCurveSandwichSpacePoint(topRightPosRatio.x, bottomLeftPosRatio.y) - rectTrans.localPosition;
|
||||
|
||||
refCurves[1].ControlPoints[0] = refCUIGraphic.GetBCurveSandwichSpacePoint(bottomLeftPosRatio.x, topRightPosRatio.y) - rectTrans.localPosition;
|
||||
refCurves[1].ControlPoints[3] = refCUIGraphic.GetBCurveSandwichSpacePoint(topRightPosRatio.x, topRightPosRatio.y) - rectTrans.localPosition;
|
||||
|
||||
// use two sample points from the reference curves to find the second and third controls points for this curves
|
||||
for (int c = 0; c < refCurves.Length; c++)
|
||||
{
|
||||
CUIBezierCurve curve = refCurves[c];
|
||||
|
||||
float yTime = c == 0 ? bottomLeftPosRatio.y : topRightPosRatio.y;
|
||||
|
||||
Vector3 leftPoint = refCUIGraphic.GetBCurveSandwichSpacePoint(bottomLeftPosRatio.x, yTime);
|
||||
Vector3 rightPoint = refCUIGraphic.GetBCurveSandwichSpacePoint(topRightPosRatio.x, yTime);
|
||||
|
||||
float quarter = 0.25f,
|
||||
threeQuarter = 0.75f;
|
||||
|
||||
Vector3 quarterPoint = refCUIGraphic.GetBCurveSandwichSpacePoint((bottomLeftPosRatio.x * 0.75f + topRightPosRatio.x * 0.25f) / 1.0f, yTime);
|
||||
Vector3 threeQuaterPoint = refCUIGraphic.GetBCurveSandwichSpacePoint((bottomLeftPosRatio.x * 0.25f + topRightPosRatio.x * 0.75f) / 1.0f, yTime);
|
||||
|
||||
float x_1 = 3 * threeQuarter * threeQuarter * quarter, // (1 - t)(1 - t)t
|
||||
y_1 = 3 * threeQuarter * quarter * quarter,
|
||||
x_2 = 3 * quarter * quarter * threeQuarter,
|
||||
y_2 = 3 * quarter * threeQuarter * threeQuarter;
|
||||
|
||||
Vector3 contant_1 = quarterPoint - Mathf.Pow(threeQuarter, 3) * leftPoint - Mathf.Pow(quarter, 3) * rightPoint,
|
||||
contant_2 = threeQuaterPoint - Mathf.Pow(quarter, 3) * leftPoint - Mathf.Pow(threeQuarter, 3) * rightPoint,
|
||||
p1,
|
||||
p2;
|
||||
|
||||
solveDoubleEquationWithVector(x_1, y_1, x_2, y_2, contant_1, contant_2, out p1, out p2);
|
||||
|
||||
curve.ControlPoints[1] = p1 - rectTrans.localPosition;
|
||||
curve.ControlPoints[2] = p2 - rectTrans.localPosition;
|
||||
|
||||
}
|
||||
// use tangent and start and end time to derive control point 2 and 3
|
||||
}
|
||||
|
||||
public override void ModifyMesh(Mesh _mesh)
|
||||
{
|
||||
|
||||
if (!IsActive())
|
||||
return;
|
||||
|
||||
using (VertexHelper vh = new VertexHelper(_mesh))
|
||||
{
|
||||
ModifyMesh(vh);
|
||||
vh.FillMesh(_mesh);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void ModifyMesh(VertexHelper _vh)
|
||||
{
|
||||
|
||||
if (!IsActive())
|
||||
return;
|
||||
|
||||
List<UIVertex> vertexList = new List<UIVertex>();
|
||||
_vh.GetUIVertexStream(vertexList);
|
||||
|
||||
modifyVertices(vertexList);
|
||||
|
||||
_vh.Clear();
|
||||
_vh.AddUIVertexTriangleStream(vertexList);
|
||||
}
|
||||
|
||||
protected virtual void modifyVertices(List<UIVertex> _verts)
|
||||
{
|
||||
if (!IsActive())
|
||||
return;
|
||||
|
||||
tessellateGraphic(_verts);
|
||||
|
||||
if (!isCurved)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int index = 0; index < _verts.Count; index++)
|
||||
{
|
||||
var uiVertex = _verts[index];
|
||||
|
||||
// finding the horizontal ratio position (0.0 - 1.0) of a vertex
|
||||
float horRatio = (uiVertex.position.x + rectTrans.rect.width * rectTrans.pivot.x) / rectTrans.rect.width;
|
||||
float verRatio = (uiVertex.position.y + rectTrans.rect.height * rectTrans.pivot.y) / rectTrans.rect.height;
|
||||
|
||||
//Vector3 pos = Vector3.Lerp(refCurves[0].GetPoint(horRatio), refCurves[1].GetPoint(horRatio), verRatio);
|
||||
Vector3 pos = GetBCurveSandwichSpacePoint(horRatio, verRatio);
|
||||
|
||||
uiVertex.position.x = pos.x;
|
||||
uiVertex.position.y = pos.y;
|
||||
uiVertex.position.z = pos.z;
|
||||
|
||||
_verts[index] = uiVertex;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateCurveControlPointPositions()
|
||||
{
|
||||
ReportSet();
|
||||
|
||||
for (int c = 0; c < refCurves.Length; c++)
|
||||
{
|
||||
CUIBezierCurve curve = refCurves[c];
|
||||
|
||||
#if UNITY_EDITOR
|
||||
Undo.RecordObject(curve, "Move Rect");
|
||||
#endif
|
||||
|
||||
for (int p = 0; p < refCurves[c].ControlPoints.Length; p++)
|
||||
{
|
||||
|
||||
Vector3 newPt = refCurvesControlRatioPoints[c][p];
|
||||
|
||||
newPt.x = newPt.x * rectTrans.rect.width - rectTrans.rect.width * rectTrans.pivot.x;
|
||||
newPt.y = newPt.y * rectTrans.rect.height - rectTrans.rect.height * rectTrans.pivot.y;
|
||||
|
||||
curve.ControlPoints[p] = newPt;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// Methods that serves other objects
|
||||
#region Services
|
||||
|
||||
public Vector3 GetBCurveSandwichSpacePoint(float _xTime, float _yTime)
|
||||
{
|
||||
//return Vector3.Lerp(refCurves[0].GetPoint(_xTime), refCurves[1].GetPoint(_xTime), _yTime);
|
||||
return refCurves[0].GetPoint(_xTime) * (1 - _yTime) + refCurves[1].GetPoint(_xTime) * _yTime; // use a custom made lerp so that the value is not clamped between 0 and 1
|
||||
}
|
||||
|
||||
public Vector3 GetBCurveSandwichSpaceTangent(float _xTime, float _yTime)
|
||||
{
|
||||
return refCurves[0].GetTangent(_xTime) * (1 - _yTime) + refCurves[1].GetTangent(_xTime) * _yTime;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e011f2cb554f96547bbfc22e5f001c17
|
||||
timeCreated: 1485600090
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,165 @@
|
||||
/// Credit Titinious (https://github.com/Titinious)
|
||||
/// Sourced from - https://github.com/Titinious/CurlyUI
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[RequireComponent(typeof(Image))]
|
||||
[AddComponentMenu("UI/Effects/Extensions/Curly UI Image")]
|
||||
public class CUIImage : CUIGraphic
|
||||
{
|
||||
#region Nature
|
||||
|
||||
public static int SlicedImageCornerRefVertexIdx = 2;
|
||||
public static int FilledImageCornerRefVertexIdx = 0;
|
||||
|
||||
/// <summary>
|
||||
/// For sliced and filled image only.
|
||||
/// </summary>
|
||||
/// <param name="_type"></param>
|
||||
/// <returns></returns>
|
||||
public static int ImageTypeCornerRefVertexIdx(Image.Type _type)
|
||||
{
|
||||
if (_type == Image.Type.Sliced)
|
||||
{
|
||||
return SlicedImageCornerRefVertexIdx;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FilledImageCornerRefVertexIdx;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Description
|
||||
|
||||
[Tooltip("For changing the size of the corner for tiled or sliced Image")]
|
||||
[HideInInspector]
|
||||
[SerializeField]
|
||||
public Vector2 cornerPosRatio = Vector2.one * -1; // -1 means unset value
|
||||
|
||||
[HideInInspector]
|
||||
[SerializeField]
|
||||
protected Vector2 oriCornerPosRatio = Vector2.one * -1;
|
||||
public Vector2 OriCornerPosRatio
|
||||
{
|
||||
get
|
||||
{
|
||||
return oriCornerPosRatio;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Image UIImage
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Image)uiGraphic;
|
||||
}
|
||||
}
|
||||
|
||||
#region Configurations
|
||||
|
||||
public override void ReportSet()
|
||||
{
|
||||
|
||||
if (uiGraphic == null)
|
||||
uiGraphic = GetComponent<Image>();
|
||||
|
||||
base.ReportSet();
|
||||
}
|
||||
|
||||
protected override void modifyVertices(List<UIVertex> _verts)
|
||||
{
|
||||
if (!IsActive())
|
||||
return;
|
||||
|
||||
if (UIImage.type == Image.Type.Filled)
|
||||
{
|
||||
Debug.LogWarning("Might not work well Radial Filled at the moment!");
|
||||
|
||||
}
|
||||
else if (UIImage.type == Image.Type.Sliced || UIImage.type == Image.Type.Tiled)
|
||||
{
|
||||
// setting the starting cornerRatio
|
||||
if (cornerPosRatio == Vector2.one * -1)
|
||||
{
|
||||
cornerPosRatio = _verts[ImageTypeCornerRefVertexIdx(UIImage.type)].position;
|
||||
cornerPosRatio.x = (cornerPosRatio.x + rectTrans.pivot.x * rectTrans.rect.width) / rectTrans.rect.width;
|
||||
cornerPosRatio.y = (cornerPosRatio.y + rectTrans.pivot.y * rectTrans.rect.height) / rectTrans.rect.height;
|
||||
|
||||
oriCornerPosRatio = cornerPosRatio;
|
||||
|
||||
}
|
||||
|
||||
// constraining the corner ratio
|
||||
if (cornerPosRatio.x < 0)
|
||||
{
|
||||
cornerPosRatio.x = 0;
|
||||
}
|
||||
if (cornerPosRatio.x >= 0.5f)
|
||||
{
|
||||
cornerPosRatio.x = 0.5f;
|
||||
}
|
||||
if (cornerPosRatio.y < 0)
|
||||
{
|
||||
cornerPosRatio.y = 0;
|
||||
}
|
||||
if (cornerPosRatio.y >= 0.5f)
|
||||
{
|
||||
cornerPosRatio.y = 0.5f;
|
||||
}
|
||||
|
||||
for (int index = 0; index < _verts.Count; index++)
|
||||
{
|
||||
var uiVertex = _verts[index];
|
||||
|
||||
// finding the horizontal ratio position (0.0 - 1.0) of a vertex
|
||||
float horRatio = (uiVertex.position.x + rectTrans.rect.width * rectTrans.pivot.x) / rectTrans.rect.width;
|
||||
float verRatio = (uiVertex.position.y + rectTrans.rect.height * rectTrans.pivot.y) / rectTrans.rect.height;
|
||||
|
||||
if (horRatio < oriCornerPosRatio.x)
|
||||
{
|
||||
horRatio = Mathf.Lerp(0, cornerPosRatio.x, horRatio / oriCornerPosRatio.x);
|
||||
}
|
||||
else if (horRatio > 1 - oriCornerPosRatio.x)
|
||||
{
|
||||
horRatio = Mathf.Lerp(1 - cornerPosRatio.x, 1, (horRatio - (1 - oriCornerPosRatio.x)) / oriCornerPosRatio.x);
|
||||
}
|
||||
else
|
||||
{
|
||||
horRatio = Mathf.Lerp(cornerPosRatio.x, 1 - cornerPosRatio.x, (horRatio - oriCornerPosRatio.x) / (1 - oriCornerPosRatio.x * 2));
|
||||
}
|
||||
|
||||
if (verRatio < oriCornerPosRatio.y)
|
||||
{
|
||||
verRatio = Mathf.Lerp(0, cornerPosRatio.y, verRatio / oriCornerPosRatio.y);
|
||||
}
|
||||
else if (verRatio > 1 - oriCornerPosRatio.y)
|
||||
{
|
||||
verRatio = Mathf.Lerp(1 - cornerPosRatio.y, 1, (verRatio - (1 - oriCornerPosRatio.y)) / oriCornerPosRatio.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
verRatio = Mathf.Lerp(cornerPosRatio.y, 1 - cornerPosRatio.y, (verRatio - oriCornerPosRatio.y) / (1 - oriCornerPosRatio.y * 2));
|
||||
}
|
||||
|
||||
uiVertex.position.x = horRatio * rectTrans.rect.width - rectTrans.rect.width * rectTrans.pivot.x;
|
||||
uiVertex.position.y = verRatio * rectTrans.rect.height - rectTrans.rect.height * rectTrans.pivot.y;
|
||||
//uiVertex.position.z = pos.z;
|
||||
|
||||
_verts[index] = uiVertex;
|
||||
}
|
||||
}
|
||||
|
||||
base.modifyVertices(_verts);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ab7726a352b5004cbf5f8e153868637
|
||||
timeCreated: 1485600090
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,24 @@
|
||||
/// Credit Titinious (https://github.com/Titinious)
|
||||
/// Sourced from - https://github.com/Titinious/CurlyUI
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[System.Serializable]
|
||||
public struct Vector3_Array2D
|
||||
{
|
||||
[SerializeField]
|
||||
public Vector3[] array;
|
||||
|
||||
public Vector3 this[int _idx]
|
||||
{
|
||||
get
|
||||
{
|
||||
return array[_idx];
|
||||
}
|
||||
set
|
||||
{
|
||||
array[_idx] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2e82bd2b2afc435438d5d8d7d3459dd0
|
||||
timeCreated: 1485704814
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,19 @@
|
||||
/// Credit Titinious (https://github.com/Titinious)
|
||||
/// Sourced from - https://github.com/Titinious/CurlyUI
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[RequireComponent(typeof(Text))]
|
||||
[AddComponentMenu("UI/Effects/Extensions/Curly UI Text")]
|
||||
public class CUIText : CUIGraphic
|
||||
{
|
||||
public override void ReportSet()
|
||||
{
|
||||
if (uiGraphic == null)
|
||||
uiGraphic = GetComponent<Text>();
|
||||
|
||||
base.ReportSet();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64c40f35eca5d5d4da4eefac2a627005
|
||||
timeCreated: 1485600090
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user