/// <summary>
    /// Rebuild the UI.
    /// </summary>

    void LateUpdate()
    {
        if (mWidgets == null)
        {
            return;
        }

        // Update all widgets
        for (int i = mWidgets.Count; i > 0;)
        {
            SGWidget w = mWidgets[--i];
            if (w == null)
            {
                mWidgets.RemoveAt(i);
            }
            else
            {
                mRebuild |= w.ScreenUpdate();
            }
        }

        // No need to keep this screen if we don't have any widgets left
        if (mWidgets.Count == 0)
        {
            if (Application.isPlaying)
            {
                Destroy(gameObject);
                return;
            }

            if (mMesh != null)
            {
                DestroyImmediate(mMesh);
                mMesh = null;
            }
            if (this != null)
            {
                DestroyImmediate(gameObject);
            }
            return;
        }

        // Only continue if we need to rebuild
        if (!mRebuild)
        {
            return;
        }

        // Sort all widgets back-to-front
        mWidgets.Sort(SGWidget.CompareFunc);

        // Cache all components
        if (mFilter == null)
        {
            mFilter = gameObject.GetComponent <MeshFilter>();
        }
        if (mFilter == null)
        {
            mFilter = gameObject.AddComponent <MeshFilter>();
        }
        if (mRen == null)
        {
            mRen = gameObject.GetComponent <MeshRenderer>();
        }

        if (mRen == null)
        {
            mRen = gameObject.AddComponent <MeshRenderer>();
            mRen.sharedMaterial = mMat;
        }

        // Fill the vertices and UVs
        foreach (SGWidget w in mWidgets)
        {
            int offset = mVerts.Count;
            w.OnFill(mVerts, mUvs, mCols);

            // Transform all vertices into world space
            Transform t = w.mTrans;

            for (int i = offset, imax = mVerts.Count; i < imax; ++i)
            {
                mVerts[i] = t.TransformPoint(mVerts[i]);
            }
        }
        int count = mVerts.Count;

        // Safety check to ensure we get valid values
        if (count > 0 && (count == mUvs.Count && count == mCols.Count) && (count % 4) == 0)
        {
            int index = 0;

            // It takes 6 indices to draw a quad of 4 vertices
            int[] indices = new int[(count >> 1) * 3];

            // Populate the index buffer
            for (int i = 0; i < count; i += 4)
            {
                indices[index++] = i;
                indices[index++] = i + 1;
                indices[index++] = i + 2;

                indices[index++] = i + 2;
                indices[index++] = i + 3;
                indices[index++] = i;
            }

            if (mMesh == null)
            {
                mMesh      = new Mesh();
                mMesh.name = "UIScreen for " + mMat.name;
            }
            else
            {
                mMesh.Clear();
            }

            // Set the mesh values
            mMesh.vertices  = mVerts.ToArray();
            mMesh.uv        = mUvs.ToArray();
            mMesh.colors    = mCols.ToArray();
            mMesh.triangles = indices;
            mMesh.RecalculateBounds();
            mFilter.mesh = mMesh;
        }
        else
        {
            Debug.LogError("UIWidgets must fill the buffer with 4 vertices per quad. Found " + count);
        }

        // Cleanup
        mVerts.Clear();
        mUvs.Clear();
        mCols.Clear();

        // Don't rebuild the screen next frame
        mRebuild = false;
    }