mirror of
https://github.com/RHeavenStudio/HeavenStudio.git
synced 2025-06-12 15:17:36 +02:00
Editor stuff
This commit is contained in:
@ -0,0 +1,62 @@
|
||||
/// Credit Melang
|
||||
/// Sourced from - http://forum.unity3d.com/members/melang.593409/
|
||||
|
||||
using System.Collections.Generic;
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/BestFit Outline")]
|
||||
public class BestFitOutline : Shadow
|
||||
{
|
||||
//
|
||||
// Constructors
|
||||
//
|
||||
protected BestFitOutline ()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// Methods
|
||||
//
|
||||
public override void ModifyMesh (Mesh mesh)
|
||||
{
|
||||
if (!this.IsActive ())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<UIVertex> verts = new List<UIVertex>();
|
||||
using (var helper = new VertexHelper(mesh))
|
||||
{
|
||||
helper.GetUIVertexStream(verts);
|
||||
}
|
||||
|
||||
Text foundtext = GetComponent<Text>();
|
||||
|
||||
float best_fit_adjustment = 1f;
|
||||
|
||||
if (foundtext && foundtext.resizeTextForBestFit)
|
||||
{
|
||||
best_fit_adjustment = (float)foundtext.cachedTextGenerator.fontSizeUsedForBestFit / (foundtext.resizeTextMaxSize-1); //max size seems to be exclusive
|
||||
}
|
||||
|
||||
int start = 0;
|
||||
int count = verts.Count;
|
||||
base.ApplyShadowZeroAlloc(verts, base.effectColor, start, verts.Count, base.effectDistance.x*best_fit_adjustment, base.effectDistance.y*best_fit_adjustment);
|
||||
start = count;
|
||||
count = verts.Count;
|
||||
base.ApplyShadowZeroAlloc(verts, base.effectColor, start, verts.Count, base.effectDistance.x*best_fit_adjustment, -base.effectDistance.y*best_fit_adjustment);
|
||||
start = count;
|
||||
count = verts.Count;
|
||||
base.ApplyShadowZeroAlloc(verts, base.effectColor, start, verts.Count, -base.effectDistance.x*best_fit_adjustment, base.effectDistance.y*best_fit_adjustment);
|
||||
start = count;
|
||||
count = verts.Count;
|
||||
base.ApplyShadowZeroAlloc(verts, base.effectColor, start, verts.Count, -base.effectDistance.x*best_fit_adjustment, -base.effectDistance.y*best_fit_adjustment);
|
||||
|
||||
using (var helper = new VertexHelper())
|
||||
{
|
||||
helper.AddUIVertexTriangleStream(verts);
|
||||
helper.FillMesh(mesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b30dd83a12669d4f973ff5a79ca9842
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e8f8c7784bd14f146a01bb324949f7cb
|
||||
folderAsset: yes
|
||||
timeCreated: 1501406849
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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:
|
@ -0,0 +1,84 @@
|
||||
/// Credit Breyer
|
||||
/// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1777407
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(Text), typeof(RectTransform))]
|
||||
[AddComponentMenu("UI/Effects/Extensions/Curved Text")]
|
||||
public class CurvedText : BaseMeshEffect
|
||||
{
|
||||
[SerializeField]
|
||||
private AnimationCurve _curveForText = AnimationCurve.Linear(0, 0, 1, 10);
|
||||
|
||||
public AnimationCurve CurveForText
|
||||
{
|
||||
get { return _curveForText; }
|
||||
set { _curveForText = value; graphic.SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private float _curveMultiplier = 1;
|
||||
|
||||
public float CurveMultiplier
|
||||
{
|
||||
get { return _curveMultiplier; }
|
||||
set { _curveMultiplier = value; graphic.SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
private RectTransform rectTrans;
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate()
|
||||
{
|
||||
base.OnValidate();
|
||||
if (_curveForText[0].time != 0)
|
||||
{
|
||||
var tmpRect = _curveForText[0];
|
||||
tmpRect.time = 0;
|
||||
_curveForText.MoveKey(0, tmpRect);
|
||||
}
|
||||
if (rectTrans == null)
|
||||
rectTrans = GetComponent<RectTransform>();
|
||||
if (_curveForText[_curveForText.length - 1].time != rectTrans.rect.width)
|
||||
OnRectTransformDimensionsChange();
|
||||
}
|
||||
#endif
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
rectTrans = GetComponent<RectTransform>();
|
||||
OnRectTransformDimensionsChange();
|
||||
}
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
rectTrans = GetComponent<RectTransform>();
|
||||
OnRectTransformDimensionsChange();
|
||||
}
|
||||
public override void ModifyMesh(VertexHelper vh)
|
||||
{
|
||||
int count = vh.currentVertCount;
|
||||
if (!IsActive() || count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < vh.currentVertCount; index++)
|
||||
{
|
||||
UIVertex uiVertex = new UIVertex();
|
||||
vh.PopulateUIVertex(ref uiVertex, index);
|
||||
uiVertex.position.y += _curveForText.Evaluate(rectTrans.rect.width * rectTrans.pivot.x + uiVertex.position.x) * _curveMultiplier;
|
||||
vh.SetUIVertex(uiVertex, index);
|
||||
}
|
||||
}
|
||||
protected override void OnRectTransformDimensionsChange()
|
||||
{
|
||||
if (rectTrans)
|
||||
{
|
||||
Keyframe tmpRect = _curveForText[_curveForText.length - 1];
|
||||
tmpRect.time = rectTrans.rect.width;
|
||||
_curveForText.MoveKey(_curveForText.length - 1, tmpRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c38666cb4d43a304588cf0b7e5f86db6
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,54 @@
|
||||
/// adaption for cylindrical bending by herbst
|
||||
/// Credit Breyer
|
||||
/// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1777407
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(Text), typeof(RectTransform))]
|
||||
[AddComponentMenu("UI/Effects/Extensions/Cylinder Text")]
|
||||
public class CylinderText : BaseMeshEffect
|
||||
{
|
||||
public float radius;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate()
|
||||
{
|
||||
base.OnValidate();
|
||||
}
|
||||
#endif
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
OnRectTransformDimensionsChange();
|
||||
}
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
OnRectTransformDimensionsChange();
|
||||
}
|
||||
public override void ModifyMesh(VertexHelper vh)
|
||||
{
|
||||
if (! IsActive()) return;
|
||||
|
||||
int count = vh.currentVertCount;
|
||||
if (!IsActive() || count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < vh.currentVertCount; index++)
|
||||
{
|
||||
UIVertex uiVertex = new UIVertex();
|
||||
vh.PopulateUIVertex(ref uiVertex, index);
|
||||
|
||||
// get x position
|
||||
var x = uiVertex.position.x;
|
||||
|
||||
// calculate bend based on pivot and radius
|
||||
uiVertex.position.z = -radius * Mathf.Cos(x / radius);
|
||||
uiVertex.position.x = radius * Mathf.Sin(x / radius);
|
||||
|
||||
vh.SetUIVertex(uiVertex, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ec526a95e7733b4396be80d3e1df80e
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,119 @@
|
||||
/// Credit Breyer
|
||||
/// Sourced from - http://forum.unity3d.com/threads/scripts-useful-4-6-scripts-collection.264161/#post-1780095
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/Gradient")]
|
||||
public class Gradient : BaseMeshEffect
|
||||
{
|
||||
[SerializeField]
|
||||
private GradientMode _gradientMode = GradientMode.Global;
|
||||
[SerializeField]
|
||||
private GradientDir _gradientDir = GradientDir.Vertical;
|
||||
[SerializeField]
|
||||
private bool _overwriteAllColor = false;
|
||||
[SerializeField]
|
||||
private Color _vertex1 = Color.white;
|
||||
[SerializeField]
|
||||
private Color _vertex2 = Color.black;
|
||||
private Graphic targetGraphic;
|
||||
|
||||
#region Properties
|
||||
public GradientMode GradientMode { get { return _gradientMode; } set { _gradientMode = value; graphic.SetVerticesDirty(); } }
|
||||
public GradientDir GradientDir { get { return _gradientDir; } set { _gradientDir = value; graphic.SetVerticesDirty(); } }
|
||||
public bool OverwriteAllColor { get { return _overwriteAllColor; } set { _overwriteAllColor = value; graphic.SetVerticesDirty(); } }
|
||||
public Color Vertex1 { get { return _vertex1; } set { _vertex1 = value; graphic.SetAllDirty(); } }
|
||||
public Color Vertex2 { get { return _vertex2; } set { _vertex2 = value; graphic.SetAllDirty(); } }
|
||||
#endregion
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
targetGraphic = GetComponent<Graphic>();
|
||||
}
|
||||
|
||||
public override void ModifyMesh(VertexHelper vh)
|
||||
{
|
||||
int count = vh.currentVertCount;
|
||||
if (!IsActive() || count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var vertexList = new List<UIVertex>();
|
||||
vh.GetUIVertexStream(vertexList);
|
||||
UIVertex uiVertex = new UIVertex();
|
||||
if (_gradientMode == GradientMode.Global)
|
||||
{
|
||||
if (_gradientDir == GradientDir.DiagonalLeftToRight || _gradientDir == GradientDir.DiagonalRightToLeft)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
Debug.LogWarning("Diagonal dir is not supported in Global mode");
|
||||
#endif
|
||||
_gradientDir = GradientDir.Vertical;
|
||||
}
|
||||
float bottomY = _gradientDir == GradientDir.Vertical ? vertexList[vertexList.Count - 1].position.y : vertexList[vertexList.Count - 1].position.x;
|
||||
float topY = _gradientDir == GradientDir.Vertical ? vertexList[0].position.y : vertexList[0].position.x;
|
||||
|
||||
float uiElementHeight = topY - bottomY;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
vh.PopulateUIVertex(ref uiVertex, i);
|
||||
if (!_overwriteAllColor && uiVertex.color != targetGraphic.color)
|
||||
continue;
|
||||
uiVertex.color *= Color.Lerp(_vertex2, _vertex1, ((_gradientDir == GradientDir.Vertical ? uiVertex.position.y : uiVertex.position.x) - bottomY) / uiElementHeight);
|
||||
vh.SetUIVertex(uiVertex, i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
vh.PopulateUIVertex(ref uiVertex, i);
|
||||
if (!_overwriteAllColor && !CompareCarefully(uiVertex.color, targetGraphic.color))
|
||||
continue;
|
||||
switch (_gradientDir)
|
||||
{
|
||||
case GradientDir.Vertical:
|
||||
uiVertex.color *= (i % 4 == 0 || (i - 1) % 4 == 0) ? _vertex1 : _vertex2;
|
||||
break;
|
||||
case GradientDir.Horizontal:
|
||||
uiVertex.color *= (i % 4 == 0 || (i - 3) % 4 == 0) ? _vertex1 : _vertex2;
|
||||
break;
|
||||
case GradientDir.DiagonalLeftToRight:
|
||||
uiVertex.color *= (i % 4 == 0) ? _vertex1 : ((i - 2) % 4 == 0 ? _vertex2 : Color.Lerp(_vertex2, _vertex1, 0.5f));
|
||||
break;
|
||||
case GradientDir.DiagonalRightToLeft:
|
||||
uiVertex.color *= ((i - 1) % 4 == 0) ? _vertex1 : ((i - 3) % 4 == 0 ? _vertex2 : Color.Lerp(_vertex2, _vertex1, 0.5f));
|
||||
break;
|
||||
|
||||
}
|
||||
vh.SetUIVertex(uiVertex, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
private bool CompareCarefully(Color col1, Color col2)
|
||||
{
|
||||
if (Mathf.Abs(col1.r - col2.r) < 0.003f && Mathf.Abs(col1.g - col2.g) < 0.003f && Mathf.Abs(col1.b - col2.b) < 0.003f && Mathf.Abs(col1.a - col2.a) < 0.003f)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public enum GradientMode
|
||||
{
|
||||
Global,
|
||||
Local
|
||||
}
|
||||
|
||||
public enum GradientDir
|
||||
{
|
||||
Vertical,
|
||||
Horizontal,
|
||||
DiagonalLeftToRight,
|
||||
DiagonalRightToLeft
|
||||
//Free
|
||||
}
|
||||
//enum color mode Additive, Multiply, Overwrite
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0671953a9c649e5438e4d961d1983915
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,536 @@
|
||||
/// Credit Brad Nelson (playemgames - bitbucket)
|
||||
/// Modified Gradient effect script from http://answers.unity3d.com/questions/1086415/gradient-text-in-unity-522-basevertexeffect-is-obs.html
|
||||
/// <summary>
|
||||
/// -Uses Unity's Gradient class to define the color
|
||||
/// -Offset is now limited to -1,1
|
||||
/// -Multiple color blend modes
|
||||
///
|
||||
/// Remember that for radial and diamond gradients, colors are applied per-vertex so if you have multiple points on your gradient where the color changes and there aren't enough vertices, you won't see all of the colors.
|
||||
/// </summary>
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/Gradient2")]
|
||||
public class Gradient2 : BaseMeshEffect
|
||||
{
|
||||
[SerializeField]
|
||||
Type _gradientType;
|
||||
|
||||
[SerializeField]
|
||||
Blend _blendMode = Blend.Multiply;
|
||||
|
||||
[SerializeField]
|
||||
[Tooltip("Add vertices to display complex gradients. Turn off if your shape is already very complex, like text.")]
|
||||
bool _modifyVertices = true;
|
||||
|
||||
[SerializeField]
|
||||
[Range(-1, 1)]
|
||||
float _offset = 0f;
|
||||
|
||||
[SerializeField]
|
||||
[Range(0.1f, 10)]
|
||||
float _zoom = 1f;
|
||||
|
||||
[SerializeField]
|
||||
UnityEngine.Gradient _effectGradient = new UnityEngine.Gradient() { colorKeys = new GradientColorKey[] { new GradientColorKey(Color.black, 0), new GradientColorKey(Color.white, 1) } };
|
||||
|
||||
#region Properties
|
||||
public Blend BlendMode
|
||||
{
|
||||
get { return _blendMode; }
|
||||
set
|
||||
{
|
||||
_blendMode = value;
|
||||
graphic.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public UnityEngine.Gradient EffectGradient
|
||||
{
|
||||
get { return _effectGradient; }
|
||||
set
|
||||
{
|
||||
_effectGradient = value;
|
||||
graphic.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public Type GradientType
|
||||
{
|
||||
get { return _gradientType; }
|
||||
set
|
||||
{
|
||||
_gradientType = value;
|
||||
graphic.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ModifyVertices
|
||||
{
|
||||
get { return _modifyVertices; }
|
||||
set
|
||||
{
|
||||
_modifyVertices = value;
|
||||
graphic.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public float Offset
|
||||
{
|
||||
get { return _offset; }
|
||||
set
|
||||
{
|
||||
_offset = Mathf.Clamp(value, -1f, 1f);
|
||||
graphic.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public float Zoom
|
||||
{
|
||||
get { return _zoom; }
|
||||
set
|
||||
{
|
||||
_zoom = Mathf.Clamp(value, 0.1f, 10f);
|
||||
graphic.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override void ModifyMesh(VertexHelper helper)
|
||||
{
|
||||
if (!IsActive() || helper.currentVertCount == 0)
|
||||
return;
|
||||
|
||||
List<UIVertex> _vertexList = new List<UIVertex>();
|
||||
|
||||
helper.GetUIVertexStream(_vertexList);
|
||||
|
||||
int nCount = _vertexList.Count;
|
||||
switch (GradientType)
|
||||
{
|
||||
case Type.Horizontal:
|
||||
case Type.Vertical:
|
||||
{
|
||||
Rect bounds = GetBounds(_vertexList);
|
||||
float min = bounds.xMin;
|
||||
float w = bounds.width;
|
||||
Func<UIVertex, float> GetPosition = v => v.position.x;
|
||||
|
||||
if (GradientType == Type.Vertical)
|
||||
{
|
||||
min = bounds.yMin;
|
||||
w = bounds.height;
|
||||
GetPosition = v => v.position.y;
|
||||
}
|
||||
|
||||
float width = w == 0f ? 0f : 1f / w / Zoom;
|
||||
float zoomOffset = (1 - (1 / Zoom)) * 0.5f;
|
||||
float offset = (Offset * (1 - zoomOffset)) - zoomOffset;
|
||||
|
||||
if (ModifyVertices)
|
||||
{
|
||||
SplitTrianglesAtGradientStops(_vertexList, bounds, zoomOffset, helper);
|
||||
}
|
||||
|
||||
UIVertex vertex = new UIVertex();
|
||||
for (int i = 0; i < helper.currentVertCount; i++)
|
||||
{
|
||||
helper.PopulateUIVertex(ref vertex, i);
|
||||
vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate((GetPosition(vertex) - min) * width - offset));
|
||||
helper.SetUIVertex(vertex, i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Type.Diamond:
|
||||
{
|
||||
Rect bounds = GetBounds(_vertexList);
|
||||
|
||||
float height = bounds.height == 0f ? 0f : 1f / bounds.height / Zoom;
|
||||
float radius = bounds.center.y / 2f;
|
||||
Vector3 center = (Vector3.right + Vector3.up) * radius + Vector3.forward * _vertexList[0].position.z;
|
||||
|
||||
if (ModifyVertices)
|
||||
{
|
||||
helper.Clear();
|
||||
for (int i = 0; i < nCount; i++) helper.AddVert(_vertexList[i]);
|
||||
|
||||
UIVertex centralVertex = new UIVertex();
|
||||
centralVertex.position = center;
|
||||
centralVertex.normal = _vertexList[0].normal;
|
||||
centralVertex.uv0 = new Vector2(0.5f, 0.5f);
|
||||
centralVertex.color = Color.white;
|
||||
helper.AddVert(centralVertex);
|
||||
|
||||
for (int i = 1; i < nCount; i++) helper.AddTriangle(i - 1, i, nCount);
|
||||
helper.AddTriangle(0, nCount - 1, nCount);
|
||||
}
|
||||
|
||||
UIVertex vertex = new UIVertex();
|
||||
|
||||
for (int i = 0; i < helper.currentVertCount; i++)
|
||||
{
|
||||
helper.PopulateUIVertex(ref vertex, i);
|
||||
|
||||
vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate(
|
||||
Vector3.Distance(vertex.position, center) * height - Offset));
|
||||
|
||||
helper.SetUIVertex(vertex, i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Type.Radial:
|
||||
{
|
||||
Rect bounds = GetBounds(_vertexList);
|
||||
|
||||
float width = bounds.width == 0f ? 0f : 1f / bounds.width / Zoom;
|
||||
float height = bounds.height == 0f ? 0f : 1f / bounds.height / Zoom;
|
||||
|
||||
if (ModifyVertices)
|
||||
{
|
||||
helper.Clear();
|
||||
|
||||
float radiusX = bounds.width / 2f;
|
||||
float radiusY = bounds.height / 2f;
|
||||
UIVertex centralVertex = new UIVertex();
|
||||
centralVertex.position = Vector3.right * bounds.center.x + Vector3.up * bounds.center.y + Vector3.forward * _vertexList[0].position.z;
|
||||
centralVertex.normal = _vertexList[0].normal;
|
||||
centralVertex.uv0 = new Vector2(0.5f, 0.5f);
|
||||
centralVertex.color = Color.white;
|
||||
|
||||
int steps = 64;
|
||||
for (int i = 0; i < steps; i++)
|
||||
{
|
||||
UIVertex curVertex = new UIVertex();
|
||||
float angle = (float)i * 360f / (float)steps;
|
||||
float cosX = Mathf.Cos(Mathf.Deg2Rad * angle);
|
||||
float cosY = Mathf.Sin(Mathf.Deg2Rad * angle);
|
||||
|
||||
curVertex.position = Vector3.right * cosX * radiusX + Vector3.up * cosY * radiusY + Vector3.forward * _vertexList[0].position.z;
|
||||
curVertex.normal = _vertexList[0].normal;
|
||||
curVertex.uv0 = new Vector2((cosX + 1) * 0.5f, (cosY + 1) * 0.5f);
|
||||
curVertex.color = Color.white;
|
||||
helper.AddVert(curVertex);
|
||||
}
|
||||
|
||||
helper.AddVert(centralVertex);
|
||||
|
||||
for (int i = 1; i < steps; i++) helper.AddTriangle(i - 1, i, steps);
|
||||
helper.AddTriangle(0, steps - 1, steps);
|
||||
}
|
||||
|
||||
UIVertex vertex = new UIVertex();
|
||||
|
||||
for (int i = 0; i < helper.currentVertCount; i++)
|
||||
{
|
||||
helper.PopulateUIVertex(ref vertex, i);
|
||||
|
||||
vertex.color = BlendColor(vertex.color, EffectGradient.Evaluate(
|
||||
Mathf.Sqrt(
|
||||
Mathf.Pow(Mathf.Abs(vertex.position.x - bounds.center.x) * width, 2f) +
|
||||
Mathf.Pow(Mathf.Abs(vertex.position.y - bounds.center.y) * height, 2f)) * 2f - Offset));
|
||||
|
||||
helper.SetUIVertex(vertex, i);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Rect GetBounds(List<UIVertex> vertices)
|
||||
{
|
||||
float left = vertices[0].position.x;
|
||||
float right = left;
|
||||
float bottom = vertices[0].position.y;
|
||||
float top = bottom;
|
||||
|
||||
for (int i = vertices.Count - 1; i >= 1; --i)
|
||||
{
|
||||
float x = vertices[i].position.x;
|
||||
float y = vertices[i].position.y;
|
||||
|
||||
if (x > right) right = x;
|
||||
else if (x < left) left = x;
|
||||
|
||||
if (y > top) top = y;
|
||||
else if (y < bottom) bottom = y;
|
||||
}
|
||||
|
||||
return new Rect(left, bottom, right - left, top - bottom);
|
||||
}
|
||||
|
||||
void SplitTrianglesAtGradientStops(List<UIVertex> _vertexList, Rect bounds, float zoomOffset, VertexHelper helper)
|
||||
{
|
||||
List<float> stops = FindStops(zoomOffset, bounds);
|
||||
if (stops.Count > 0)
|
||||
{
|
||||
helper.Clear();
|
||||
|
||||
int nCount = _vertexList.Count;
|
||||
for (int i = 0; i < nCount; i += 3)
|
||||
{
|
||||
float[] positions = GetPositions(_vertexList, i);
|
||||
List<int> originIndices = new List<int>(3);
|
||||
List<UIVertex> starts = new List<UIVertex>(3);
|
||||
List<UIVertex> ends = new List<UIVertex>(2);
|
||||
|
||||
for (int s = 0; s < stops.Count; s++)
|
||||
{
|
||||
int initialCount = helper.currentVertCount;
|
||||
bool hadEnds = ends.Count > 0;
|
||||
bool earlyStart = false;
|
||||
|
||||
// find any start vertices for this stop
|
||||
for (int p = 0; p < 3; p++)
|
||||
{
|
||||
if (!originIndices.Contains(p) && positions[p] < stops[s])
|
||||
{
|
||||
// make sure the first index crosses the stop
|
||||
int p1 = (p + 1) % 3;
|
||||
var start = _vertexList[p + i];
|
||||
if (positions[p1] > stops[s])
|
||||
{
|
||||
originIndices.Insert(0, p);
|
||||
starts.Insert(0, start);
|
||||
earlyStart = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
originIndices.Add(p);
|
||||
starts.Add(start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bail if all before or after the stop
|
||||
if (originIndices.Count == 0)
|
||||
continue;
|
||||
if (originIndices.Count == 3)
|
||||
break;
|
||||
|
||||
// report any start vertices
|
||||
foreach (var start in starts)
|
||||
helper.AddVert(start);
|
||||
|
||||
// make two ends, splitting at the stop
|
||||
ends.Clear();
|
||||
foreach (int index in originIndices)
|
||||
{
|
||||
int oppositeIndex = (index + 1) % 3;
|
||||
if (positions[oppositeIndex] < stops[s])
|
||||
oppositeIndex = (oppositeIndex + 1) % 3;
|
||||
ends.Add(CreateSplitVertex(_vertexList[index + i], _vertexList[oppositeIndex + i], stops[s]));
|
||||
}
|
||||
if (ends.Count == 1)
|
||||
{
|
||||
int oppositeIndex = (originIndices[0] + 2) % 3;
|
||||
ends.Add(CreateSplitVertex(_vertexList[originIndices[0] + i], _vertexList[oppositeIndex + i], stops[s]));
|
||||
}
|
||||
|
||||
// report end vertices
|
||||
foreach (var end in ends)
|
||||
helper.AddVert(end);
|
||||
|
||||
// make triangles
|
||||
if (hadEnds)
|
||||
{
|
||||
helper.AddTriangle(initialCount - 2, initialCount, initialCount + 1);
|
||||
helper.AddTriangle(initialCount - 2, initialCount + 1, initialCount - 1);
|
||||
if (starts.Count > 0)
|
||||
{
|
||||
if (earlyStart)
|
||||
helper.AddTriangle(initialCount - 2, initialCount + 3, initialCount);
|
||||
else
|
||||
helper.AddTriangle(initialCount + 1, initialCount + 3, initialCount - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int vertexCount = helper.currentVertCount;
|
||||
helper.AddTriangle(initialCount, vertexCount - 2, vertexCount - 1);
|
||||
if (starts.Count > 1)
|
||||
helper.AddTriangle(initialCount, vertexCount - 1, initialCount + 1);
|
||||
}
|
||||
|
||||
starts.Clear();
|
||||
}
|
||||
|
||||
// clean up after looping through gradient stops
|
||||
if (ends.Count > 0)
|
||||
{
|
||||
// find any final vertices after the gradient stops
|
||||
if (starts.Count == 0)
|
||||
{
|
||||
for (int p = 0; p < 3; p++)
|
||||
{
|
||||
if (!originIndices.Contains(p) && positions[p] > stops[stops.Count - 1])
|
||||
{
|
||||
int p1 = (p + 1) % 3;
|
||||
UIVertex end = _vertexList[p + i];
|
||||
if (positions[p1] > stops[stops.Count - 1])
|
||||
starts.Insert(0, end);
|
||||
else
|
||||
starts.Add(end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// report final vertices
|
||||
foreach (var start in starts)
|
||||
helper.AddVert(start);
|
||||
|
||||
// make final triangle(s)
|
||||
int vertexCount = helper.currentVertCount;
|
||||
if (starts.Count > 1)
|
||||
{
|
||||
helper.AddTriangle(vertexCount - 4, vertexCount - 2, vertexCount - 1);
|
||||
helper.AddTriangle(vertexCount - 4, vertexCount - 1, vertexCount - 3);
|
||||
}
|
||||
else if (starts.Count > 0)
|
||||
{
|
||||
helper.AddTriangle(vertexCount - 3, vertexCount - 1, vertexCount - 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the triangle wasn't split, add it as-is
|
||||
helper.AddVert(_vertexList[i]);
|
||||
helper.AddVert(_vertexList[i + 1]);
|
||||
helper.AddVert(_vertexList[i + 2]);
|
||||
int vertexCount = helper.currentVertCount;
|
||||
helper.AddTriangle(vertexCount - 3, vertexCount - 2, vertexCount - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float[] GetPositions(List<UIVertex> _vertexList, int index)
|
||||
{
|
||||
float[] positions = new float[3];
|
||||
if (GradientType == Type.Horizontal)
|
||||
{
|
||||
positions[0] = _vertexList[index].position.x;
|
||||
positions[1] = _vertexList[index + 1].position.x;
|
||||
positions[2] = _vertexList[index + 2].position.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
positions[0] = _vertexList[index].position.y;
|
||||
positions[1] = _vertexList[index + 1].position.y;
|
||||
positions[2] = _vertexList[index + 2].position.y;
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
List<float> FindStops(float zoomOffset, Rect bounds)
|
||||
{
|
||||
List<float> stops = new List<float>();
|
||||
var offset = Offset * (1 - zoomOffset);
|
||||
var startBoundary = zoomOffset - offset;
|
||||
var endBoundary = (1 - zoomOffset) - offset;
|
||||
|
||||
foreach (var color in EffectGradient.colorKeys)
|
||||
{
|
||||
if (color.time >= endBoundary)
|
||||
break;
|
||||
if (color.time > startBoundary)
|
||||
stops.Add((color.time - startBoundary) * Zoom);
|
||||
}
|
||||
foreach (var alpha in EffectGradient.alphaKeys)
|
||||
{
|
||||
if (alpha.time >= endBoundary)
|
||||
break;
|
||||
if (alpha.time > startBoundary)
|
||||
stops.Add((alpha.time - startBoundary) * Zoom);
|
||||
}
|
||||
|
||||
float min = bounds.xMin;
|
||||
float size = bounds.width;
|
||||
if (GradientType == Type.Vertical)
|
||||
{
|
||||
min = bounds.yMin;
|
||||
size = bounds.height;
|
||||
}
|
||||
|
||||
stops.Sort();
|
||||
for (int i = 0; i < stops.Count; i++)
|
||||
{
|
||||
stops[i] = (stops[i] * size) + min;
|
||||
|
||||
if (i > 0 && Math.Abs(stops[i] - stops[i - 1]) < 2)
|
||||
{
|
||||
stops.RemoveAt(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
return stops;
|
||||
}
|
||||
|
||||
UIVertex CreateSplitVertex(UIVertex vertex1, UIVertex vertex2, float stop)
|
||||
{
|
||||
if (GradientType == Type.Horizontal)
|
||||
{
|
||||
float sx = vertex1.position.x - stop;
|
||||
float dx = vertex1.position.x - vertex2.position.x;
|
||||
float dy = vertex1.position.y - vertex2.position.y;
|
||||
float uvx = vertex1.uv0.x - vertex2.uv0.x;
|
||||
float uvy = vertex1.uv0.y - vertex2.uv0.y;
|
||||
float ratio = sx / dx;
|
||||
float splitY = vertex1.position.y - (dy * ratio);
|
||||
|
||||
UIVertex splitVertex = new UIVertex();
|
||||
splitVertex.position = new Vector3(stop, splitY, vertex1.position.z);
|
||||
splitVertex.normal = vertex1.normal;
|
||||
splitVertex.uv0 = new Vector2(vertex1.uv0.x - (uvx * ratio), vertex1.uv0.y - (uvy * ratio));
|
||||
splitVertex.color = Color.white;
|
||||
return splitVertex;
|
||||
}
|
||||
else
|
||||
{
|
||||
float sy = vertex1.position.y - stop;
|
||||
float dy = vertex1.position.y - vertex2.position.y;
|
||||
float dx = vertex1.position.x - vertex2.position.x;
|
||||
float uvx = vertex1.uv0.x - vertex2.uv0.x;
|
||||
float uvy = vertex1.uv0.y - vertex2.uv0.y;
|
||||
float ratio = sy / dy;
|
||||
float splitX = vertex1.position.x - (dx * ratio);
|
||||
|
||||
UIVertex splitVertex = new UIVertex();
|
||||
splitVertex.position = new Vector3(splitX, stop, vertex1.position.z);
|
||||
splitVertex.normal = vertex1.normal;
|
||||
splitVertex.uv0 = new Vector2(vertex1.uv0.x - (uvx * ratio), vertex1.uv0.y - (uvy * ratio));
|
||||
splitVertex.color = Color.white;
|
||||
return splitVertex;
|
||||
}
|
||||
}
|
||||
|
||||
Color BlendColor(Color colorA, Color colorB)
|
||||
{
|
||||
switch (BlendMode)
|
||||
{
|
||||
default: return colorB;
|
||||
case Blend.Add: return colorA + colorB;
|
||||
case Blend.Multiply: return colorA * colorB;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Type
|
||||
{
|
||||
Horizontal,
|
||||
Vertical,
|
||||
Radial,
|
||||
Diamond
|
||||
}
|
||||
|
||||
public enum Blend
|
||||
{
|
||||
Override,
|
||||
Add,
|
||||
Multiply
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45facfdc6a639f041b007c036dc527b8
|
||||
timeCreated: 1479244798
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,168 @@
|
||||
/// Credit Deeperbeige
|
||||
/// Sourced from - http://forum.unity3d.com/threads/adjustable-character-spacing-free-script.288277/
|
||||
/*
|
||||
|
||||
Produces an simple tracking/letter-spacing effect on UI Text components.
|
||||
|
||||
Set the spacing parameter to adjust letter spacing.
|
||||
Negative values cuddle the text up tighter than normal. Go too far and it'll look odd.
|
||||
Positive values spread the text out more than normal. This will NOT respect the text area you've defined.
|
||||
Zero spacing will present the font with no changes.
|
||||
|
||||
Relies on counting off characters in your Text component's text property and
|
||||
matching those against the quads passed in via the verts array. This is really
|
||||
rather primitive, but I can't see any better way at the moment. It means that
|
||||
all sorts of things can break the effect...
|
||||
|
||||
This component should be placed higher in component list than any other vertex
|
||||
modifiers that alter the total number of vertices. EG, place this above Shadow
|
||||
or Outline effects. If you don't, the outline/shadow won't match the position
|
||||
of the letters properly. If you place the outline/shadow effect second however,
|
||||
it will just work on the altered vertices from this component, and function
|
||||
as expected.
|
||||
|
||||
This component works best if you don't allow text to automatically wrap. It also
|
||||
blows up outside of the given text area. Basically, it's a cheap and dirty effect,
|
||||
not a clever text layout engine. It can't affect how Unity chooses to break up
|
||||
your lines. If you manually use line breaks however, it should detect those and
|
||||
function more or less as you'd expect.
|
||||
|
||||
The spacing parameter is measured in pixels multiplied by the font size. This was
|
||||
chosen such that when you adjust the font size, it does not change the visual spacing
|
||||
that you've dialed in. There's also a scale factor of 1/100 in this number to
|
||||
bring it into a comfortable adjustable range. There's no limit on this parameter,
|
||||
but obviously some values will look quite strange.
|
||||
|
||||
This component doesn't really work with Rich Text. You don't need to remember to
|
||||
turn off Rich Text via the checkbox, but because it can't see what makes a
|
||||
printable character and what doesn't, it will typically miscount characters when you
|
||||
use HTML-like tags in your text. Try it out, you'll see what I mean. It doesn't
|
||||
break down entirely, but it doesn't really do what you'd want either.
|
||||
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/Letter Spacing")]
|
||||
///Summary
|
||||
/// Note, Vertex Count has changed in 5.2.1+, is now 6 (two tris) instead of 4 (tri strip).
|
||||
public class LetterSpacing : BaseMeshEffect
|
||||
{
|
||||
[SerializeField]
|
||||
private float m_spacing = 0f;
|
||||
|
||||
protected LetterSpacing() { }
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate()
|
||||
{
|
||||
spacing = m_spacing;
|
||||
base.OnValidate();
|
||||
}
|
||||
#endif
|
||||
|
||||
public float spacing
|
||||
{
|
||||
get { return m_spacing; }
|
||||
set
|
||||
{
|
||||
if (m_spacing == value) return;
|
||||
m_spacing = value;
|
||||
if (graphic != null) graphic.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public override void ModifyMesh(VertexHelper vh)
|
||||
{
|
||||
if (! IsActive()) return;
|
||||
|
||||
List<UIVertex> verts = new List<UIVertex>();
|
||||
vh.GetUIVertexStream(verts);
|
||||
|
||||
Text text = GetComponent<Text>();
|
||||
if (text == null)
|
||||
{
|
||||
Debug.LogWarning("LetterSpacing: Missing Text component");
|
||||
return;
|
||||
}
|
||||
|
||||
string[] lines = text.text.Split('\n');
|
||||
Vector3 pos;
|
||||
float letterOffset = spacing * (float)text.fontSize / 100f;
|
||||
float alignmentFactor = 0;
|
||||
int glyphIdx = 0;
|
||||
|
||||
switch (text.alignment)
|
||||
{
|
||||
case TextAnchor.LowerLeft:
|
||||
case TextAnchor.MiddleLeft:
|
||||
case TextAnchor.UpperLeft:
|
||||
alignmentFactor = 0f;
|
||||
break;
|
||||
|
||||
case TextAnchor.LowerCenter:
|
||||
case TextAnchor.MiddleCenter:
|
||||
case TextAnchor.UpperCenter:
|
||||
alignmentFactor = 0.5f;
|
||||
break;
|
||||
|
||||
case TextAnchor.LowerRight:
|
||||
case TextAnchor.MiddleRight:
|
||||
case TextAnchor.UpperRight:
|
||||
alignmentFactor = 1f;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int lineIdx=0; lineIdx < lines.Length; lineIdx++)
|
||||
{
|
||||
string line = lines[lineIdx];
|
||||
float lineOffset = (line.Length -1) * letterOffset * alignmentFactor;
|
||||
|
||||
for (int charIdx = 0; charIdx < line.Length; charIdx++)
|
||||
{
|
||||
int idx1 = glyphIdx * 6 + 0;
|
||||
int idx2 = glyphIdx * 6 + 1;
|
||||
int idx3 = glyphIdx * 6 + 2;
|
||||
int idx4 = glyphIdx * 6 + 3;
|
||||
int idx5 = glyphIdx * 6 + 4;
|
||||
int idx6 = glyphIdx * 6 + 5;
|
||||
|
||||
// Check for truncated text (doesn't generate verts for all characters)
|
||||
if (idx6 > verts.Count - 1) return;
|
||||
|
||||
UIVertex vert1 = verts[idx1];
|
||||
UIVertex vert2 = verts[idx2];
|
||||
UIVertex vert3 = verts[idx3];
|
||||
UIVertex vert4 = verts[idx4];
|
||||
UIVertex vert5 = verts[idx5];
|
||||
UIVertex vert6 = verts[idx6];
|
||||
|
||||
pos = Vector3.right * (letterOffset * charIdx - lineOffset);
|
||||
|
||||
vert1.position += pos;
|
||||
vert2.position += pos;
|
||||
vert3.position += pos;
|
||||
vert4.position += pos;
|
||||
vert5.position += pos;
|
||||
vert6.position += pos;
|
||||
|
||||
verts[idx1] = vert1;
|
||||
verts[idx2] = vert2;
|
||||
verts[idx3] = vert3;
|
||||
verts[idx4] = vert4;
|
||||
verts[idx5] = vert5;
|
||||
verts[idx6] = vert6;
|
||||
|
||||
glyphIdx++;
|
||||
}
|
||||
|
||||
// Offset for carriage return character that still generates verts
|
||||
glyphIdx++;
|
||||
}
|
||||
vh.Clear();
|
||||
vh.AddUIVertexTriangleStream(verts);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8ee10f5b9a0e16c40b25e079c03a17a2
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,190 @@
|
||||
/// Credit herbst / derived from LetterSpacing by Deeperbeige
|
||||
/// Sourced from - http://forum.unity3d.com/threads/adjustable-character-spacing-free-script.288277/
|
||||
/*
|
||||
|
||||
Produces an simple mono-spacing effect on UI Text components.
|
||||
|
||||
Set the spacing parameter to adjust mono spacing.
|
||||
Negative values cuddle the text up tighter than normal. Go too far and it'll look odd.
|
||||
Positive values spread the text out more than normal. This will NOT respect the text area you've defined.
|
||||
Zero spacing will present the font with no changes.
|
||||
|
||||
Relies on counting off characters in your Text component's text property and
|
||||
matching those against the quads passed in via the verts array. This is really
|
||||
rather primitive, but I can't see any better way at the moment. It means that
|
||||
all sorts of things can break the effect...
|
||||
|
||||
This component should be placed higher in component list than any other vertex
|
||||
modifiers that alter the total number of vertices. EG, place this above Shadow
|
||||
or Outline effects. If you don't, the outline/shadow won't match the position
|
||||
of the letters properly. If you place the outline/shadow effect second however,
|
||||
it will just work on the altered vertices from this component, and function
|
||||
as expected.
|
||||
|
||||
This component works best if you don't allow text to automatically wrap. It also
|
||||
blows up outside of the given text area. Basically, it's a cheap and dirty effect,
|
||||
not a clever text layout engine. It can't affect how Unity chooses to break up
|
||||
your lines. If you manually use line breaks however, it should detect those and
|
||||
function more or less as you'd expect.
|
||||
|
||||
The spacing parameter is measured in pixels multiplied by the font size. This was
|
||||
chosen such that when you adjust the font size, it does not change the visual spacing
|
||||
that you've dialed in. There's also a scale factor of 1/100 in this number to
|
||||
bring it into a comfortable adjustable range. There's no limit on this parameter,
|
||||
but obviously some values will look quite strange.
|
||||
|
||||
This component doesn't really work with Rich Text. You don't need to remember to
|
||||
turn off Rich Text via the checkbox, but because it can't see what makes a
|
||||
printable character and what doesn't, it will typically miscount characters when you
|
||||
use HTML-like tags in your text. Try it out, you'll see what I mean. It doesn't
|
||||
break down entirely, but it doesn't really do what you'd want either.
|
||||
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/Mono Spacing")]
|
||||
[RequireComponent(typeof(Text))]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
///Summary
|
||||
/// Note, Vertex Count has changed in 5.2.1+, is now 6 (two tris) instead of 4 (tri strip).
|
||||
public class MonoSpacing : BaseMeshEffect
|
||||
{
|
||||
[SerializeField]
|
||||
private float m_spacing = 0f;
|
||||
public float HalfCharWidth = 1;
|
||||
public bool UseHalfCharWidth = false;
|
||||
|
||||
private RectTransform rectTransform;
|
||||
private Text text;
|
||||
|
||||
protected MonoSpacing() { }
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
text = GetComponent<Text>();
|
||||
if (text == null)
|
||||
{
|
||||
Debug.LogWarning("MonoSpacing: Missing Text component");
|
||||
return;
|
||||
}
|
||||
rectTransform = text.GetComponent<RectTransform>();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate()
|
||||
{
|
||||
Spacing = m_spacing;
|
||||
base.OnValidate();
|
||||
}
|
||||
#endif
|
||||
|
||||
public float Spacing
|
||||
{
|
||||
get { return m_spacing; }
|
||||
set
|
||||
{
|
||||
if (m_spacing == value) return;
|
||||
m_spacing = value;
|
||||
if (graphic != null) graphic.SetVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public override void ModifyMesh(VertexHelper vh)
|
||||
{
|
||||
if (! IsActive()) return;
|
||||
|
||||
List<UIVertex> verts = new List<UIVertex>();
|
||||
vh.GetUIVertexStream(verts);
|
||||
|
||||
string[] lines = text.text.Split('\n');
|
||||
// Vector3 pos;
|
||||
float letterOffset = Spacing * (float)text.fontSize / 100f;
|
||||
float alignmentFactor = 0;
|
||||
int glyphIdx = 0;
|
||||
|
||||
switch (text.alignment)
|
||||
{
|
||||
case TextAnchor.LowerLeft:
|
||||
case TextAnchor.MiddleLeft:
|
||||
case TextAnchor.UpperLeft:
|
||||
alignmentFactor = 0f;
|
||||
break;
|
||||
|
||||
case TextAnchor.LowerCenter:
|
||||
case TextAnchor.MiddleCenter:
|
||||
case TextAnchor.UpperCenter:
|
||||
alignmentFactor = 0.5f;
|
||||
break;
|
||||
|
||||
case TextAnchor.LowerRight:
|
||||
case TextAnchor.MiddleRight:
|
||||
case TextAnchor.UpperRight:
|
||||
alignmentFactor = 1f;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int lineIdx=0; lineIdx < lines.Length; lineIdx++)
|
||||
{
|
||||
string line = lines[lineIdx];
|
||||
float lineOffset = (line.Length - 1) * letterOffset * (alignmentFactor) - (alignmentFactor - 0.5f) * rectTransform.rect.width;
|
||||
|
||||
var offsetX = -lineOffset + letterOffset / 2 * (1 - alignmentFactor * 2);
|
||||
|
||||
for (int charIdx = 0; charIdx < line.Length; charIdx++)
|
||||
{
|
||||
int idx1 = glyphIdx * 6 + 0;
|
||||
int idx2 = glyphIdx * 6 + 1;
|
||||
int idx3 = glyphIdx * 6 + 2;
|
||||
int idx4 = glyphIdx * 6 + 3;
|
||||
int idx5 = glyphIdx * 6 + 4;
|
||||
int idx6 = glyphIdx * 6 + 5;
|
||||
|
||||
// Check for truncated text (doesn't generate verts for all characters)
|
||||
if (idx6 > verts.Count - 1) return;
|
||||
|
||||
UIVertex vert1 = verts[idx1];
|
||||
UIVertex vert2 = verts[idx2];
|
||||
UIVertex vert3 = verts[idx3];
|
||||
UIVertex vert4 = verts[idx4];
|
||||
UIVertex vert5 = verts[idx5];
|
||||
UIVertex vert6 = verts[idx6];
|
||||
|
||||
// pos = Vector3.right * (letterOffset * (charIdx) - lineOffset);
|
||||
float charWidth = (vert2.position - vert1.position).x;
|
||||
var smallChar = UseHalfCharWidth && (charWidth < HalfCharWidth);
|
||||
|
||||
var smallCharOffset = smallChar ? -letterOffset/4 : 0;
|
||||
|
||||
vert1.position += new Vector3(-vert1.position.x + offsetX + -.5f * charWidth + smallCharOffset, 0, 0);
|
||||
vert2.position += new Vector3(-vert2.position.x + offsetX + .5f * charWidth + smallCharOffset, 0, 0);
|
||||
vert3.position += new Vector3(-vert3.position.x + offsetX + .5f * charWidth + smallCharOffset, 0, 0);
|
||||
vert4.position += new Vector3(-vert4.position.x + offsetX + .5f * charWidth + smallCharOffset, 0, 0);
|
||||
vert5.position += new Vector3(-vert5.position.x + offsetX + -.5f * charWidth + smallCharOffset, 0, 0);
|
||||
vert6.position += new Vector3(-vert6.position.x + offsetX + -.5f * charWidth + smallCharOffset, 0, 0);
|
||||
|
||||
if (smallChar)
|
||||
offsetX += letterOffset / 2;
|
||||
else
|
||||
offsetX += letterOffset;
|
||||
|
||||
verts[idx1] = vert1;
|
||||
verts[idx2] = vert2;
|
||||
verts[idx3] = vert3;
|
||||
verts[idx4] = vert4;
|
||||
verts[idx5] = vert5;
|
||||
verts[idx6] = vert6;
|
||||
|
||||
glyphIdx++;
|
||||
}
|
||||
|
||||
// Offset for carriage return character that still generates verts
|
||||
glyphIdx++;
|
||||
}
|
||||
vh.Clear();
|
||||
vh.AddUIVertexTriangleStream(verts);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97a58789aa01843488ef44dc747ee8e8
|
||||
timeCreated: 1490183235
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,190 @@
|
||||
/// Credit Melang
|
||||
/// Sourced from - http://forum.unity3d.com/members/melang.593409/
|
||||
|
||||
using System.Collections.Generic;
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
//An outline that looks a bit nicer than the default one. It has less "holes" in the outline by drawing more copies of the effect
|
||||
[AddComponentMenu("UI/Effects/Extensions/Nicer Outline")]
|
||||
public class NicerOutline : BaseMeshEffect
|
||||
{
|
||||
[SerializeField]
|
||||
private Color m_EffectColor = new Color (0f, 0f, 0f, 0.5f);
|
||||
|
||||
[SerializeField]
|
||||
private Vector2 m_EffectDistance = new Vector2 (1f, -1f);
|
||||
|
||||
[SerializeField]
|
||||
private bool m_UseGraphicAlpha = true;
|
||||
|
||||
private List < UIVertex > m_Verts = new List<UIVertex>();
|
||||
|
||||
//
|
||||
// Properties
|
||||
//
|
||||
public Color effectColor
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_EffectColor;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_EffectColor = value;
|
||||
if (base.graphic != null)
|
||||
{
|
||||
base.graphic.SetVerticesDirty ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 effectDistance
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_EffectDistance;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value.x > 600f)
|
||||
{
|
||||
value.x = 600f;
|
||||
}
|
||||
if (value.x < -600f)
|
||||
{
|
||||
value.x = -600f;
|
||||
}
|
||||
if (value.y > 600f)
|
||||
{
|
||||
value.y = 600f;
|
||||
}
|
||||
if (value.y < -600f)
|
||||
{
|
||||
value.y = -600f;
|
||||
}
|
||||
if (this.m_EffectDistance == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.m_EffectDistance = value;
|
||||
if (base.graphic != null)
|
||||
{
|
||||
base.graphic.SetVerticesDirty ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool useGraphicAlpha
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_UseGraphicAlpha;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_UseGraphicAlpha = value;
|
||||
if (base.graphic != null)
|
||||
{
|
||||
base.graphic.SetVerticesDirty ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void ApplyShadowZeroAlloc(List<UIVertex> verts, Color32 color, int start, int end, float x, float y)
|
||||
{
|
||||
UIVertex vt;
|
||||
|
||||
var neededCpacity = verts.Count * 2;
|
||||
if (verts.Capacity < neededCpacity)
|
||||
verts.Capacity = neededCpacity;
|
||||
|
||||
for (int i = start; i < end; ++i)
|
||||
{
|
||||
vt = verts[i];
|
||||
verts.Add(vt);
|
||||
|
||||
Vector3 v = vt.position;
|
||||
v.x += x;
|
||||
v.y += y;
|
||||
vt.position = v;
|
||||
var newColor = color;
|
||||
if (m_UseGraphicAlpha)
|
||||
newColor.a = (byte)((newColor.a * verts[i].color.a) / 255);
|
||||
vt.color = newColor;
|
||||
verts[i] = vt;
|
||||
}
|
||||
}
|
||||
|
||||
protected void ApplyShadow(List<UIVertex> verts, Color32 color, int start, int end, float x, float y)
|
||||
{
|
||||
var neededCpacity = verts.Count * 2;
|
||||
if (verts.Capacity < neededCpacity)
|
||||
verts.Capacity = neededCpacity;
|
||||
|
||||
ApplyShadowZeroAlloc(verts, color, start, end, x, y);
|
||||
}
|
||||
|
||||
|
||||
public override void ModifyMesh(VertexHelper vh)
|
||||
{
|
||||
if (!this.IsActive ())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Verts.Clear();
|
||||
vh.GetUIVertexStream(m_Verts);
|
||||
|
||||
Text foundtext = GetComponent<Text>();
|
||||
|
||||
float best_fit_adjustment = 1f;
|
||||
|
||||
if (foundtext && foundtext.resizeTextForBestFit)
|
||||
{
|
||||
best_fit_adjustment = (float)foundtext.cachedTextGenerator.fontSizeUsedForBestFit / (foundtext.resizeTextMaxSize-1); //max size seems to be exclusive
|
||||
|
||||
}
|
||||
|
||||
float distanceX = this.effectDistance.x * best_fit_adjustment;
|
||||
float distanceY = this.effectDistance.y * best_fit_adjustment;
|
||||
|
||||
int start = 0;
|
||||
int count = m_Verts.Count;
|
||||
this.ApplyShadow (m_Verts, this.effectColor, start, m_Verts.Count, distanceX, distanceY);
|
||||
start = count;
|
||||
count = m_Verts.Count;
|
||||
this.ApplyShadow (m_Verts, this.effectColor, start, m_Verts.Count, distanceX, -distanceY);
|
||||
start = count;
|
||||
count = m_Verts.Count;
|
||||
this.ApplyShadow (m_Verts, this.effectColor, start, m_Verts.Count, -distanceX, distanceY);
|
||||
start = count;
|
||||
count = m_Verts.Count;
|
||||
this.ApplyShadow (m_Verts, this.effectColor, start, m_Verts.Count, -distanceX, -distanceY);
|
||||
|
||||
start = count;
|
||||
count = m_Verts.Count;
|
||||
this.ApplyShadow (m_Verts, this.effectColor, start, m_Verts.Count, distanceX, 0);
|
||||
start = count;
|
||||
count = m_Verts.Count;
|
||||
this.ApplyShadow (m_Verts, this.effectColor, start, m_Verts.Count, -distanceX, 0);
|
||||
|
||||
start = count;
|
||||
count = m_Verts.Count;
|
||||
this.ApplyShadow (m_Verts, this.effectColor, start, m_Verts.Count, 0, distanceY);
|
||||
start = count;
|
||||
count = m_Verts.Count;
|
||||
this.ApplyShadow (m_Verts, this.effectColor, start, m_Verts.Count, 0, -distanceY);
|
||||
|
||||
vh.Clear();
|
||||
vh.AddUIVertexTriangleStream(m_Verts);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate ()
|
||||
{
|
||||
this.effectDistance = this.m_EffectDistance;
|
||||
base.OnValidate ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db125c7de00668f4e98849d0aaf366d7
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,125 @@
|
||||
/// Credit senritsu
|
||||
/// Sourced from - https://github.com/senritsu/unitility/blob/master/Assets/Unitility/GUI/RaycastMask.cs
|
||||
|
||||
/***************************************************************************\
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Jonas Schiegl (https://github.com/senritsu)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
\***************************************************************************/
|
||||
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[RequireComponent(typeof(Image))]
|
||||
[AddComponentMenu("UI/Extensions/Raycast Mask")]
|
||||
public class RaycastMask : MonoBehaviour, ICanvasRaycastFilter
|
||||
{
|
||||
private Image _image;
|
||||
private Sprite _sprite;
|
||||
|
||||
void Start()
|
||||
{
|
||||
_image = GetComponent<Image>();
|
||||
}
|
||||
|
||||
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
|
||||
{
|
||||
_sprite = _image.sprite;
|
||||
|
||||
var rectTransform = (RectTransform)transform;
|
||||
Vector2 localPositionPivotRelative;
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)transform, sp, eventCamera, out localPositionPivotRelative);
|
||||
|
||||
// convert to bottom-left origin coordinates
|
||||
var localPosition = new Vector2(localPositionPivotRelative.x + rectTransform.pivot.x * rectTransform.rect.width,
|
||||
localPositionPivotRelative.y + rectTransform.pivot.y * rectTransform.rect.height);
|
||||
|
||||
var spriteRect = _sprite.textureRect;
|
||||
var maskRect = rectTransform.rect;
|
||||
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
// convert to texture space
|
||||
switch (_image.type)
|
||||
{
|
||||
|
||||
case Image.Type.Sliced:
|
||||
{
|
||||
var border = _sprite.border;
|
||||
// x slicing
|
||||
if (localPosition.x < border.x)
|
||||
{
|
||||
x = Mathf.FloorToInt(spriteRect.x + localPosition.x);
|
||||
}
|
||||
else if (localPosition.x > maskRect.width - border.z)
|
||||
{
|
||||
x = Mathf.FloorToInt(spriteRect.x + spriteRect.width - (maskRect.width - localPosition.x));
|
||||
}
|
||||
else
|
||||
{
|
||||
x = Mathf.FloorToInt(spriteRect.x + border.x +
|
||||
((localPosition.x - border.x) /
|
||||
(maskRect.width - border.x - border.z)) *
|
||||
(spriteRect.width - border.x - border.z));
|
||||
}
|
||||
// y slicing
|
||||
if (localPosition.y < border.y)
|
||||
{
|
||||
y = Mathf.FloorToInt(spriteRect.y + localPosition.y);
|
||||
}
|
||||
else if (localPosition.y > maskRect.height - border.w)
|
||||
{
|
||||
y = Mathf.FloorToInt(spriteRect.y + spriteRect.height - (maskRect.height - localPosition.y));
|
||||
}
|
||||
else
|
||||
{
|
||||
y = Mathf.FloorToInt(spriteRect.y + border.y +
|
||||
((localPosition.y - border.y) /
|
||||
(maskRect.height - border.y - border.w)) *
|
||||
(spriteRect.height - border.y - border.w));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Image.Type.Simple:
|
||||
default:
|
||||
{
|
||||
// conversion to uniform UV space
|
||||
x = Mathf.FloorToInt(spriteRect.x + spriteRect.width * localPosition.x / maskRect.width);
|
||||
y = Mathf.FloorToInt(spriteRect.y + spriteRect.height * localPosition.y / maskRect.height);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// destroy component if texture import settings are wrong
|
||||
try
|
||||
{
|
||||
return _sprite.texture.GetPixel(x, y).a > 0;
|
||||
}
|
||||
catch (UnityException)
|
||||
{
|
||||
Debug.LogWarning("Mask texture not readable, set your sprite to Texture Type 'Advanced' and check 'Read/Write Enabled'");
|
||||
Destroy(this);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22757922dd9d4064d8186fbef72b0772
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f9656bd8c19a5a74c90babab7228f771
|
||||
folderAsset: yes
|
||||
timeCreated: 1467468503
|
||||
licenseType: Pro
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,41 @@
|
||||
/// Credit 00christian00
|
||||
/// Sourced from - http://forum.unity3d.com/threads/any-way-to-show-part-of-an-image-without-using-mask.360085/#post-2332030
|
||||
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/UIAdditiveEffect")]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
public class UIAdditiveEffect : MonoBehaviour
|
||||
{
|
||||
MaskableGraphic mGraphic;
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
SetMaterial();
|
||||
}
|
||||
|
||||
public void SetMaterial()
|
||||
{
|
||||
mGraphic = this.GetComponent<MaskableGraphic>();
|
||||
if (mGraphic != null)
|
||||
{
|
||||
if (mGraphic.material == null || mGraphic.material.name == "Default UI Material")
|
||||
{
|
||||
//Applying default material with UI Image Crop shader
|
||||
mGraphic.material = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/UIAdditive"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Please attach component to a Graphical UI component");
|
||||
}
|
||||
}
|
||||
public void OnValidate()
|
||||
{
|
||||
SetMaterial();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a29c8587a101744ea9e6198d89cb2df
|
||||
timeCreated: 1464643709
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,70 @@
|
||||
/// Credit 00christian00
|
||||
/// Sourced from - http://forum.unity3d.com/threads/any-way-to-show-part-of-an-image-without-using-mask.360085/#post-2332030
|
||||
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/UIImageCrop")]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
public class UIImageCrop : MonoBehaviour
|
||||
{
|
||||
MaskableGraphic mGraphic;
|
||||
Material mat;
|
||||
int XCropProperty, YCropProperty;
|
||||
public float XCrop = 0f;
|
||||
public float YCrop = 0f;
|
||||
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
SetMaterial();
|
||||
}
|
||||
|
||||
public void SetMaterial()
|
||||
{
|
||||
mGraphic = this.GetComponent<MaskableGraphic>();
|
||||
XCropProperty = Shader.PropertyToID("_XCrop");
|
||||
YCropProperty = Shader.PropertyToID("_YCrop");
|
||||
if (mGraphic != null)
|
||||
{
|
||||
if (mGraphic.material == null || mGraphic.material.name == "Default UI Material")
|
||||
{
|
||||
//Applying default material with UI Image Crop shader
|
||||
mGraphic.material = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/UI Image Crop"));
|
||||
}
|
||||
mat = mGraphic.material;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Please attach component to a Graphical UI component");
|
||||
}
|
||||
}
|
||||
public void OnValidate()
|
||||
{
|
||||
SetMaterial();
|
||||
SetXCrop(XCrop);
|
||||
SetYCrop(YCrop);
|
||||
}
|
||||
/// <summary>
|
||||
/// Set the x crop factor, with x being a normalized value 0-1f.
|
||||
/// </summary>
|
||||
/// <param name="xcrop"></param>
|
||||
public void SetXCrop(float xcrop)
|
||||
{
|
||||
XCrop = Mathf.Clamp01(xcrop);
|
||||
mat.SetFloat(XCropProperty, XCrop);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the y crop factor, with y being a normalized value 0-1f.
|
||||
/// </summary>
|
||||
/// <param name="ycrop"></param>
|
||||
public void SetYCrop(float ycrop)
|
||||
{
|
||||
YCrop = Mathf.Clamp01(ycrop);
|
||||
mat.SetFloat(YCropProperty, YCrop);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 022c3983095dce44c9504739a8ed7324
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,41 @@
|
||||
/// Credit 00christian00
|
||||
/// Sourced from - http://forum.unity3d.com/threads/any-way-to-show-part-of-an-image-without-using-mask.360085/#post-2332030
|
||||
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/UILinearDodgeEffect")]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
public class UILinearDodgeEffect : MonoBehaviour
|
||||
{
|
||||
MaskableGraphic mGraphic;
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
SetMaterial();
|
||||
}
|
||||
|
||||
public void SetMaterial()
|
||||
{
|
||||
mGraphic = this.GetComponent<MaskableGraphic>();
|
||||
if (mGraphic != null)
|
||||
{
|
||||
if (mGraphic.material == null || mGraphic.material.name == "Default UI Material")
|
||||
{
|
||||
//Applying default material with UI Image Crop shader
|
||||
mGraphic.material = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/UILinearDodge"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Please attach component to a Graphical UI component");
|
||||
}
|
||||
}
|
||||
public void OnValidate()
|
||||
{
|
||||
SetMaterial();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4fbdc2185cba1c42ad07e43eea19561
|
||||
timeCreated: 1464643896
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,41 @@
|
||||
/// Credit 00christian00
|
||||
/// Sourced from - http://forum.unity3d.com/threads/any-way-to-show-part-of-an-image-without-using-mask.360085/#post-2332030
|
||||
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/UIMultiplyEffect")]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
public class UIMultiplyEffect : MonoBehaviour
|
||||
{
|
||||
MaskableGraphic mGraphic;
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
SetMaterial();
|
||||
}
|
||||
|
||||
public void SetMaterial()
|
||||
{
|
||||
mGraphic = this.GetComponent<MaskableGraphic>();
|
||||
if (mGraphic != null)
|
||||
{
|
||||
if (mGraphic.material == null || mGraphic.material.name == "Default UI Material")
|
||||
{
|
||||
//Applying default material with UI Image Crop shader
|
||||
mGraphic.material = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/UIMultiply"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Please attach component to a Graphical UI component");
|
||||
}
|
||||
}
|
||||
public void OnValidate()
|
||||
{
|
||||
SetMaterial();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a1216dfb98544e44afb7fb3abc093f2
|
||||
timeCreated: 1464643921
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,41 @@
|
||||
/// Credit 00christian00
|
||||
/// Sourced from - http://forum.unity3d.com/threads/any-way-to-show-part-of-an-image-without-using-mask.360085/#post-2332030
|
||||
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/UIScreenEffect")]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
public class UIScreenEffect : MonoBehaviour
|
||||
{
|
||||
MaskableGraphic mGraphic;
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
SetMaterial();
|
||||
}
|
||||
|
||||
public void SetMaterial()
|
||||
{
|
||||
mGraphic = this.GetComponent<MaskableGraphic>();
|
||||
if (mGraphic != null)
|
||||
{
|
||||
if (mGraphic.material == null || mGraphic.material.name == "Default UI Material")
|
||||
{
|
||||
//Applying default material with UI Image Crop shader
|
||||
mGraphic.material = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/UIScreen"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Please attach component to a Graphical UI component");
|
||||
}
|
||||
}
|
||||
public void OnValidate()
|
||||
{
|
||||
SetMaterial();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07afba72913387d488019cbb35ec1965
|
||||
timeCreated: 1464643319
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,41 @@
|
||||
/// Credit 00christian00
|
||||
/// Sourced from - http://forum.unity3d.com/threads/any-way-to-show-part-of-an-image-without-using-mask.360085/#post-2332030
|
||||
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[AddComponentMenu("UI/Effects/Extensions/UISoftAdditiveEffect")]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
public class UISoftAdditiveEffect : MonoBehaviour
|
||||
{
|
||||
MaskableGraphic mGraphic;
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
SetMaterial();
|
||||
}
|
||||
|
||||
public void SetMaterial()
|
||||
{
|
||||
mGraphic = this.GetComponent<MaskableGraphic>();
|
||||
if (mGraphic != null)
|
||||
{
|
||||
if (mGraphic.material == null || mGraphic.material.name == "Default UI Material")
|
||||
{
|
||||
//Applying default material with UI Image Crop shader
|
||||
mGraphic.material = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/UISoftAdditive"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Please attach component to a Graphical UI component");
|
||||
}
|
||||
}
|
||||
public void OnValidate()
|
||||
{
|
||||
SetMaterial();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 692867a1eddc7df419ec15b05b4084ec
|
||||
timeCreated: 1464643947
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,95 @@
|
||||
/// Credit ömer faruk sayılır
|
||||
/// Sourced from - https://bitbucket.org/snippets/Lordinarius/nrn4L
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
public class ShineEffect : MaskableGraphic
|
||||
{
|
||||
|
||||
[SerializeField]
|
||||
float yoffset = -1;
|
||||
|
||||
public float Yoffset
|
||||
{
|
||||
get
|
||||
{
|
||||
return yoffset;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetVerticesDirty();
|
||||
yoffset = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
float width = 1;
|
||||
|
||||
public float Width
|
||||
{
|
||||
get
|
||||
{
|
||||
return width;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetAllDirty();
|
||||
width = value;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPopulateMesh(VertexHelper vh)
|
||||
{
|
||||
var r = GetPixelAdjustedRect();
|
||||
var v = new Vector4(r.x, r.y, r.x + r.width, r.y + r.height);
|
||||
float dif = (v.w - v.y) * 2;
|
||||
Color32 color32 = color;
|
||||
vh.Clear();
|
||||
|
||||
color32.a = (byte)0;
|
||||
vh.AddVert(new Vector3(v.x - 50, width * v.y + yoffset * dif), color32, new Vector2(0f, 0f));
|
||||
vh.AddVert(new Vector3(v.z + 50, width * v.y + yoffset * dif), color32, new Vector2(1f, 0f));
|
||||
|
||||
color32.a = (byte)(color.a * 255);
|
||||
vh.AddVert(new Vector3(v.x - 50, width * (v.y / 4) + yoffset * dif), color32, new Vector2(0f, 1f));
|
||||
vh.AddVert(new Vector3(v.z + 50, width * (v.y / 4) + yoffset * dif), color32, new Vector2(1f, 1f));
|
||||
|
||||
color32.a = (byte)(color.a * 255);
|
||||
vh.AddVert(new Vector3(v.x - 50, width * (v.w / 4) + yoffset * dif), color32, new Vector2(0f, 1f));
|
||||
vh.AddVert(new Vector3(v.z + 50, width * (v.w / 4) + yoffset * dif), color32, new Vector2(1f, 1f));
|
||||
color32.a = (byte)(color.a * 255);
|
||||
|
||||
color32.a = (byte)0;
|
||||
vh.AddVert(new Vector3(v.x - 50, width * v.w + yoffset * dif), color32, new Vector2(0f, 1f));
|
||||
vh.AddVert(new Vector3(v.z + 50, width * v.w + yoffset * dif), color32, new Vector2(1f, 1f));
|
||||
|
||||
vh.AddTriangle(0, 1, 2);
|
||||
vh.AddTriangle(2, 3, 1);
|
||||
|
||||
vh.AddTriangle(2, 3, 4);
|
||||
vh.AddTriangle(4, 5, 3);
|
||||
|
||||
vh.AddTriangle(4, 5, 6);
|
||||
vh.AddTriangle(6, 7, 5);
|
||||
}
|
||||
|
||||
public void Triangulate(VertexHelper vh)
|
||||
{
|
||||
int triangleCount = vh.currentVertCount - 2;
|
||||
Debug.Log(triangleCount);
|
||||
for (int i = 0; i <= triangleCount / 2 + 1; i += 2)
|
||||
{
|
||||
vh.AddTriangle(i, i + 1, i + 2);
|
||||
vh.AddTriangle(i + 2, i + 3, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public override void OnRebuildRequested()
|
||||
{
|
||||
base.OnRebuildRequested();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 453baf32313c0bc41a532c409ec25177
|
||||
timeCreated: 1464388954
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,115 @@
|
||||
/// Credit ömer faruk sayılır
|
||||
/// Sourced from - https://bitbucket.org/snippets/Lordinarius/nrn4L
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[ExecuteInEditMode, RequireComponent(typeof(Image))]
|
||||
[AddComponentMenu("UI/Effects/Extensions/Shining Effect")]
|
||||
public class ShineEffector : MonoBehaviour
|
||||
{
|
||||
|
||||
public ShineEffect effector;
|
||||
[SerializeField, HideInInspector]
|
||||
GameObject effectRoot;
|
||||
[Range(-1, 1)]
|
||||
public float yOffset = -1;
|
||||
|
||||
public float YOffset
|
||||
{
|
||||
get
|
||||
{
|
||||
return yOffset;
|
||||
}
|
||||
set
|
||||
{
|
||||
ChangeVal(value);
|
||||
yOffset = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Range(0.1f, 1)]
|
||||
public float width = 0.5f;
|
||||
RectTransform effectorRect;
|
||||
void OnEnable()
|
||||
{
|
||||
if (effector == null)
|
||||
{
|
||||
GameObject effectorobj = new GameObject("effector");
|
||||
|
||||
effectRoot = new GameObject("ShineEffect");
|
||||
effectRoot.transform.SetParent(this.transform);
|
||||
effectRoot.AddComponent<Image>().sprite = gameObject.GetComponent<Image>().sprite;
|
||||
effectRoot.GetComponent<Image>().type = gameObject.GetComponent<Image>().type;
|
||||
effectRoot.AddComponent<Mask>().showMaskGraphic = false;
|
||||
effectRoot.transform.localScale = Vector3.one;
|
||||
effectRoot.GetComponent<RectTransform>().anchoredPosition3D = Vector3.zero;
|
||||
effectRoot.GetComponent<RectTransform>().anchorMax = Vector2.one;
|
||||
effectRoot.GetComponent<RectTransform>().anchorMin = Vector2.zero;
|
||||
effectRoot.GetComponent<RectTransform>().offsetMax = Vector2.zero;
|
||||
effectRoot.GetComponent<RectTransform>().offsetMin = Vector2.zero;
|
||||
effectRoot.transform.SetAsFirstSibling();
|
||||
|
||||
effectorobj.AddComponent<RectTransform>();
|
||||
effectorobj.transform.SetParent(effectRoot.transform);
|
||||
effectorRect = effectorobj.GetComponent<RectTransform>();
|
||||
effectorRect.localScale = Vector3.one;
|
||||
effectorRect.anchoredPosition3D = Vector3.zero;
|
||||
|
||||
effectorRect.gameObject.AddComponent<ShineEffect>();
|
||||
effectorRect.anchorMax = Vector2.one;
|
||||
effectorRect.anchorMin = Vector2.zero;
|
||||
|
||||
effectorRect.Rotate(0, 0, -8);
|
||||
effector = effectorobj.GetComponent<ShineEffect>();
|
||||
effectorRect.offsetMax = Vector2.zero;
|
||||
effectorRect.offsetMin = Vector2.zero;
|
||||
OnValidate();
|
||||
}
|
||||
}
|
||||
|
||||
void OnValidate()
|
||||
{
|
||||
effector.Yoffset = yOffset;
|
||||
effector.Width = width;
|
||||
|
||||
if (yOffset <= -1 || yOffset >= 1)
|
||||
{
|
||||
effectRoot.SetActive(false);
|
||||
}
|
||||
else if (!effectRoot.activeSelf)
|
||||
{
|
||||
effectRoot.SetActive(true);
|
||||
}
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ChangeVal(float value)
|
||||
{
|
||||
effector.Yoffset = value;
|
||||
if (value <= -1 || value >= 1)
|
||||
{
|
||||
effectRoot.SetActive(false);
|
||||
}
|
||||
else if (!effectRoot.activeSelf)
|
||||
{
|
||||
effectRoot.SetActive(true);
|
||||
}
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
void OnDestroy()
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
DestroyImmediate(effectRoot);
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(effectRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ced63edd65f3aed41a6c4125a5f54217
|
||||
timeCreated: 1464388991
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,112 @@
|
||||
/// Credit NemoKrad (aka Charles Humphrey) / valtain
|
||||
/// Sourced from - http://www.randomchaos.co.uk/SoftAlphaUIMask.aspx
|
||||
/// Updated by valtain - https://bitbucket.org/SimonDarksideJ/unity-ui-extensions/pull-requests/33
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
[AddComponentMenu("UI/Effects/Extensions/SoftMaskScript")]
|
||||
public class SoftMaskScript : MonoBehaviour
|
||||
{
|
||||
Material mat;
|
||||
|
||||
Canvas cachedCanvas = null;
|
||||
Transform cachedCanvasTransform = null;
|
||||
readonly Vector3[] m_WorldCorners = new Vector3[4];
|
||||
readonly Vector3[] m_CanvasCorners = new Vector3[4];
|
||||
|
||||
[Tooltip("The area that is to be used as the container.")]
|
||||
public RectTransform MaskArea;
|
||||
|
||||
[Tooltip("Texture to be used to do the soft alpha")]
|
||||
public Texture AlphaMask;
|
||||
|
||||
[Tooltip("At what point to apply the alpha min range 0-1")]
|
||||
[Range(0, 1)]
|
||||
public float CutOff = 0;
|
||||
|
||||
[Tooltip("Implement a hard blend based on the Cutoff")]
|
||||
public bool HardBlend = false;
|
||||
|
||||
[Tooltip("Flip the masks alpha value")]
|
||||
public bool FlipAlphaMask = false;
|
||||
|
||||
[Tooltip("If a different Mask Scaling Rect is given, and this value is true, the area around the mask will not be clipped")]
|
||||
public bool DontClipMaskScalingRect = false;
|
||||
|
||||
Vector2 maskOffset = Vector2.zero;
|
||||
Vector2 maskScale = Vector2.one;
|
||||
|
||||
// Use this for initialization
|
||||
void Start()
|
||||
{
|
||||
if (MaskArea == null)
|
||||
{
|
||||
MaskArea = GetComponent<RectTransform>();
|
||||
}
|
||||
|
||||
var text = GetComponent<Text>();
|
||||
if (text != null)
|
||||
{
|
||||
mat = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/SoftMaskShader"));
|
||||
text.material = mat;
|
||||
cachedCanvas = text.canvas;
|
||||
cachedCanvasTransform = cachedCanvas.transform;
|
||||
// For some reason, having the mask control on the parent and disabled stops the mouse interacting
|
||||
// with the texture layer that is not visible.. Not needed for the Image.
|
||||
if (transform.parent.GetComponent<Mask>() == null)
|
||||
transform.parent.gameObject.AddComponent<Mask>();
|
||||
|
||||
transform.parent.GetComponent<Mask>().enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var graphic = GetComponent<Graphic>();
|
||||
if (graphic != null)
|
||||
{
|
||||
mat = new Material(ShaderLibrary.GetShaderInstance("UI Extensions/SoftMaskShader"));
|
||||
graphic.material = mat;
|
||||
cachedCanvas = graphic.canvas;
|
||||
cachedCanvasTransform = cachedCanvas.transform;
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (cachedCanvas != null)
|
||||
{
|
||||
SetMask();
|
||||
}
|
||||
}
|
||||
|
||||
void SetMask()
|
||||
{
|
||||
var worldRect = GetCanvasRect();
|
||||
var size = worldRect.size;
|
||||
maskScale.Set(1.0f / size.x, 1.0f / size.y);
|
||||
maskOffset = -worldRect.min;
|
||||
maskOffset.Scale(maskScale);
|
||||
|
||||
mat.SetTextureOffset("_AlphaMask", maskOffset);
|
||||
mat.SetTextureScale("_AlphaMask", maskScale);
|
||||
mat.SetTexture("_AlphaMask", AlphaMask);
|
||||
|
||||
mat.SetFloat("_HardBlend", HardBlend ? 1 : 0);
|
||||
mat.SetInt("_FlipAlphaMask", FlipAlphaMask ? 1 : 0);
|
||||
mat.SetInt("_NoOuterClip", DontClipMaskScalingRect ? 1 : 0);
|
||||
mat.SetFloat("_CutOff", CutOff);
|
||||
}
|
||||
|
||||
public Rect GetCanvasRect()
|
||||
{
|
||||
if (cachedCanvas == null)
|
||||
return new Rect();
|
||||
|
||||
MaskArea.GetWorldCorners(m_WorldCorners);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
m_CanvasCorners[i] = cachedCanvasTransform.InverseTransformPoint(m_WorldCorners[i]);
|
||||
|
||||
return new Rect(m_CanvasCorners[0].x, m_CanvasCorners[0].y, m_CanvasCorners[2].x - m_CanvasCorners[0].x, m_CanvasCorners[2].y - m_CanvasCorners[0].y);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8ee60af491978345bc197ed4e1316bc
|
||||
timeCreated: 1448034177
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,78 @@
|
||||
/// Credit ChoMPHi
|
||||
/// Sourced from - http://forum.unity3d.com/threads/script-flippable-for-ui-graphics.291711/
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
[RequireComponent(typeof(RectTransform), typeof(Graphic)), DisallowMultipleComponent]
|
||||
[AddComponentMenu("UI/Effects/Extensions/Flippable")]
|
||||
public class UIFlippable : BaseMeshEffect
|
||||
{
|
||||
[SerializeField] private bool m_Horizontal = false;
|
||||
[SerializeField] private bool m_Veritical = false;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Awake()
|
||||
{
|
||||
OnValidate();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="UnityEngine.UI.UIFlippable"/> should be flipped horizontally.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if horizontal; otherwise, <c>false</c>.</value>
|
||||
public bool horizontal
|
||||
{
|
||||
get { return this.m_Horizontal; }
|
||||
set { this.m_Horizontal = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="UnityEngine.UI.UIFlippable"/> should be flipped vertically.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if vertical; otherwise, <c>false</c>.</value>
|
||||
public bool vertical
|
||||
{
|
||||
get { return this.m_Veritical; }
|
||||
set { this.m_Veritical = value; }
|
||||
}
|
||||
|
||||
public override void ModifyMesh(VertexHelper verts)
|
||||
{
|
||||
RectTransform rt = this.transform as RectTransform;
|
||||
|
||||
for (int i = 0; i < verts.currentVertCount; ++i)
|
||||
{
|
||||
UIVertex uiVertex = new UIVertex();
|
||||
verts.PopulateUIVertex(ref uiVertex,i);
|
||||
|
||||
// Modify positions
|
||||
uiVertex.position = new Vector3(
|
||||
(this.m_Horizontal ? (uiVertex.position.x + (rt.rect.center.x - uiVertex.position.x) * 2) : uiVertex.position.x),
|
||||
(this.m_Veritical ? (uiVertex.position.y + (rt.rect.center.y - uiVertex.position.y) * 2) : uiVertex.position.y),
|
||||
uiVertex.position.z
|
||||
);
|
||||
|
||||
// Apply
|
||||
verts.SetUIVertex(uiVertex, i);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate()
|
||||
{
|
||||
var components = gameObject.GetComponents(typeof(BaseMeshEffect));
|
||||
foreach (var comp in components)
|
||||
{
|
||||
if (comp.GetType() != typeof(UIFlippable))
|
||||
{
|
||||
UnityEditorInternal.ComponentUtility.MoveComponentUp(this);
|
||||
}
|
||||
else break;
|
||||
}
|
||||
this.GetComponent<Graphic>().SetVerticesDirty();
|
||||
base.OnValidate();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67f304b9bd84e9848bcfb79f47790081
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
@ -0,0 +1,410 @@
|
||||
/// Credit glennpow, Zarlang
|
||||
/// Sourced from - http://forum.unity3d.com/threads/free-script-particle-systems-in-ui-screen-space-overlay.406862/
|
||||
/// Updated by Zarlang with a more robust implementation, including TextureSheet animation support
|
||||
|
||||
namespace UnityEngine.UI.Extensions
|
||||
{
|
||||
#if UNITY_5_3_OR_NEWER
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(CanvasRenderer), typeof(ParticleSystem))]
|
||||
[AddComponentMenu("UI/Effects/Extensions/UIParticleSystem")]
|
||||
public class UIParticleSystem : MaskableGraphic
|
||||
{
|
||||
[Tooltip("Having this enabled run the system in LateUpdate rather than in Update making it faster but less precise (more clunky)")]
|
||||
public bool fixedTime = true;
|
||||
|
||||
[Tooltip("Enables 3d rotation for the particles")]
|
||||
public bool use3dRotation = false;
|
||||
|
||||
private Transform _transform;
|
||||
private ParticleSystem pSystem;
|
||||
private ParticleSystem.Particle[] particles;
|
||||
private UIVertex[] _quad = new UIVertex[4];
|
||||
private Vector4 imageUV = Vector4.zero;
|
||||
private ParticleSystem.TextureSheetAnimationModule textureSheetAnimation;
|
||||
private int textureSheetAnimationFrames;
|
||||
private Vector2 textureSheetAnimationFrameSize;
|
||||
private ParticleSystemRenderer pRenderer;
|
||||
private bool isInitialised = false;
|
||||
|
||||
private Material currentMaterial;
|
||||
|
||||
private Texture currentTexture;
|
||||
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
private ParticleSystem.MainModule mainModule;
|
||||
#endif
|
||||
|
||||
public override Texture mainTexture
|
||||
{
|
||||
get
|
||||
{
|
||||
return currentTexture;
|
||||
}
|
||||
}
|
||||
|
||||
protected bool Initialize()
|
||||
{
|
||||
// initialize members
|
||||
if (_transform == null)
|
||||
{
|
||||
_transform = transform;
|
||||
}
|
||||
if (pSystem == null)
|
||||
{
|
||||
pSystem = GetComponent<ParticleSystem>();
|
||||
|
||||
if (pSystem == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
mainModule = pSystem.main;
|
||||
if (pSystem.main.maxParticles > 14000)
|
||||
{
|
||||
mainModule.maxParticles = 14000;
|
||||
}
|
||||
#else
|
||||
if (pSystem.maxParticles > 14000)
|
||||
pSystem.maxParticles = 14000;
|
||||
#endif
|
||||
|
||||
pRenderer = pSystem.GetComponent<ParticleSystemRenderer>();
|
||||
if (pRenderer != null)
|
||||
pRenderer.enabled = false;
|
||||
|
||||
if (material == null)
|
||||
{
|
||||
var foundShader = ShaderLibrary.GetShaderInstance("UI Extensions/Particles/Additive");
|
||||
if (foundShader)
|
||||
{
|
||||
material = new Material(foundShader);
|
||||
}
|
||||
}
|
||||
|
||||
currentMaterial = material;
|
||||
if (currentMaterial && currentMaterial.HasProperty("_MainTex"))
|
||||
{
|
||||
currentTexture = currentMaterial.mainTexture;
|
||||
if (currentTexture == null)
|
||||
currentTexture = Texture2D.whiteTexture;
|
||||
}
|
||||
material = currentMaterial;
|
||||
// automatically set scaling
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
mainModule.scalingMode = ParticleSystemScalingMode.Hierarchy;
|
||||
#else
|
||||
pSystem.scalingMode = ParticleSystemScalingMode.Hierarchy;
|
||||
#endif
|
||||
|
||||
particles = null;
|
||||
}
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
if (particles == null)
|
||||
particles = new ParticleSystem.Particle[pSystem.main.maxParticles];
|
||||
#else
|
||||
if (particles == null)
|
||||
particles = new ParticleSystem.Particle[pSystem.maxParticles];
|
||||
#endif
|
||||
|
||||
imageUV = new Vector4(0, 0, 1, 1);
|
||||
|
||||
// prepare texture sheet animation
|
||||
textureSheetAnimation = pSystem.textureSheetAnimation;
|
||||
textureSheetAnimationFrames = 0;
|
||||
textureSheetAnimationFrameSize = Vector2.zero;
|
||||
if (textureSheetAnimation.enabled)
|
||||
{
|
||||
textureSheetAnimationFrames = textureSheetAnimation.numTilesX * textureSheetAnimation.numTilesY;
|
||||
textureSheetAnimationFrameSize = new Vector2(1f / textureSheetAnimation.numTilesX, 1f / textureSheetAnimation.numTilesY);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
if (!Initialize())
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
|
||||
protected override void OnPopulateMesh(VertexHelper vh)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
if (!Initialize())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// prepare vertices
|
||||
vh.Clear();
|
||||
|
||||
if (!gameObject.activeInHierarchy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isInitialised && !pSystem.main.playOnAwake)
|
||||
{
|
||||
pSystem.Stop(false, ParticleSystemStopBehavior.StopEmittingAndClear);
|
||||
isInitialised = true;
|
||||
}
|
||||
|
||||
Vector2 temp = Vector2.zero;
|
||||
Vector2 corner1 = Vector2.zero;
|
||||
Vector2 corner2 = Vector2.zero;
|
||||
// iterate through current particles
|
||||
int count = pSystem.GetParticles(particles);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
ParticleSystem.Particle particle = particles[i];
|
||||
|
||||
// get particle properties
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
Vector2 position = (mainModule.simulationSpace == ParticleSystemSimulationSpace.Local ? particle.position : _transform.InverseTransformPoint(particle.position));
|
||||
#else
|
||||
Vector2 position = (pSystem.simulationSpace == ParticleSystemSimulationSpace.Local ? particle.position : _transform.InverseTransformPoint(particle.position));
|
||||
#endif
|
||||
float rotation = -particle.rotation * Mathf.Deg2Rad;
|
||||
float rotation90 = rotation + Mathf.PI / 2;
|
||||
Color32 color = particle.GetCurrentColor(pSystem);
|
||||
float size = particle.GetCurrentSize(pSystem) * 0.5f;
|
||||
|
||||
// apply scale
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
if (mainModule.scalingMode == ParticleSystemScalingMode.Shape)
|
||||
position /= canvas.scaleFactor;
|
||||
#else
|
||||
if (pSystem.scalingMode == ParticleSystemScalingMode.Shape)
|
||||
position /= canvas.scaleFactor;
|
||||
#endif
|
||||
|
||||
// apply texture sheet animation
|
||||
Vector4 particleUV = imageUV;
|
||||
if (textureSheetAnimation.enabled)
|
||||
{
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
float frameProgress = 1 - (particle.remainingLifetime / particle.startLifetime);
|
||||
|
||||
if (textureSheetAnimation.frameOverTime.curveMin != null)
|
||||
{
|
||||
frameProgress = textureSheetAnimation.frameOverTime.curveMin.Evaluate(1 - (particle.remainingLifetime / particle.startLifetime));
|
||||
}
|
||||
else if (textureSheetAnimation.frameOverTime.curve != null)
|
||||
{
|
||||
frameProgress = textureSheetAnimation.frameOverTime.curve.Evaluate(1 - (particle.remainingLifetime / particle.startLifetime));
|
||||
}
|
||||
else if (textureSheetAnimation.frameOverTime.constant > 0)
|
||||
{
|
||||
frameProgress = textureSheetAnimation.frameOverTime.constant - (particle.remainingLifetime / particle.startLifetime);
|
||||
}
|
||||
#else
|
||||
float frameProgress = 1 - (particle.lifetime / particle.startLifetime);
|
||||
#endif
|
||||
|
||||
frameProgress = Mathf.Repeat(frameProgress * textureSheetAnimation.cycleCount, 1);
|
||||
int frame = 0;
|
||||
|
||||
switch (textureSheetAnimation.animation)
|
||||
{
|
||||
|
||||
case ParticleSystemAnimationType.WholeSheet:
|
||||
frame = Mathf.FloorToInt(frameProgress * textureSheetAnimationFrames);
|
||||
break;
|
||||
|
||||
case ParticleSystemAnimationType.SingleRow:
|
||||
frame = Mathf.FloorToInt(frameProgress * textureSheetAnimation.numTilesX);
|
||||
|
||||
int row = textureSheetAnimation.rowIndex;
|
||||
#if UNITY_2020 || UNITY_2019
|
||||
if (textureSheetAnimation.rowMode == ParticleSystemAnimationRowMode.Random)
|
||||
#else
|
||||
if (textureSheetAnimation.useRandomRow)
|
||||
#endif
|
||||
{ // FIXME - is this handled internally by rowIndex?
|
||||
row = Mathf.Abs((int)particle.randomSeed % textureSheetAnimation.numTilesY);
|
||||
}
|
||||
frame += row * textureSheetAnimation.numTilesX;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
frame %= textureSheetAnimationFrames;
|
||||
|
||||
particleUV.x = (frame % textureSheetAnimation.numTilesX) * textureSheetAnimationFrameSize.x;
|
||||
particleUV.y = 1.0f - ((frame / textureSheetAnimation.numTilesX) + 1) * textureSheetAnimationFrameSize.y;
|
||||
particleUV.z = particleUV.x + textureSheetAnimationFrameSize.x;
|
||||
particleUV.w = particleUV.y + textureSheetAnimationFrameSize.y;
|
||||
}
|
||||
|
||||
temp.x = particleUV.x;
|
||||
temp.y = particleUV.y;
|
||||
|
||||
_quad[0] = UIVertex.simpleVert;
|
||||
_quad[0].color = color;
|
||||
_quad[0].uv0 = temp;
|
||||
|
||||
temp.x = particleUV.x;
|
||||
temp.y = particleUV.w;
|
||||
_quad[1] = UIVertex.simpleVert;
|
||||
_quad[1].color = color;
|
||||
_quad[1].uv0 = temp;
|
||||
|
||||
temp.x = particleUV.z;
|
||||
temp.y = particleUV.w;
|
||||
_quad[2] = UIVertex.simpleVert;
|
||||
_quad[2].color = color;
|
||||
_quad[2].uv0 = temp;
|
||||
|
||||
temp.x = particleUV.z;
|
||||
temp.y = particleUV.y;
|
||||
_quad[3] = UIVertex.simpleVert;
|
||||
_quad[3].color = color;
|
||||
_quad[3].uv0 = temp;
|
||||
|
||||
if (rotation == 0)
|
||||
{
|
||||
// no rotation
|
||||
corner1.x = position.x - size;
|
||||
corner1.y = position.y - size;
|
||||
corner2.x = position.x + size;
|
||||
corner2.y = position.y + size;
|
||||
|
||||
temp.x = corner1.x;
|
||||
temp.y = corner1.y;
|
||||
_quad[0].position = temp;
|
||||
temp.x = corner1.x;
|
||||
temp.y = corner2.y;
|
||||
_quad[1].position = temp;
|
||||
temp.x = corner2.x;
|
||||
temp.y = corner2.y;
|
||||
_quad[2].position = temp;
|
||||
temp.x = corner2.x;
|
||||
temp.y = corner1.y;
|
||||
_quad[3].position = temp;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (use3dRotation)
|
||||
{
|
||||
// get particle properties
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
Vector3 pos3d = (mainModule.simulationSpace == ParticleSystemSimulationSpace.Local ? particle.position : _transform.InverseTransformPoint(particle.position));
|
||||
#else
|
||||
Vector3 pos3d = (pSystem.simulationSpace == ParticleSystemSimulationSpace.Local ? particle.position : _transform.InverseTransformPoint(particle.position));
|
||||
#endif
|
||||
|
||||
// apply scale
|
||||
#if UNITY_5_5_OR_NEWER
|
||||
if (mainModule.scalingMode == ParticleSystemScalingMode.Shape)
|
||||
position /= canvas.scaleFactor;
|
||||
#else
|
||||
if (pSystem.scalingMode == ParticleSystemScalingMode.Shape)
|
||||
position /= canvas.scaleFactor;
|
||||
#endif
|
||||
|
||||
Vector3[] verts = new Vector3[4]
|
||||
{
|
||||
new Vector3(-size, -size, 0),
|
||||
new Vector3(-size, size, 0),
|
||||
new Vector3(size, size, 0),
|
||||
new Vector3(size, -size, 0)
|
||||
};
|
||||
|
||||
Quaternion particleRotation = Quaternion.Euler(particle.rotation3D);
|
||||
|
||||
_quad[0].position = pos3d + particleRotation * verts[0];
|
||||
_quad[1].position = pos3d + particleRotation * verts[1];
|
||||
_quad[2].position = pos3d + particleRotation * verts[2];
|
||||
_quad[3].position = pos3d + particleRotation * verts[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
// apply rotation
|
||||
Vector2 right = new Vector2(Mathf.Cos(rotation), Mathf.Sin(rotation)) * size;
|
||||
Vector2 up = new Vector2(Mathf.Cos(rotation90), Mathf.Sin(rotation90)) * size;
|
||||
|
||||
_quad[0].position = position - right - up;
|
||||
_quad[1].position = position - right + up;
|
||||
_quad[2].position = position + right + up;
|
||||
_quad[3].position = position + right - up;
|
||||
}
|
||||
}
|
||||
|
||||
vh.AddUIVertexQuad(_quad);
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!fixedTime && Application.isPlaying)
|
||||
{
|
||||
pSystem.Simulate(Time.unscaledDeltaTime, false, false, true);
|
||||
SetAllDirty();
|
||||
|
||||
if ((currentMaterial != null && currentTexture != currentMaterial.mainTexture) ||
|
||||
(material != null && currentMaterial != null && material.shader != currentMaterial.shader))
|
||||
{
|
||||
pSystem = null;
|
||||
Initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
SetAllDirty();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fixedTime)
|
||||
{
|
||||
pSystem.Simulate(Time.unscaledDeltaTime, false, false, true);
|
||||
SetAllDirty();
|
||||
if ((currentMaterial != null && currentTexture != currentMaterial.mainTexture) ||
|
||||
(material != null && currentMaterial != null && material.shader != currentMaterial.shader))
|
||||
{
|
||||
pSystem = null;
|
||||
Initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (material == currentMaterial)
|
||||
return;
|
||||
pSystem = null;
|
||||
Initialize();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
currentMaterial = null;
|
||||
currentTexture = null;
|
||||
}
|
||||
|
||||
public void StartParticleEmission()
|
||||
{
|
||||
pSystem.time = 0;
|
||||
pSystem.Play();
|
||||
}
|
||||
|
||||
public void StopParticleEmission()
|
||||
{
|
||||
pSystem.Stop(false, ParticleSystemStopBehavior.StopEmittingAndClear);
|
||||
}
|
||||
|
||||
public void PauseParticleEmission()
|
||||
{
|
||||
pSystem.Stop(false, ParticleSystemStopBehavior.StopEmitting);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5f85388e938d9e4599afc6d9441ed57
|
||||
timeCreated: 1464383716
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user