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(); } }
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(); } }