Unity – 渐变文字

【实现】

[AddComponentMenu("UI/Effects/Gradient")]
public class Gradient : BaseMeshEffect
{
public enum Type
{
Horizontal,
Vertical,
}

public enum Blend
{
Override,
Add,
Multiply,
}

[SerializeField]
private Type m_GradientType = Type.Vertical;
[SerializeField]
private Blend m_BlendMode = Blend.Override;
[SerializeField]
[Range(-1, 1)]
private float m_Offset = 0;
[SerializeField]
private UnityEngine.Gradient m_effectGradient
= new UnityEngine.Gradient()
{
colorKeys = new GradientColorKey[] {
new GradientColorKey(Color.black, 0),
new GradientColorKey(Color.white, 1)}
};

private Text m_Text;

protected override void OnEnable()
{
m_Text = GetComponent<Text>();
}

public override void ModifyMesh(VertexHelper helper)
{
if (!IsActive() || helper.currentVertCount == 0)
return;

List<UIVertex> vertexList = new List<UIVertex>();
helper.GetUIVertexStream(vertexList);

int count = vertexList.Count;
switch (GradientType)
{
case Type.Horizontal:
float left = vertexList[0].position.x;
float right = vertexList[0].position.x;
float x = 0;
for (int i = count - 1; i >= 1; --i)
{
x = vertexList[i].position.x;

if (x > right)
right = x;
else if (x < left)
left = x;
}

float width = right - left;
UIVertex vertex = new UIVertex();

for (int i = 0; i < helper.currentVertCount; i++)
{
helper.PopulateUIVertex(ref vertex, i);

vertex.color = BlendColor(vertex.color,
EffectGradient.Evaluate((vertex.position.x - left) / width - Offset));
vertex.color.a = (byte)(m_Text.color.a * 255);
helper.SetUIVertex(vertex, i);
}
break;
case Type.Vertical:
float top = vertexList[0].position.y;
float bottom = vertexList[0].position.y;
float y = 0;
for (int i = count - 1; i >= 1; --i)
{
y = vertexList[i].position.y;

if (y > top)
top = y;
else if (y < bottom)
bottom = y;
}

float height = top - bottom;
UIVertex vertex2 = new UIVertex();

for (int i = 0; i < helper.currentVertCount; i++)
{
helper.PopulateUIVertex(ref vertex2, i);

vertex2.color = BlendColor(vertex2.color,
EffectGradient.Evaluate((vertex2.position.y - bottom) / height - Offset));
vertex2.color.a = (byte)(m_Text.color.a * 255);
helper.SetUIVertex(vertex2, i);
}
break;
}
}

Color BlendColor(Color colorA, Color colorB)
{
switch (BlendMode)
{
case Blend.Add:
return colorA + colorB;
case Blend.Multiply:
return colorA * colorB;
default:
return colorB;
}
}
}

【问题】

  1. 如果Text需要使用Outline和Shadow组件,需要将他们放在Gradient组件下面,否则上面两个组件的效果会被覆盖掉。
  2. 由于我给字体添加了DotweenAnimation组件用于制作Text的透明度动画,所以Gradient组件需要更新自己的透明度,与Text组件中的值统一。(蓝字部分)

【参考】

1. Unity5.X中渐变字体的实现方法

2.Unity2017中渐变字体的实现方法

Add a Comment

您的电子邮箱地址不会被公开。 必填项已用*标注