渐变无法在 Unity3D GUI 对象上正确呈现
Gradient not rendering correctly on a Unity3D GUI object
我正在尝试对 Unity3D(5.2) gui 对象应用渐变效果,但好像其中一个渐变颜色键被完全忽略了。我尝试过实例化一个新的渐变场并声明一个渐变场 public 并在编辑器中编辑它的键,但效果保持不变。
我开始认为我不应该以我使用它的方式在 BaseMeshEffect 中使用渐变。如果只有 2 个键,颜色会正确呈现。我哪里错了?
这是一个代码示例,后面是一个屏幕截图。
public class GradientUI : BaseMeshEffect
{
[SerializeField]
public Gradient Grad;
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);
}
void ModifyVertices(List<UIVertex> vertexList)
{
int count = vertexList.Count;
float bottomY = vertexList[0].position.y;
float topY = vertexList[0].position.y;
for (int i = 1; i < count; i++)
{
float y = vertexList[i].position.y;
if (y > topY)
{
topY = y;
}
else if (y < bottomY)
{
bottomY = y;
}
}
float uiElementHeight = topY - bottomY;
for (int i = 0; i < count; i++)
{
UIVertex uiVertex = vertexList[i];
float percentage = (uiVertex.position.y - bottomY) / uiElementHeight;
// Debug.Log(percentage);
Color col = Grad.Evaluate(percentage);
uiVertex.color = col;
vertexList[i] = uiVertex;
Debug.Log(uiVertex.position);
}
}
你的脚本其实没问题,没问题。这里的问题是 UI 元素根本没有足够的几何形状让您实际看到整个渐变。
让我解释一下。简而言之,每个 UI 元素实际上是由几个 3D 三角形组成的网格,每个三角形都旋转以使其正面完全面向相机,因此它看起来是 2D 的。您通过为这些三角形的每个顶点分配一个颜色值来过滤作品。三角形中间的颜色值根据与每个彩色顶点的接近度进行插值。
如果您查看线框图中的 UI 元素,您会发现它的几何结构非常简单。这是例如切片图像的外观:
可以看到,它所有的顶点都集中在角上,中间没有顶点。因此,假设您的渐变是 2 个键 WHITE=>RED。上方顶点的值为白色或接近白色,下方的顶点值为红色或接近红色。这适用于 2 个键。
现在假设您有 3 个键 WHITE=>BLUE=>RED。上面的值是白色或接近白色,下面的值是红色或接近红色,蓝色值应该在中间的某个地方,但中间没有顶点,所以它没有分配给任何东西。所以你仍然得到白色到红色的渐变。
现在,您可以做什么:
1) 您可以通过编程方式添加更多几何图形,例如通过简单地细分整个网格。这可能对您有帮助:http://answers.unity3d.com/questions/259127/does-anyone-have-any-code-to-subdivide-a-mesh-and.html。注意,在这种情况下,你的渐变键越多,需要细分的次数就越多。
2) 使用看起来像渐变渐变的纹理。
我正在尝试对 Unity3D(5.2) gui 对象应用渐变效果,但好像其中一个渐变颜色键被完全忽略了。我尝试过实例化一个新的渐变场并声明一个渐变场 public 并在编辑器中编辑它的键,但效果保持不变。 我开始认为我不应该以我使用它的方式在 BaseMeshEffect 中使用渐变。如果只有 2 个键,颜色会正确呈现。我哪里错了?
这是一个代码示例,后面是一个屏幕截图。
public class GradientUI : BaseMeshEffect
{
[SerializeField]
public Gradient Grad;
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);
}
void ModifyVertices(List<UIVertex> vertexList)
{
int count = vertexList.Count;
float bottomY = vertexList[0].position.y;
float topY = vertexList[0].position.y;
for (int i = 1; i < count; i++)
{
float y = vertexList[i].position.y;
if (y > topY)
{
topY = y;
}
else if (y < bottomY)
{
bottomY = y;
}
}
float uiElementHeight = topY - bottomY;
for (int i = 0; i < count; i++)
{
UIVertex uiVertex = vertexList[i];
float percentage = (uiVertex.position.y - bottomY) / uiElementHeight;
// Debug.Log(percentage);
Color col = Grad.Evaluate(percentage);
uiVertex.color = col;
vertexList[i] = uiVertex;
Debug.Log(uiVertex.position);
}
}
你的脚本其实没问题,没问题。这里的问题是 UI 元素根本没有足够的几何形状让您实际看到整个渐变。
让我解释一下。简而言之,每个 UI 元素实际上是由几个 3D 三角形组成的网格,每个三角形都旋转以使其正面完全面向相机,因此它看起来是 2D 的。您通过为这些三角形的每个顶点分配一个颜色值来过滤作品。三角形中间的颜色值根据与每个彩色顶点的接近度进行插值。
如果您查看线框图中的 UI 元素,您会发现它的几何结构非常简单。这是例如切片图像的外观:
可以看到,它所有的顶点都集中在角上,中间没有顶点。因此,假设您的渐变是 2 个键 WHITE=>RED。上方顶点的值为白色或接近白色,下方的顶点值为红色或接近红色。这适用于 2 个键。
现在假设您有 3 个键 WHITE=>BLUE=>RED。上面的值是白色或接近白色,下面的值是红色或接近红色,蓝色值应该在中间的某个地方,但中间没有顶点,所以它没有分配给任何东西。所以你仍然得到白色到红色的渐变。
现在,您可以做什么:
1) 您可以通过编程方式添加更多几何图形,例如通过简单地细分整个网格。这可能对您有帮助:http://answers.unity3d.com/questions/259127/does-anyone-have-any-code-to-subdivide-a-mesh-and.html。注意,在这种情况下,你的渐变键越多,需要细分的次数就越多。
2) 使用看起来像渐变渐变的纹理。