VertexHelper.AddUIVertexTriangleStream() - Bug or misuse?

Hi all,

In updating my UI asset for Unity 5.2.2 I noticed something odd, namely that only the last triangle stream added gets drawn. For example:

protected override void OnPopulateMesh(VertexHelper vh){
    vh.Clear();
    List<UIVertex> l1 = elements[0].GetUIVertexTriangleStream(...);
    List<UIVertex> l2 = elements[1].GetUIVertexTriangleStream(...);
    vh.AddUIVertexTriangleStream(l1);
    vh.AddUIVertexTriangleStream(l2);
}

Running this code only shows the triangles described in l2, whereas the following works as expected:

protected override void OnPopulateMesh(VertexHelper vh){
    vh.Clear();
    List<UIVertex> l1 = elements[0].GetUIVertexTriangleStream(...);
    List<UIVertex> l2 = elements[1].GetUIVertexTriangleStream(...);
    vh.AddUIVertexTriangleStream(l1.Concat(l2).ToList());
}

I would have expected VertexHelper.AddUIVertexTriangleStream() to be additive, but instead it seems to replace the entire stream. And since the documentation on this is a bit… let’s call it sparse, I figured I’d ask here first. :wink:

As always, thanks in advance!

1 Like

If you check the source for the VertexHelper
(https://bitbucket.org/Unity-Technologies/ui/src/a5f41955ad119e1708b79f10154009c984992769/UnityEngine.UI/UI/Core/Utility/VertexHelper.cs?at=5.2

I think the function you actually want is the AddUIVertexStream function as shown below:

        public void AddUIVertexStream(List<UIVertex> verts, List<int> indicies)
        {
            if (verts != null)
            {
                CanvasRenderer.AddUIVertexStream(verts, m_Positions, m_Colors, m_Uv0S, m_Uv1S, m_Normals, m_Tangents);
            }

            if (indicies != null)
            {
                m_Indicies.AddRange(indicies);
            }
        }

        public void AddUIVertexTriangleStream(List<UIVertex> verts)
        {
            CanvasRenderer.SplitUIVertexStreams(verts, m_Positions, m_Colors, m_Uv0S, m_Uv1S, m_Normals, m_Tangents, m_Indicies);
        }

Which seems to indicate it’s an additive function against the CanvasRenderer. It doesn’t seem clear what the SplitUIVertexStreams function does but from your example, it does seem to overwrite the current UI Mesh for the object with the new content.

@SimonDarksideJ Hey Simon! Thanks, I did indeed miss that one! I just gave it a try though, and I am getting the exact same results for it. I also tried creating an entirely new List reference and instance, thinking it may be holding on to it or something, but no dice. Only the last stream added is actually drawn.

I’m definitely starting to think this is a bug, though I’m afraid Unity will fix it and I’ll have to submit yet another version for 5.2.2p2. T_T

My real-world solution for now is to first collect all seperate lists first and then combine them, like so:

List<List<UIVertex>> uiVertexTriangleStreams = new List<List<UIVertex>>(elements.Count);

for(int i=0; i<elements.Count; i++){
    uiVertexTriangleStreams.Add(elements[i].GetUIVertexTriangleStream(...));
}

vh.AddUIVertexTriangleStream(uiVertexTriangleStreams.SelectMany(l => l).ToList());

And if anyone wants to confirm the described behaviour for themselves, here is the sample code I used.

protected override void OnPopulateMesh(VertexHelper vh){
    vh.Clear();

    List<UIVertex> verts = new List<UIVertex>();
    UIVertex v1 = UIVertex.simpleVert;
    UIVertex v2 = UIVertex.simpleVert;
    UIVertex v3 = UIVertex.simpleVert;
    UIVertex v4 = UIVertex.simpleVert;
    v1.position = new Vector3(0f, 0f, 0f);
    v2.position = new Vector3(100f, 0f, 0f);
    v3.position = new Vector3(100f, 100f, 0f);
    v4.position = new Vector3(0f, 100f, 0f);
    verts.Add(v1);
    verts.Add(v2);
    verts.Add(v3);
    verts.Add(v4);
    List<int> ind = new List<int>(new int[]{0,1,2,0,2,3});
    vh.AddUIVertexStream(verts, ind);

    List<UIVertex> _verts = new List<UIVertex>();
    UIVertex _v1 = UIVertex.simpleVert;
    UIVertex _v2 = UIVertex.simpleVert;
    UIVertex _v3 = UIVertex.simpleVert;
    UIVertex _v4 = UIVertex.simpleVert;
    _v1.position = new Vector3(-200f, -200f, 0f);
    _v2.position = new Vector3(-100f, -200f, 0f);
    _v3.position = new Vector3(-100f, -100f, 0f);
    _v4.position = new Vector3(-200f, -100f, 0f);
    _verts.Add(_v1);
    _verts.Add(_v2);
    _verts.Add(_v3);
    _verts.Add(_v4);
    List<int> _ind = new List<int>(new int[]{0,1,2,0,2,3});
    vh.AddUIVertexStream(_verts, _ind);

Just ran in to the same issue. Has this been fixed in versions above 5.2.2? Can’t find it in the issue tracker, so I’m guessing no, but you never know.

Honestly I think I completely forgot to create an official bug report for this, so it wouldn’t surprise me if it was still present. Don’t have a 5.2.2+ Unity to test on though.