protected override void GenerateTextMesh()
        {
            if (!m_textFxAnimDrawCall || _forceNativeDrawCall)
            {
                _forceNativeDrawCall = false;

                // Text has changed, need to update mesh verts and re-cache them

                base.GenerateTextMesh();

                _strippedText = richText ? TextFxHelperMethods.StripRichTextCode(text) : text;
                _rawMeshChars = _strippedText.Replace("\n", string.Empty);

                _numRenderedLetters = _rawMeshChars.Length - m_textInfo.spaceCount;

                // Update current mesh vert/colour state
                m_currentVerts = new Vector3[_numRenderedLetters * 4];
                for (int idx = 0; idx < _numRenderedLetters * 4; idx++)
                {
                    m_currentVerts [idx] = m_textInfo.meshInfo [0].vertices [idx];
                }

                m_currentColours = new Color32[_numRenderedLetters * 4];
                for (int idx = 0; idx < _numRenderedLetters * 4; idx++)
                {
                    m_currentColours [idx] = m_textInfo.meshInfo [0].colors32 [idx];
                }

                // Call to update animation letter setups
                m_animation_manager.UpdateText(_strippedText,
                                               new TMPTextDataHandler(m_currentVerts, m_currentColours, _numRenderedLetters),
                                               white_space_meshes: false);

                if (m_animation_manager.CheckCurveData())
                {
                    // Update mesh values to latest using new curve offset values
                    m_animation_manager.PopulateDefaultMeshData(true);

                    _vertsToUse = m_animation_manager.MeshVerts;

                    // Re-assign latest meshInfo to mesh
                    if (_vertsToUse.Length == mesh.vertexCount)
                    {
                        mesh.vertices = _vertsToUse;

                        m_currentVerts = _vertsToUse;
                    }
                    else if (mesh.vertexCount > _vertsToUse.Length)
                    {
                        if (m_currentVerts.Length != mesh.vertexCount)
                        {
                            m_currentVerts = new Vector3[mesh.vertexCount];
                        }

                        for (int idx = 0; idx < _vertsToUse.Length; idx++)
                        {
                            m_currentVerts [idx] = _vertsToUse [idx];
                        }

                        mesh.vertices = m_currentVerts;
                    }

                    if (m_canvasRendererComp != null)
                    {
                        m_canvasRendererComp.SetMesh(mesh);
                    }
                }


                if (Application.isPlaying ||
                    m_animation_manager.Playing                                                 // Animation is playing, so will now need to render this new mesh in the current animated state
                                        #if UNITY_EDITOR
                    || TextFxAnimationManager.ExitingPlayMode                                   // To stop text being auto rendered in to default position when exiting play mode in editor.
                                        #endif
                    )
                {
                    // The verts need to be set to their current animated states
                    // So recall OnFill, getting it to populate with whatever available animate mesh data for this frame
                    m_textFxAnimDrawCall = true;

                    // Update animated mesh values to latest
                    m_animation_manager.UpdateMesh(true, true, delta_time: 0);

                    GenerateTextMesh();
                    return;
                }
            }
            else
            {
                _vertsToUse = m_animation_manager.MeshVerts;
                if (_colsToUse == null || _colsToUse.Length != m_animation_manager.MeshColours.Length)
                {
                    _colsToUse = new Color32[m_animation_manager.MeshColours.Length];
                }

                for (int idx = 0; idx < _colsToUse.Length; idx++)
                {
                    _colsToUse[idx] = m_animation_manager.MeshColours[idx];
                }

                // Re-assign latest meshInfo to mesh
                if (_vertsToUse.Length == mesh.vertexCount)
                {
                    mesh.vertices = _vertsToUse;
                    mesh.colors32 = _colsToUse;

                    m_currentVerts   = _vertsToUse;
                    m_currentColours = _colsToUse;
                }
                else if (mesh.vertexCount > _vertsToUse.Length)
                {
                    if (m_currentVerts.Length != mesh.vertexCount)
                    {
                        m_currentVerts = new Vector3[mesh.vertexCount];
                    }
                    if (m_currentColours.Length != mesh.vertexCount)
                    {
                        m_currentColours = new Color32[mesh.vertexCount];
                    }

                    for (int idx = 0; idx < _vertsToUse.Length; idx++)
                    {
                        m_currentVerts [idx]   = _vertsToUse [idx];
                        m_currentColours [idx] = _colsToUse [idx];
                    }

                    mesh.vertices = m_currentVerts;
                    mesh.colors32 = m_currentColours;
                }

                if (m_canvasRendererComp != null)
                {
                    m_canvasRendererComp.SetMesh(mesh);
                }

#if UNITY_EDITOR
                // Set object dirty to trigger sceneview redraw/update. Calling SceneView.RepaintAll() doesn't work for some reason.
                EditorUtility.SetDirty(GameObject);
#endif
            }

            // Reset textFx anim call flag
            m_textFxAnimDrawCall = false;

            _forceNativeDrawCall = false;

            if (OnMeshUpdateCall != null)
            {
                OnMeshUpdateCall();
            }
        }
