Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

VertexHelper.AddUIVertexTriangleStream() - Bug or misuse?

Discussion in 'UGUI & TextMesh Pro' started by Senshi, Nov 3, 2015.

  1. Senshi

    Senshi

    Joined:
    Oct 3, 2010
    Posts:
    556
    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:

    Code (CSharp):
    1. protected override void OnPopulateMesh(VertexHelper vh){
    2.     vh.Clear();
    3.     List<UIVertex> l1 = elements[0].GetUIVertexTriangleStream(...);
    4.     List<UIVertex> l2 = elements[1].GetUIVertexTriangleStream(...);
    5.     vh.AddUIVertexTriangleStream(l1);
    6.     vh.AddUIVertexTriangleStream(l2);
    7. }
    Running this code only shows the triangles described in l2, whereas the following works as expected:

    Code (CSharp):
    1. protected override void OnPopulateMesh(VertexHelper vh){
    2.     vh.Clear();
    3.     List<UIVertex> l1 = elements[0].GetUIVertexTriangleStream(...);
    4.     List<UIVertex> l2 = elements[1].GetUIVertexTriangleStream(...);
    5.     vh.AddUIVertexTriangleStream(l1.Concat(l2).ToList());
    6. }
    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. ;)

    As always, thanks in advance!
     
  2. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,683
    If you check the source for the VertexHelper
    (https://bitbucket.org/Unity-Technol...ine.UI/UI/Core/Utility/VertexHelper.cs?at=5.2

    I think the function you actually want is the AddUIVertexStream function as shown below:
    Code (CSharp):
    1.         public void AddUIVertexStream(List<UIVertex> verts, List<int> indicies)
    2.         {
    3.             if (verts != null)
    4.             {
    5.                 CanvasRenderer.AddUIVertexStream(verts, m_Positions, m_Colors, m_Uv0S, m_Uv1S, m_Normals, m_Tangents);
    6.             }
    7.  
    8.             if (indicies != null)
    9.             {
    10.                 m_Indicies.AddRange(indicies);
    11.             }
    12.         }
    13.  
    14.         public void AddUIVertexTriangleStream(List<UIVertex> verts)
    15.         {
    16.             CanvasRenderer.SplitUIVertexStreams(verts, m_Positions, m_Colors, m_Uv0S, m_Uv1S, m_Normals, m_Tangents, m_Indicies);
    17.         }
    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.
     
  3. Senshi

    Senshi

    Joined:
    Oct 3, 2010
    Posts:
    556
    @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:

    Code (CSharp):
    1. List<List<UIVertex>> uiVertexTriangleStreams = new List<List<UIVertex>>(elements.Count);
    2.  
    3. for(int i=0; i<elements.Count; i++){
    4.     uiVertexTriangleStreams.Add(elements[i].GetUIVertexTriangleStream(...));
    5. }
    6.  
    7. 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.

    Code (CSharp):
    1. protected override void OnPopulateMesh(VertexHelper vh){
    2.     vh.Clear();
    3.  
    4.     List<UIVertex> verts = new List<UIVertex>();
    5.     UIVertex v1 = UIVertex.simpleVert;
    6.     UIVertex v2 = UIVertex.simpleVert;
    7.     UIVertex v3 = UIVertex.simpleVert;
    8.     UIVertex v4 = UIVertex.simpleVert;
    9.     v1.position = new Vector3(0f, 0f, 0f);
    10.     v2.position = new Vector3(100f, 0f, 0f);
    11.     v3.position = new Vector3(100f, 100f, 0f);
    12.     v4.position = new Vector3(0f, 100f, 0f);
    13.     verts.Add(v1);
    14.     verts.Add(v2);
    15.     verts.Add(v3);
    16.     verts.Add(v4);
    17.     List<int> ind = new List<int>(new int[]{0,1,2,0,2,3});
    18.     vh.AddUIVertexStream(verts, ind);
    19.  
    20.     List<UIVertex> _verts = new List<UIVertex>();
    21.     UIVertex _v1 = UIVertex.simpleVert;
    22.     UIVertex _v2 = UIVertex.simpleVert;
    23.     UIVertex _v3 = UIVertex.simpleVert;
    24.     UIVertex _v4 = UIVertex.simpleVert;
    25.     _v1.position = new Vector3(-200f, -200f, 0f);
    26.     _v2.position = new Vector3(-100f, -200f, 0f);
    27.     _v3.position = new Vector3(-100f, -100f, 0f);
    28.     _v4.position = new Vector3(-200f, -100f, 0f);
    29.     _verts.Add(_v1);
    30.     _verts.Add(_v2);
    31.     _verts.Add(_v3);
    32.     _verts.Add(_v4);
    33.     List<int> _ind = new List<int>(new int[]{0,1,2,0,2,3});
    34.     vh.AddUIVertexStream(_verts, _ind);
     
  4. Drapan

    Drapan

    Joined:
    Apr 9, 2013
    Posts:
    14
    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.
     
  5. Senshi

    Senshi

    Joined:
    Oct 3, 2010
    Posts:
    556
    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.