- Home /
Gradient Text in Unity 5.2.2 "BaseVertexEffect is obsolete use BaseMeshEffect instead"
Hello! I recently upgraded Unity to 5.2.2 and ran into an issue with my current gradient script. Somebody was nice enough to upload this for everyone, so I did not write it myself.
You can find it here... https://www.reddit.com/r/Unity3D/comments/2ephku/unity_46_text_gradient_effect/
This being said, I'm not fully aware of how things work with BaseVertexEffect or how to move it over to BaseMeshEffect. I'm fairly new to programming, so I struggle to find solutions to stuff like this. I saw a post about it here...
http://forum.unity3d.com/threads/basevertexeffect-change-to-basemesheffect.338455/
There is a suggestion offered that seemed to work for some people, but I am not sure how to apply that to the script I'm using. I don't know if it would work for mine, or if there is a better script I should be using. Any help is appreciated. Thanks.
Answer by koshik · Oct 23, 2015 at 11:56 AM
I just hit the same issue and here's my update:
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.UI;
[AddComponentMenu("UI/Effects/Gradient")]
public class Gradient : BaseMeshEffect
{
public Color32 topColor = Color.white;
public Color32 bottomColor = Color.black;
public override void ModifyMesh(VertexHelper helper)
{
if (!IsActive() || helper.currentVertCount == 0)
return;
List<UIVertex> vertices = new List<UIVertex>();
helper.GetUIVertexStream(vertices);
float bottomY = vertices[0].position.y;
float topY = vertices[0].position.y;
for (int i = 1; i < vertices.Count; i++)
{
float y = vertices[i].position.y;
if (y > topY)
{
topY = y;
}
else if (y < bottomY)
{
bottomY = y;
}
}
float uiElementHeight = topY - bottomY;
UIVertex v = new UIVertex();
for (int i = 0; i < helper.currentVertCount; i++)
{
helper.PopulateUIVertex(ref v, i);
v.color = Color32.Lerp(bottomColor, topColor, (v.position.y - bottomY) / uiElementHeight);
helper.SetUIVertex(v, i);
}
}
}
I'd also like to say thanks, this is a good update!
Answer by DanielEsposito · Nov 25, 2015 at 08:56 PM
More optional script:
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.UI;
[AddComponentMenu("UI/Effects/Gradient")]
public class Gradient : BaseMeshEffect
{
public enum Type
{
Vertical,
Horizontal
}
[SerializeField]
public Type GradientType = Type.Vertical;
[SerializeField]
[Range(-1.5f, 1.5f)]
public float Offset = 0f;
[SerializeField]
private Color32 StartColor = Color.white;
[SerializeField]
private Color32 EndColor = Color.black;
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.Vertical:
{
float fBottomY = _vertexList [0].position.y;
float fTopY = _vertexList [0].position.y;
float fYPos = 0f;
for (int i = nCount - 1; i >= 1; --i) {
fYPos = _vertexList [i].position.y;
if (fYPos > fTopY)
fTopY = fYPos;
else if (fYPos < fBottomY)
fBottomY = fYPos;
}
float fUIElementHeight = 1f / (fTopY - fBottomY);
UIVertex v = new UIVertex ();
for (int i = 0; i < helper.currentVertCount; i++) {
helper.PopulateUIVertex (ref v, i);
v.color = Color32.Lerp (EndColor, StartColor, (v.position.y - fBottomY) * fUIElementHeight - Offset);
helper.SetUIVertex (v, i);
}
}
break;
case Type.Horizontal:
{
float fLeftX = _vertexList [0].position.x;
float fRightX = _vertexList [0].position.x;
float fXPos = 0f;
for (int i = nCount - 1; i >= 1; --i) {
fXPos = _vertexList [i].position.x;
if (fXPos > fRightX)
fRightX = fXPos;
else if (fXPos < fLeftX)
fLeftX = fXPos;
}
float fUIElementWidth = 1f / (fRightX - fLeftX);
UIVertex v = new UIVertex ();
for (int i = 0; i < helper.currentVertCount; i++) {
helper.PopulateUIVertex (ref v, i);
v.color = Color32.Lerp (EndColor, StartColor, (v.position.x - fLeftX) * fUIElementWidth - Offset);
helper.SetUIVertex (v, i);
}
}
break;
default:
break;
}
}
}
$$anonymous$$y goal was just a quick fix - thanks for extending it :)
I noticed that after this update each letter is rendered as a separate mesh (previously the the whole text was rendered on one rectangle). That gives even more possibilities!
It's work with 5.3. But override "shadow" and "ouline" effects.
$$anonymous$$ove the Gradient component above Shadow and Outline in the object's Inspector.
Any chance per-line gradient is possible, ins$$anonymous$$d of gradient over entire paragraph?
Answer by GibTreaty · Apr 30, 2016 at 07:19 PM
Modified @DanielEsposito's version to use Unity's Gradient class for the coloring/alpha and added a few blend modes so that the colors can blend with other effects.
I've also put it on pastebin http://pastebin.com/WwUh3eZg
using System.Collections.Generic;
/// <summary>
/// Modified Gradient effect script from http://answers.unity3d.com/questions/1086415/gradient-text-in-unity-522-basevertexeffect-is-obs.html
/// -Uses Unity's Gradient class to define the color
/// -Offset is now limited to -1,1
/// -Multiple color blend modes
///
/// Remember that the 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>
namespace UnityEngine.UI {
[AddComponentMenu("UI/Effects/Gradient")]
public class Gradient : BaseMeshEffect {
[SerializeField]
Type _gradientType;
[SerializeField]
Blend _blendMode = Blend.Multiply;
[SerializeField]
[Range(-1, 1)]
float _offset = 0f;
[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; }
}
public UnityEngine.Gradient EffectGradient {
get { return _effectGradient; }
set { _effectGradient = value; }
}
public Type GradientType {
get { return _gradientType; }
set { _gradientType = value; }
}
public float Offset {
get { return _offset; }
set { _offset = value; }
}
#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: {
float left = _vertexList[0].position.x;
float right = _vertexList[0].position.x;
float x = 0f;
for(int i = nCount - 1; i >= 1; --i) {
x = _vertexList[i].position.x;
if(x > right) right = x;
else if(x < left) left = x;
}
float width = 1f / (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));
helper.SetUIVertex(vertex, i);
}
}
break;
case Type.Vertical: {
float bottom = _vertexList[0].position.y;
float top = _vertexList[0].position.y;
float y = 0f;
for(int i = nCount - 1; i >= 1; --i) {
y = _vertexList[i].position.y;
if(y > top) top = y;
else if(y < bottom) bottom = y;
}
float height = 1f / (top - bottom);
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.y - bottom) * height - Offset));
helper.SetUIVertex(vertex, i);
}
}
break;
}
}
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
}
public enum Blend {
Override,
Add,
Multiply
}
}
}
The issue there is that there aren't enough vertices for it to color between so it's only coloring from the left and right sides of the gradient. :( I don't know any way around that.