Exemple #2
0
        protected override void OnFillVBO(List <UIVertex> vbo)
#endif
        {
            if (font == null)
            {
                m_textFxAnimDrawCall = false;
                return;
            }


            if (!m_textFxAnimDrawCall || m_cachedVerts == null)
            {
#if UGUI_VERSION_3
                if (m_cachedVerts == null)
                {
                    m_cachedVerts = new List <UIVertex>();
                }

                base.OnPopulateMesh(vHelper);
#else
                base.OnFillVBO(vbo);
#endif



#if UGUI_VERSION_3
                int numLetterMeshes = vHelper.currentVertCount / 4;

                // Add in any effect mesh additions
                AddEffectMeshes(vHelper);


                // Update UIVertex cache
                m_cachedVerts.Clear();

                UIVertex new_vert = new UIVertex();
                for (int idx = 0; idx < vHelper.currentVertCount; idx++)
                {
                    vHelper.PopulateUIVertex(ref new_vert, idx);

                    m_cachedVerts.Add(new_vert);
                }

                // Update current mesh state values
                m_currentMeshVerts = m_cachedVerts.GetRange(0, m_cachedVerts.Count);
#else
                int numLetterMeshes = vbo.Count / 4;

                // Update caches
                m_cachedVerts = vbo.GetRange(0, vbo.Count);

                // Update current mesh state values
                m_currentMeshVerts = vbo.GetRange(0, vbo.Count);
#endif


                // Call to update animation letter setups
                m_animation_manager.UpdateText(text, new UGUITextDataHandler(m_cachedVerts, numLetterMeshes), white_space_meshes: true);


                if (Application.isPlaying ||
                    m_animation_manager.Playing                                         // Animation is playing, so will now need to render this new mesh in the current animated state
#if UNITY_EDITOR
                    || TextFxAnimationManager.ExitingPlayMode                           // To stop text being auto rendered in to default position when exiting play mode in editor.
#endif
                    )
                {
                    // The verts need to be set to their current animated states
                    // So recall OnFillVBO, getting it to populate with whatever available animate mesh data for this frame
                    m_textFxAnimDrawCall = true;

                    // Update animated mesh values to latest
                    m_animation_manager.UpdateMesh(true, true, delta_time: 0);

#if UGUI_VERSION_3
                    OnPopulateMesh(vHelper);
#else
                    vbo.Clear();

                    OnFillVBO(vbo);
#endif

                    return;
                }
                else
                {
                    m_animation_manager.PopulateDefaultMeshData(true);
                }
            }
            else
            {
                // TextFx render call. Use cached text mesh data
                UIVertex new_vert = new UIVertex();

#if UGUI_VERSION_3
                vHelper.Clear();
                if (m_currentMeshVerts == null)
                {
                    m_currentMeshVerts = new List <UIVertex>();
                }
                else
                {
                    m_currentMeshVerts.Clear();
                }

                // Add each cached vert into the VBO buffer. Verts seem to need to be added one by one using Add(), can't just copy the list over
                for (int idx = 0; idx < m_cachedVerts.Count; idx += 4)
                {
                    vHelper.AddUIVertexQuad(new UIVertex[] { m_cachedVerts[idx], m_cachedVerts[idx + 1], m_cachedVerts[idx + 2], m_cachedVerts[idx + 3] });

                    m_currentMeshVerts.Add(m_cachedVerts[idx]);
                    m_currentMeshVerts.Add(m_cachedVerts[idx + 1]);
                    m_currentMeshVerts.Add(m_cachedVerts[idx + 2]);
                    m_currentMeshVerts.Add(m_cachedVerts[idx + 3]);

                    if (m_animation_manager.MeshVerts != null && idx < m_animation_manager.MeshVerts.Length)
                    {
                        for (int qidx = 0; qidx < 4; qidx++)
                        {
                            vHelper.PopulateUIVertex(ref new_vert, idx + qidx);
                            new_vert.position = m_animation_manager.MeshVerts[idx + qidx];
                            new_vert.color    = m_animation_manager.MeshColours[idx + qidx];
                            vHelper.SetUIVertex(new_vert, idx + qidx);

                            m_currentMeshVerts[idx + qidx] = new_vert;
                        }
                    }
                }
#else
                // Add each cached vert into the VBO buffer. Verts seem to need to be added one by one using Add(), can't just copy the list over
                for (int idx = 0; idx < m_cachedVerts.Count; idx++)
                {
                    vbo.Add(m_cachedVerts[idx]);

                    if (m_animation_manager.MeshVerts != null && idx < m_animation_manager.MeshVerts.Length)
                    {
                        new_vert           = vbo[vbo.Count - 1];
                        new_vert.position  = m_animation_manager.MeshVerts[idx];
                        new_vert.color     = m_animation_manager.MeshColours[idx];
                        vbo[vbo.Count - 1] = new_vert;
                    }
                }

                // Update current mesh state values
                m_currentMeshVerts = vbo.GetRange(0, vbo.Count);
#endif

#if UNITY_EDITOR
                // Set object dirty to trigger sceneview redraw/update. Calling SceneView.RepaintAll() doesn't work for some reason.
                EditorUtility.SetDirty(GameObject);
#endif
            }

            m_textFxAnimDrawCall = false;

            if (OnMeshUpdateCall != null)
            {
                OnMeshUpdateCall();
            }
        }
        public override void OnFill(List <Vector3> verts, List <Vector2> uvs, List <Color> cols)
        {
            if (!m_textFxAnimDrawCall || forceNativeDrawCall)
            {
                forceNativeDrawCall = false;

                // Text has changed, need to update mesh verts and re-cache them

                base.OnFill(verts, uvs, cols);

                // Update current mesh vert/colour state
                m_currentVerts   = verts;
                m_currentColours = cols;

                // Calculate num raw letter meshes
                _numRenderedLetters = m_currentVerts.Count / 4;

                if (effectStyle == Effect.Shadow)
                {
                    _numRenderedLetters /= 2;
                }
                else if (effectStyle == Effect.Outline)
                {
                    _numRenderedLetters /= 5;
                }
                else if (effectStyle == Effect.Outline8)
                {
                    _numRenderedLetters /= 9;
                }

                _textDataHandler = new NGUITextDataHandler(verts, cols, uvs, _numRenderedLetters);

                // Call to update animation letter setups
                m_animation_manager.UpdateText(text, _textDataHandler, white_space_meshes: false);


                // Make sure m_cachedUVs is ordered correctly, mirroring the vert order returned by the TextFx animation system
                m_cachedUVs = new Vector2[uvs.Count];
                int baseUVIndexOffset = _numRenderedLetters * _textDataHandler.ExtraVertsPerLetter;

                for (int letterIdx = 0; letterIdx < _numRenderedLetters; letterIdx++)
                {
                    _uvSection = _textDataHandler.GetLetterExtraUVs(letterIdx);

                    if (_uvSection != null)
                    {
                        for (int eIdx = 0; eIdx < _uvSection.Length; eIdx++)
                        {
                            m_cachedUVs[letterIdx * _textDataHandler.ExtraVertsPerLetter + eIdx] = _uvSection[eIdx];
                        }
                    }

                    _uvSection = _textDataHandler.GetLetterBaseUVs(letterIdx);

                    if (baseUVIndexOffset + (letterIdx * 4) >= m_cachedUVs.Length)
                    {
                        return;
                    }

                    for (int bIdx = 0; bIdx < _uvSection.Length; bIdx++)
                    {
                        m_cachedUVs[baseUVIndexOffset + (letterIdx * 4) + bIdx] = _uvSection[bIdx];
                    }
                }

                if (m_animation_manager.CheckCurveData())
                {
                    // Update mesh values to latest using new curve offset values
                    ForceUpdateCachedVertData();

                    // Reset the verts data to reflect the curves offset
                    verts.Clear();

                    for (int idx = 0; idx < m_animation_manager.MeshVerts.Length; idx++)
                    {
                        verts.Add(m_animation_manager.MeshVerts[idx]);
                    }
                }

                if (Application.isPlaying ||
                    m_animation_manager.Playing                                         // Animation is playing, so will now need to render this new mesh in the current animated state
#if UNITY_EDITOR
                    || TextFxAnimationManager.ExitingPlayMode                           // To stop text being auto rendered in to default position when exiting play mode in editor.
#endif
                    )
                {
                    // The verts need to be set to their current animated states
                    // So recall OnFill, getting it to populate with whatever available animate mesh data for this frame
                    m_textFxAnimDrawCall = true;

                    verts.Clear();
                    uvs.Clear();
                    cols.Clear();

                    // Update animated mesh values to latest
                    m_animation_manager.UpdateMesh(true, true, delta_time: 0);

                    OnFill(verts, uvs, cols);
                    return;
                }
                else
                {
                    m_animation_manager.PopulateDefaultMeshData(true);
                }
            }
            else
            {
                if (_colsToUse == null || _colsToUse.Length != m_animation_manager.MeshColours.Length)
                {
                    _colsToUse = new Color[m_animation_manager.MeshColours.Length];
                }

                for (int idx = 0; idx < _colsToUse.Length; idx++)
                {
                    _colsToUse[idx] = m_animation_manager.MeshColours[idx];
                }


                // Use cached vert data

                // Add each cached vert into the VBO buffer. Verts seem to need to be added one by one using Add(), can't just copy the list over
                for (int idx = 0; idx < m_cachedUVs.Length; idx++)
                {
                    // Check incase there are more cachedUVs than animatedVerts; caused when text length has been extended, so this frames animated mesh data is short of what is required.
                    // The verts without available data will be temporarily filled with blank data for this frame
                    if (idx >= m_animation_manager.MeshVerts.Length)
                    {
                        break;
                    }

                    verts.Add(m_animation_manager.MeshVerts[idx]);
                    cols.Add(_colsToUse[idx]);
                    uvs.Add(m_cachedUVs[idx]);
                }


                if (m_animation_manager.MeshVerts.Length < m_cachedUVs.Length)
                {
                    // Temporarily fill overlapping verts with blank data until animated vert data is available next frame.
                    for (int idx = m_animation_manager.MeshVerts.Length; idx < m_cachedUVs.Length; idx++)
                    {
                        verts.Add(Vector3.zero);
                        cols.Add(Color.clear);
                        uvs.Add(Vector2.zero);
                    }
                }

                m_currentVerts   = verts;
                m_currentColours = cols;
            }

            m_markChangedCallMade = false;

            // Reset textFx anim call flag
            m_textFxAnimDrawCall = false;

            forceNativeDrawCall = false;

            if (OnMeshUpdateCall != null)
            {
                OnMeshUpdateCall();
            }
        }