示例#1
0
    void OnRenderObject()
    {
        // Make sure I have the thigs I need to get the data to deform text
        if (m_TextComponent == null)
        {
            m_TextComponent = gameObject.GetComponent <TextMeshPro>();
        }
        if (vertexCurve == null)
        {
            vertexCurve = gameObject.GetComponent <BezierSpline>();
        }

        if (m_TextComponent)
        {
            Vector3[] vertexPositions;

            m_TextComponent.renderMode = TextRenderFlags.Render;
            m_TextComponent.ForceMeshUpdate();
            m_TextComponent.renderMode = TextRenderFlags.DontRender;

            TMP_TextInfo textInfo       = m_TextComponent.textInfo;
            int          characterCount = textInfo.characterCount;

            if (characterCount >= 0)
            {
                vertexPositions = textInfo.meshInfo[0].vertices;

                float boundsMaxX = m_TextComponent.rectTransform.rect.width * 0.5f;
                float boundsMinX = -boundsMaxX;

                for (int i = 0; i < characterCount; i++)
                {
                    if (!textInfo.characterInfo[i].isVisible)
                    {
                        continue;
                    }

                    int vertexIndex = textInfo.characterInfo[i].vertexIndex;

                    // Compute the baseline mid point for each character
                    Vector3 offsetToMidBaseline = new Vector3((vertexPositions[vertexIndex + 0].x + vertexPositions[vertexIndex + 2].x) / 2, textInfo.characterInfo[i].baseLine);

                    Vector3 c0 = vertexPositions[vertexIndex + 0] - offsetToMidBaseline;
                    Vector3 c1 = vertexPositions[vertexIndex + 1] - offsetToMidBaseline;
                    Vector3 c2 = vertexPositions[vertexIndex + 2] - offsetToMidBaseline;
                    Vector3 c3 = vertexPositions[vertexIndex + 3] - offsetToMidBaseline;

                    float   t     = (offsetToMidBaseline.x - boundsMinX) / (boundsMaxX - boundsMinX);
                    Vector3 point = transform.InverseTransformPoint(vertexCurve.GetPoint(t)) * curveScale;
                    Vector3 xAxis = transform.InverseTransformDirection(vertexCurve.GetVelocity(t)).normalized;
                    Vector3 yAxis = (Vector3.up - xAxis * xAxis.y).normalized;

                    vertexPositions[vertexIndex + 0] = point + c0.x * xAxis + c0.y * yAxis;
                    vertexPositions[vertexIndex + 1] = point + c1.x * xAxis + c1.y * yAxis;
                    vertexPositions[vertexIndex + 2] = point + c2.x * xAxis + c2.y * yAxis;
                    vertexPositions[vertexIndex + 3] = point + c3.x * xAxis + c3.y * yAxis;
                }

                // Upload the mesh with the revised information
                m_TextComponent.mesh.vertices = vertexPositions;
                m_TextComponent.mesh.uv       = textInfo.meshInfo[0].uvs0;
                m_TextComponent.mesh.uv2      = textInfo.meshInfo[0].uvs2;
                m_TextComponent.mesh.colors32 = textInfo.meshInfo[0].colors32;

                m_TextComponent.mesh.RecalculateBounds(); // We need to update the bounds of the text object.
            }
        }
    }
示例#2
0
        /// <summary>
        /// Method to animate vertex colors of a TMP Text object.
        /// </summary>
        /// <returns></returns>
        IEnumerator AnimateVertexColors()
        {
            // We force an update of the text object since it would only be updated at the end of the frame. Ie. before this code is executed on the first frame.
            // Alternatively, we could yield and wait until the end of the frame when the text object will be generated.
            m_TextComponent.ForceMeshUpdate();

            TMP_TextInfo textInfo = m_TextComponent.textInfo;

            Matrix4x4 matrix;
            var       copyOfVertices = new Vector3[0][];

            hasTextChanged = true;

            while (true)
            {
                // Allocate new vertices
                if (hasTextChanged)
                {
                    if (copyOfVertices.Length < textInfo.meshInfo.Length)
                    {
                        copyOfVertices = new Vector3[textInfo.meshInfo.Length][];
                    }

                    for (var i = 0; i < textInfo.meshInfo.Length; i++)
                    {
                        var length = textInfo.meshInfo[i].vertices.Length;
                        copyOfVertices[i] = new Vector3[length];
                    }

                    hasTextChanged = false;
                }

                var characterCount = textInfo.characterCount;

                // If No Characters then just yield and wait for some text to be added
                if (characterCount == 0)
                {
                    yield return(new WaitForSeconds(0.25f));

                    continue;
                }

                var lineCount = textInfo.lineCount;

                // Iterate through each line of the text.
                for (var i = 0; i < lineCount; i++)
                {
                    var first = textInfo.lineInfo[i].firstCharacterIndex;
                    var last  = textInfo.lineInfo[i].lastCharacterIndex;

                    // Determine the center of each line
                    Vector3    centerOfLine = (textInfo.characterInfo[first].bottomLeft + textInfo.characterInfo[last].topRight) / 2;
                    Quaternion rotation     = Quaternion.Euler(0, 0, Random.Range(-0.25f, 0.25f) * RotationMultiplier);

                    // Iterate through each character of the line.
                    for (var j = first; j <= last; j++)
                    {
                        // Skip characters that are not visible and thus have no geometry to manipulate.
                        if (!textInfo.characterInfo[j].isVisible)
                        {
                            continue;
                        }

                        // Get the index of the material used by the current character.
                        var materialIndex = textInfo.characterInfo[j].materialReferenceIndex;

                        // Get the index of the first vertex used by this text element.
                        var vertexIndex = textInfo.characterInfo[j].vertexIndex;

                        // Get the vertices of the mesh used by this text element (character or sprite).
                        var sourceVertices = textInfo.meshInfo[materialIndex].vertices;

                        // Need to translate all 4 vertices of each quad to aligned with center of character.
                        // This is needed so the matrix TRS is applied at the origin for each character.
                        copyOfVertices[materialIndex][vertexIndex + 0] = sourceVertices[vertexIndex + 0] - centerOfLine;
                        copyOfVertices[materialIndex][vertexIndex + 1] = sourceVertices[vertexIndex + 1] - centerOfLine;
                        copyOfVertices[materialIndex][vertexIndex + 2] = sourceVertices[vertexIndex + 2] - centerOfLine;
                        copyOfVertices[materialIndex][vertexIndex + 3] = sourceVertices[vertexIndex + 3] - centerOfLine;

                        // Determine the random scale change for each character.
                        var randomScale = Random.Range(0.995f - 0.001f * ScaleMultiplier, 1.005f + 0.001f * ScaleMultiplier);

                        // Setup the matrix rotation.
                        matrix = Matrix4x4.TRS(Vector3.one, rotation, Vector3.one * randomScale);

                        // Apply the matrix TRS to the individual characters relative to the center of the current line.
                        copyOfVertices[materialIndex][vertexIndex + 0] = matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 0]);
                        copyOfVertices[materialIndex][vertexIndex + 1] = matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 1]);
                        copyOfVertices[materialIndex][vertexIndex + 2] = matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 2]);
                        copyOfVertices[materialIndex][vertexIndex + 3] = matrix.MultiplyPoint3x4(copyOfVertices[materialIndex][vertexIndex + 3]);

                        // Revert the translation change.
                        copyOfVertices[materialIndex][vertexIndex + 0] += centerOfLine;
                        copyOfVertices[materialIndex][vertexIndex + 1] += centerOfLine;
                        copyOfVertices[materialIndex][vertexIndex + 2] += centerOfLine;
                        copyOfVertices[materialIndex][vertexIndex + 3] += centerOfLine;
                    }
                }

                // Push changes into meshes
                for (var i = 0; i < textInfo.meshInfo.Length; i++)
                {
                    textInfo.meshInfo[i].mesh.vertices = copyOfVertices[i];
                    m_TextComponent.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
                }

                yield return(new WaitForSeconds(0.1f));
            }
        }
 public void StartEffect(TMP_TextInfo textInfo, Color[] colors, Vector3[] vertices, ReadOnlyCollection <Vector3> originVertices)
 {
     // Do nothing.
 }
        /// <summary>
        /// Method to draw a rectangle around each character.
        /// </summary>
        /// <param name="text"></param>
        void DrawCharactersBounds()
        {
            TMP_TextInfo textInfo = m_TextComponent.textInfo;

            for (int i = 0; i < textInfo.characterCount; i++)
            {
                // Draw visible as well as invisible characters
                TMP_CharacterInfo cInfo = textInfo.characterInfo[i];

                bool isCharacterVisible = i >= m_TextComponent.maxVisibleCharacters ||
                                          cInfo.lineNumber >= m_TextComponent.maxVisibleLines ||
                                          (m_TextComponent.overflowMode == TextOverflowModes.Page && cInfo.pageNumber + 1 != m_TextComponent.pageToDisplay) ? false : true;

                if (!isCharacterVisible)
                {
                    continue;
                }

                // Get Bottom Left and Top Right position of the current character
                Vector3 bottomLeft  = m_Transform.TransformPoint(cInfo.bottomLeft);
                Vector3 topLeft     = m_Transform.TransformPoint(new Vector3(cInfo.topLeft.x, cInfo.topLeft.y, 0));
                Vector3 topRight    = m_Transform.TransformPoint(cInfo.topRight);
                Vector3 bottomRight = m_Transform.TransformPoint(new Vector3(cInfo.bottomRight.x, cInfo.bottomRight.y, 0));

                Color color = cInfo.isVisible ? Color.yellow : Color.grey;
                DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, color);

                // Baseline
                Vector3 baselineStart = new Vector3(topLeft.x, m_Transform.TransformPoint(new Vector3(0, cInfo.baseLine, 0)).y, 0);
                Vector3 baselineEnd   = new Vector3(topRight.x, m_Transform.TransformPoint(new Vector3(0, cInfo.baseLine, 0)).y, 0);

                Gizmos.color = Color.cyan;
                Gizmos.DrawLine(baselineStart, baselineEnd);


                // Draw Ascender & Descender for each character.
                Vector3 ascenderStart  = new Vector3(topLeft.x, m_Transform.TransformPoint(new Vector3(0, cInfo.ascender, 0)).y, 0);
                Vector3 ascenderEnd    = new Vector3(topRight.x, m_Transform.TransformPoint(new Vector3(0, cInfo.ascender, 0)).y, 0);
                Vector3 descenderStart = new Vector3(bottomLeft.x, m_Transform.TransformPoint(new Vector3(0, cInfo.descender, 0)).y, 0);
                Vector3 descenderEnd   = new Vector3(bottomRight.x, m_Transform.TransformPoint(new Vector3(0, cInfo.descender, 0)).y, 0);

                Gizmos.color = Color.cyan;
                Gizmos.DrawLine(ascenderStart, ascenderEnd);
                Gizmos.DrawLine(descenderStart, descenderEnd);

                // Draw Cap Height
                float   capHeight      = cInfo.baseLine + cInfo.fontAsset.fontInfo.CapHeight * cInfo.scale;
                Vector3 capHeightStart = new Vector3(topLeft.x, m_Transform.TransformPoint(new Vector3(0, capHeight, 0)).y, 0);
                Vector3 capHeightEnd   = new Vector3(topRight.x, m_Transform.TransformPoint(new Vector3(0, capHeight, 0)).y, 0);

                Gizmos.color = Color.cyan;
                Gizmos.DrawLine(capHeightStart, capHeightEnd);

                // Draw xAdvance for each character.
                float   xAdvance      = m_Transform.TransformPoint(cInfo.xAdvance, 0, 0).x;
                Vector3 topAdvance    = new Vector3(xAdvance, topLeft.y, 0);
                Vector3 bottomAdvance = new Vector3(xAdvance, bottomLeft.y, 0);

                Gizmos.color = Color.green;
                Gizmos.DrawLine(topAdvance, bottomAdvance);
            }
        }
        void OnDrawGizmos()
        {
            // Update Text Statistics
            TMP_TextInfo textInfo = m_TextComponent.textInfo;

            ObjectStats = "Characters: " + textInfo.characterCount + "   Words: " + textInfo.wordCount + "   Spaces: " + textInfo.spaceCount + "   Sprites: " + textInfo.spriteCount + "   Links: " + textInfo.linkCount
                          + "\nLines: " + textInfo.lineCount + "   Pages: " + textInfo.pageCount;


            // Draw Quads around each of the Characters
            #region Draw Characters
            if (ShowCharacters)
            {
                DrawCharactersBounds();
            }
            #endregion


            // Draw Quads around each of the words
            #region Draw Words
            if (ShowWords)
            {
                DrawWordBounds();
            }
            #endregion


            // Draw Quads around each of the words
            #region Draw Links
            if (ShowLinks)
            {
                DrawLinkBounds();
            }
            #endregion


            // Draw Quads around each line
            #region Draw Lines
            if (ShowLines)
            {
                DrawLineBounds();
            }
            #endregion


            // Draw Quad around the bounds of the text
            #region Draw Bounds
            if (ShowMeshBounds)
            {
                DrawBounds();
            }
            #endregion

            // Draw Quad around the rendered region of the text.
            #region Draw Text Bounds
            if (ShowTextBounds)
            {
                DrawTextBounds();
            }
            #endregion
        }
示例#6
0
        // Token: 0x060045AF RID: 17839 RVA: 0x00177B74 File Offset: 0x00175F74
        private IEnumerator AnimateVertexColors()
        {
            this.m_TextComponent.ForceMeshUpdate();
            TMP_TextInfo textInfo  = this.m_TextComponent.textInfo;
            int          loopCount = 0;

            this.hasTextChanged = true;
            VertexJitter.VertexAnim[] vertexAnim = new VertexJitter.VertexAnim[1024];
            for (int i = 0; i < 1024; i++)
            {
                vertexAnim[i].angleRange = UnityEngine.Random.Range(10f, 25f);
                vertexAnim[i].speed      = UnityEngine.Random.Range(1f, 3f);
            }
            TMP_MeshInfo[] cachedMeshInfo = textInfo.CopyMeshInfoVertexData();
            for (;;)
            {
                if (this.hasTextChanged)
                {
                    cachedMeshInfo      = textInfo.CopyMeshInfoVertexData();
                    this.hasTextChanged = false;
                }
                int characterCount = textInfo.characterCount;
                if (characterCount == 0)
                {
                    yield return(new WaitForSeconds(0.25f));
                }
                else
                {
                    for (int j = 0; j < characterCount; j++)
                    {
                        TMP_CharacterInfo tmp_CharacterInfo = textInfo.characterInfo[j];
                        if (tmp_CharacterInfo.isVisible)
                        {
                            VertexJitter.VertexAnim vertexAnim2 = vertexAnim[j];
                            int       materialReferenceIndex    = textInfo.characterInfo[j].materialReferenceIndex;
                            int       vertexIndex = textInfo.characterInfo[j].vertexIndex;
                            Vector3[] vertices    = cachedMeshInfo[materialReferenceIndex].vertices;
                            Vector2   v           = (vertices[vertexIndex] + vertices[vertexIndex + 2]) / 2f;
                            Vector3   b           = v;
                            Vector3[] vertices2   = textInfo.meshInfo[materialReferenceIndex].vertices;
                            vertices2[vertexIndex]     = vertices[vertexIndex] - b;
                            vertices2[vertexIndex + 1] = vertices[vertexIndex + 1] - b;
                            vertices2[vertexIndex + 2] = vertices[vertexIndex + 2] - b;
                            vertices2[vertexIndex + 3] = vertices[vertexIndex + 3] - b;
                            vertexAnim2.angle          = Mathf.SmoothStep(-vertexAnim2.angleRange, vertexAnim2.angleRange, Mathf.PingPong((float)loopCount / 25f * vertexAnim2.speed, 1f));
                            Vector3   a      = new Vector3(UnityEngine.Random.Range(-0.25f, 0.25f), UnityEngine.Random.Range(-0.25f, 0.25f), 0f);
                            Matrix4x4 matrix = Matrix4x4.TRS(a * this.CurveScale, Quaternion.Euler(0f, 0f, UnityEngine.Random.Range(-5f, 5f) * this.AngleMultiplier), Vector3.one);
                            vertices2[vertexIndex]      = matrix.MultiplyPoint3x4(vertices2[vertexIndex]);
                            vertices2[vertexIndex + 1]  = matrix.MultiplyPoint3x4(vertices2[vertexIndex + 1]);
                            vertices2[vertexIndex + 2]  = matrix.MultiplyPoint3x4(vertices2[vertexIndex + 2]);
                            vertices2[vertexIndex + 3]  = matrix.MultiplyPoint3x4(vertices2[vertexIndex + 3]);
                            vertices2[vertexIndex]     += b;
                            vertices2[vertexIndex + 1] += b;
                            vertices2[vertexIndex + 2] += b;
                            vertices2[vertexIndex + 3] += b;
                            vertexAnim[j] = vertexAnim2;
                        }
                    }
                    for (int k = 0; k < textInfo.meshInfo.Length; k++)
                    {
                        textInfo.meshInfo[k].mesh.vertices = textInfo.meshInfo[k].vertices;
                        this.m_TextComponent.UpdateGeometry(textInfo.meshInfo[k].mesh, k);
                    }
                    loopCount++;
                    yield return(new WaitForSeconds(0.1f));
                }
            }
            yield break;
        }
示例#7
0
    public void AnimateText()
    {
        //Y'know.
        m_TextComponent.ForceMeshUpdate();

        //we gotta get the mesh info. we gotta.
        TMP_TextInfo textInfo = m_TextComponent.textInfo;

        TMP_MeshInfo[] cachedMeshInfo = textInfo.CopyMeshInfoVertexData();

        hasTextChanged = true;

        //materials.
        int numMaterials;

        Vector3[][] sourceVertices = new Vector3[1][];
        Vector3[][] destVertices   = new Vector3[1][];
        Color[][]   destColors     = new Color[1][];


        //infinite loop
        //while (true)
        {
            // we gotta get that NEW mesh if the text is diffrntetnt
            if (hasTextChanged)
            {
                // Update the copy of the vertex data for the text object.
                cachedMeshInfo = textInfo.CopyMeshInfoVertexData();

                numMaterials = textInfo.materialCount;

                sourceVertices = new Vector3[numMaterials][];
                destVertices   = new Vector3[numMaterials][];
                destColors     = new Color[numMaterials][];

                //Y'see, like
                //We can have more than 1 material for a text thing, so we gotta have multiple arrays cuz they can't be shared
                //among different materials.
                //I don't know why I'm commenting the stuff I didn't write.
                for (int i = 0; i < numMaterials; i++)
                {
                    int numVerts = cachedMeshInfo[i].vertices.Length;

                    sourceVertices[i] = new Vector3[numVerts];
                    destVertices[i]   = new Vector3[numVerts];
                    destColors[i]     = new Color[numVerts];

                    System.Array.Copy(cachedMeshInfo[i].vertices, sourceVertices[i], numVerts);
                }
                hasTextChanged = false;
            }

            int characterCount = textInfo.characterCount;


            if (characterCount == 0)
            {
                //oh no, we don't have any text ;(
                //so sad.
                //better luck next time.
                //yield return new WaitForSeconds(0.25f);
                //continue;
            }

            int curSegment = 0;

            //We have passed the test above and have characters. Praise Talos.
            for (int i = 0; i < characterCount; i++)
            {
                TMP_CharacterInfo charInfo = textInfo.characterInfo[i];

                //why was there a comment on this line.
                //like
                //it's pretty friggin obvious what's going on here.
                if (!charInfo.isVisible)
                {
                    continue;
                }

                // Retrieve the pre-computed animation data for the given character.
                //VertexAnim vertAnim = vertexAnim[i]; //JESSE: this does not exist, does not know what vertexAnim[i] is

                // Get the index of the material used by the current character.
                int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;

                // Get the index of the first vertex used by this text element.
                int vertexIndex = textInfo.characterInfo[i].vertexIndex;

                //I don't fuggin know how
                AnimType t = AnimType.Nope;

                //keep track of which animated segment we're in
                //...If there are any, anyway

                //print("hello?");
                if (curSegment < segments.Count)
                {
                    if (i >= segments[curSegment].stert && i < segments[curSegment].ernd)
                    {
                        t = segments[curSegment].type;
                        //print("we displayin a segment up in this bitch");
                    }
                    else if (i > segments[curSegment].ernd)
                    {
                        curSegment++;
                    }
                }

                //we did it
                destColors[materialIndex][vertexIndex + 0] = textmesh.color;
                destColors[materialIndex][vertexIndex + 1] = textmesh.color;
                destColors[materialIndex][vertexIndex + 2] = textmesh.color;
                destColors[materialIndex][vertexIndex + 3] = textmesh.color;


                //do the thing
                switch (t)
                {
                case AnimType.Jitter:
                    Jitter(destVertices[materialIndex], sourceVertices[materialIndex], vertexIndex);
                    break;

                case AnimType.Pulse:
                {
                    float intensity = Pulse(destVertices[materialIndex], sourceVertices[materialIndex], vertexIndex);

                    Color textColor = Color.Lerp(textmesh.color, PulseColor, intensity);
                    //textColor = Color.Lerp();

                    destColors[materialIndex][vertexIndex]     = textColor;
                    destColors[materialIndex][vertexIndex + 1] = textColor;
                    destColors[materialIndex][vertexIndex + 2] = textColor;
                    destColors[materialIndex][vertexIndex + 3] = textColor;
                }
                break;

                case AnimType.Flow:
                    Flow(ref destVertices[materialIndex], ref sourceVertices[materialIndex], vertexIndex);
                    break;

                default:
                    Nothing(destVertices[materialIndex], sourceVertices[materialIndex], vertexIndex);
                    break;
                }

                System.Array.Copy(destVertices[materialIndex], textInfo.meshInfo[materialIndex].vertices, destVertices[materialIndex].Length);
                //System.Array.Copy(destColors[materialIndex], textInfo.meshInfo[materialIndex].vertices, destVertices[materialIndex].Length);
                // vertexAnim[i] = vertAnim; //error, vertexanim[i] does not exist
            }

            for (int i = 0; i < textInfo.meshInfo.Length; i++)
            {
                textInfo.meshInfo[i].mesh.vertices = textInfo.meshInfo[i].vertices;
                if (i < destColors.Length)
                {
                    textInfo.meshInfo[i].mesh.colors = destColors[i];
                }
                m_TextComponent.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
            }

            //yield return new WaitForSeconds(updateDT);
        }
    }
        public override void ModifyCharacter(CharacterData characterData, TMP_Text textComponent,
                                             TMP_TextInfo textInfo,
                                             float progress,
                                             TMP_MeshInfo[] meshInfo)
        {
            var materialIndex = characterData.MaterialIndex;

            var vertexIndex = characterData.VertexIndex;

            var sourceVertices = meshInfo[materialIndex].vertices;

            Vector2 charMidBasline =
                (sourceVertices[vertexIndex + 0] + sourceVertices[vertexIndex + 2]) / 2;

            Vector3 offset = charMidBasline;

            var destinationVertices = textInfo.meshInfo[materialIndex].vertices;

            destinationVertices[vertexIndex + 0] = sourceVertices[vertexIndex + 0] - offset;
            destinationVertices[vertexIndex + 1] = sourceVertices[vertexIndex + 1] - offset;
            destinationVertices[vertexIndex + 2] = sourceVertices[vertexIndex + 2] - offset;
            destinationVertices[vertexIndex + 3] = sourceVertices[vertexIndex + 3] - offset;

            var finalScale = Vector3.one;

            if (animateScale)
            {
                if (applyOnX)
                {
                    finalScale.x = scaleCurve.Evaluate(characterData.Progress);
                }

                if (applyOnY)
                {
                    finalScale.y = scaleCurve.Evaluate(characterData.Progress);
                }

                if (applyOnZ)
                {
                    finalScale.z = scaleCurve.Evaluate(characterData.Progress);
                }
            }

            var finalPosition = Vector3.zero;

            if (animatePosition)
            {
                finalPosition = positionMultiplier * positionCurve.Evaluate(characterData.Progress);
            }

            var finalQuaternion = Quaternion.identity;

            if (animateRotation)
            {
                finalQuaternion =
                    Quaternion.Euler(rotationMultiplier
                                     * rotationCurve.Evaluate(characterData.Progress));
            }

            var matrix = Matrix4x4.TRS(finalPosition, finalQuaternion, finalScale);

            destinationVertices[vertexIndex + 0] =
                matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 0]);
            destinationVertices[vertexIndex + 1] =
                matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 1]);
            destinationVertices[vertexIndex + 2] =
                matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 2]);
            destinationVertices[vertexIndex + 3] =
                matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 3]);

            destinationVertices[vertexIndex + 0] += offset;
            destinationVertices[vertexIndex + 1] += offset;
            destinationVertices[vertexIndex + 2] += offset;
            destinationVertices[vertexIndex + 3] += offset;
        }
示例#9
0
        /// <summary>
        /// Method to draw a rectangle around each character.
        /// </summary>
        /// <param name="text"></param>
        void DrawCharactersBounds()
        {
            TMP_TextInfo textInfo = mTextComponent.textInfo;

            for (int i = 0; i < textInfo.characterCount; i++)
            {
                // Draw visible as well as invisible characters
                TMP_CharacterInfo cInfo = textInfo.characterInfo[i];

                bool isCharacterVisible = i >= mTextComponent.maxVisibleCharacters ||
                                          cInfo.lineNumber >= mTextComponent.maxVisibleLines ||
                                          (mTextComponent.overflowMode == TextOverflowModes.Page && cInfo.pageNumber + 1 != mTextComponent.pageToDisplay) ? false : true;

                if (!isCharacterVisible)
                {
                    continue;
                }

                // Get Bottom Left and Top Right position of the current character
                Vector3 bottomLeft  = mTransform.TransformPoint(cInfo.bottomLeft);
                Vector3 topLeft     = mTransform.TransformPoint(new Vector3(cInfo.topLeft.x, cInfo.topLeft.y, 0));
                Vector3 topRight    = mTransform.TransformPoint(cInfo.topRight);
                Vector3 bottomRight = mTransform.TransformPoint(new Vector3(cInfo.bottomRight.x, cInfo.bottomRight.y, 0));

                Color color = cInfo.isVisible ? Color.yellow : Color.grey;
                DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, color);

                // Baseline
                Vector3 baselineStart = new Vector3(topLeft.x, mTransform.TransformPoint(new Vector3(0, cInfo.baseLine, 0)).y, 0);
                Vector3 baselineEnd   = new Vector3(topRight.x, mTransform.TransformPoint(new Vector3(0, cInfo.baseLine, 0)).y, 0);

                Gizmos.color = Color.cyan;
                Gizmos.DrawLine(baselineStart, baselineEnd);


                // Draw Ascender & Descender for each character.
                Vector3 ascenderStart  = new Vector3(topLeft.x, mTransform.TransformPoint(new Vector3(0, cInfo.ascender, 0)).y, 0);
                Vector3 ascenderEnd    = new Vector3(topRight.x, mTransform.TransformPoint(new Vector3(0, cInfo.ascender, 0)).y, 0);
                Vector3 descenderStart = new Vector3(bottomLeft.x, mTransform.TransformPoint(new Vector3(0, cInfo.descender, 0)).y, 0);
                Vector3 descenderEnd   = new Vector3(bottomRight.x, mTransform.TransformPoint(new Vector3(0, cInfo.descender, 0)).y, 0);

                Gizmos.color = Color.cyan;
                Gizmos.DrawLine(ascenderStart, ascenderEnd);
                Gizmos.DrawLine(descenderStart, descenderEnd);

                // Draw Cap Height
                float   capHeight      = cInfo.baseLine + cInfo.fontAsset.faceInfo.capLine * cInfo.scale;
                Vector3 capHeightStart = new Vector3(topLeft.x, mTransform.TransformPoint(new Vector3(0, capHeight, 0)).y, 0);
                Vector3 capHeightEnd   = new Vector3(topRight.x, mTransform.TransformPoint(new Vector3(0, capHeight, 0)).y, 0);

                Gizmos.color = Color.cyan;
                Gizmos.DrawLine(capHeightStart, capHeightEnd);

                // Draw Centerline
                float   meanline        = cInfo.baseLine + cInfo.fontAsset.faceInfo.meanLine * cInfo.scale;
                Vector3 centerlineStart = new Vector3(topLeft.x, mTransform.TransformPoint(new Vector3(0, meanline, 0)).y, 0);
                Vector3 centerlineEnd   = new Vector3(topRight.x, mTransform.TransformPoint(new Vector3(0, meanline, 0)).y, 0);

                Gizmos.color = Color.cyan;
                Gizmos.DrawLine(centerlineStart, centerlineEnd);

                // Draw Origin for each character.
                float   gizmoSize = (ascenderEnd.y - descenderEnd.y) * 0.02f;
                Vector3 origin    = mTransform.TransformPoint(cInfo.origin, cInfo.baseLine, 0);
                Vector3 originBl  = new Vector3(origin.x - gizmoSize, origin.y - gizmoSize, 0);
                Vector3 originTl  = new Vector3(originBl.x, origin.y + gizmoSize, 0);
                Vector3 originTr  = new Vector3(origin.x + gizmoSize, originTl.y, 0);
                Vector3 originBr  = new Vector3(originTr.x, originBl.y, 0);

                Gizmos.color = new Color(1, 0.5f, 0);
                Gizmos.DrawLine(originBl, originTl);
                Gizmos.DrawLine(originTl, originTr);
                Gizmos.DrawLine(originTr, originBr);
                Gizmos.DrawLine(originBr, originBl);

                // Draw xAdvance for each character.
                gizmoSize = (ascenderEnd.y - descenderEnd.y) * 0.04f;
                float   xAdvance      = mTransform.TransformPoint(cInfo.xAdvance, 0, 0).x;
                Vector3 topAdvance    = new Vector3(xAdvance, baselineStart.y + gizmoSize, 0);
                Vector3 bottomAdvance = new Vector3(xAdvance, baselineStart.y - gizmoSize, 0);
                Vector3 leftAdvance   = new Vector3(xAdvance - gizmoSize, baselineStart.y, 0);
                Vector3 rightAdvance  = new Vector3(xAdvance + gizmoSize, baselineStart.y, 0);

                Gizmos.color = Color.green;
                Gizmos.DrawLine(topAdvance, bottomAdvance);
                Gizmos.DrawLine(leftAdvance, rightAdvance);
            }
        }
示例#10
0
    /// <summary>
    /// Method to animate vertex colors of a TMP Text object.
    /// </summary>
    /// <returns></returns>
    public IEnumerator AnimateVertexColors()
    {
        int          visibleCount = 0;
        TMP_TextInfo textInfo     = m_TextComponent.textInfo;

        Color32[] newVertexColors;
        Color32   c0 = m_TextComponent.color;

        // We wait one fram to avoid a collision with other effect leading to a miss on first character color animation
        yield return(null);

        while (visibleCount < textInfo.characterCount)
        {
            // Get the index of the material used by the current character.
            int materialIndex = textInfo.characterInfo[visibleCount].materialReferenceIndex;

            // Get the vertex colors of the mesh used by this text element (character or sprite).
            newVertexColors = textInfo.meshInfo[materialIndex].colors32;

            // Update actual letter
            // Get the index of the first vertex used by this text element.
            int vertexIndex = textInfo.characterInfo[visibleCount].vertexIndex;

            c0 = new Color32(255, 255, 255, 125);

            newVertexColors[vertexIndex + 0] = c0;
            newVertexColors[vertexIndex + 1] = c0;
            newVertexColors[vertexIndex + 2] = c0;
            newVertexColors[vertexIndex + 3] = c0;

            if (visibleCount > 1)
            {
                vertexIndex = textInfo.characterInfo[visibleCount - 1].vertexIndex;

                c0 = new Color32(255, 255, 255, 195);

                newVertexColors[vertexIndex + 0] = c0;
                newVertexColors[vertexIndex + 1] = c0;
                newVertexColors[vertexIndex + 2] = c0;
                newVertexColors[vertexIndex + 3] = c0;

                vertexIndex = textInfo.characterInfo[visibleCount - 2].vertexIndex;

                c0 = new Color32(255, 255, 255, 255);

                newVertexColors[vertexIndex + 0] = c0;
                newVertexColors[vertexIndex + 1] = c0;
                newVertexColors[vertexIndex + 2] = c0;
                newVertexColors[vertexIndex + 3] = c0;
            }

            m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);

            yield return(null);

            yield return(null);

            yield return(null);

            visibleCount++;
        }

        int count = 0;

        while (count <= 1)
        {
            // Get the index of the material used by the current character.
            int materialIndex = textInfo.characterInfo[visibleCount - 1].materialReferenceIndex;

            // Get the vertex colors of the mesh used by this text element (character or sprite).
            newVertexColors = textInfo.meshInfo[materialIndex].colors32;

            // Update actual letter
            // Get the index of the first vertex used by this text element.
            int vertexIndex = textInfo.characterInfo[visibleCount - 1].vertexIndex;

            switch (count)
            {
            case 0:
                c0 = new Color32(255, 255, 255, 195);
                break;

            case 1:
                c0 = new Color32(255, 255, 255, 255);
                break;
            }

            newVertexColors[vertexIndex + 0] = c0;
            newVertexColors[vertexIndex + 1] = c0;
            newVertexColors[vertexIndex + 2] = c0;
            newVertexColors[vertexIndex + 3] = c0;

            m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);

            yield return(null);

            yield return(null);

            yield return(null);

            count++;
        }
    }
示例#11
0
        /// <summary>
        /// Method to animate vertex colors of a TMP Text object.
        /// </summary>
        /// <returns></returns>
        IEnumerator AnimateVertexColors()
        {
            // We force an update of the text object since it would only be updated at the end of the frame. Ie. before this code is executed on the first frame.
            // Alternatively, we could yield and wait until the end of the frame when the text object will be generated.
            m_TextComponent.ForceMeshUpdate();

            TMP_TextInfo textInfo = m_TextComponent.textInfo;

            Matrix4x4 matrix;

            TMP_MeshInfo[] cachedMeshInfoVertexData = textInfo.CopyMeshInfoVertexData();

            // Allocations for sorting of the modified scales
            List <float> modifiedCharScale = new List <float>();
            List <int>   scaleSortingOrder = new List <int>();

            hasTextChanged = true;

            while (true)
            {
                // Allocate new vertices
                if (hasTextChanged)
                {
                    // Get updated vertex data
                    cachedMeshInfoVertexData = textInfo.CopyMeshInfoVertexData();

                    hasTextChanged = false;
                }

                int characterCount = textInfo.characterCount;

                // If No Characters then just yield and wait for some text to be added
                if (characterCount == 0)
                {
                    yield return(new WaitForSeconds(0.25f));

                    continue;
                }

                // Clear list of character scales
                modifiedCharScale.Clear();
                scaleSortingOrder.Clear();

                for (int i = 0; i < characterCount; i++)
                {
                    TMP_CharacterInfo charInfo = textInfo.characterInfo[i];

                    // Skip characters that are not visible and thus have no geometry to manipulate.
                    if (!charInfo.isVisible)
                    {
                        continue;
                    }

                    // Get the index of the material used by the current character.
                    int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;

                    // Get the index of the first vertex used by this text element.
                    int vertexIndex = textInfo.characterInfo[i].vertexIndex;

                    // Get the cached vertices of the mesh used by this text element (character or sprite).
                    Vector3[] sourceVertices = cachedMeshInfoVertexData[materialIndex].vertices;

                    // Determine the center point of each character at the baseline.
                    //Vector2 charMidBasline = new Vector2((sourceVertices[vertexIndex + 0].x + sourceVertices[vertexIndex + 2].x) / 2, charInfo.baseLine);
                    // Determine the center point of each character.
                    Vector2 charMidBasline = (sourceVertices[vertexIndex + 0] + sourceVertices[vertexIndex + 2]) / 2;

                    // Need to translate all 4 vertices of each quad to aligned with middle of character / baseline.
                    // This is needed so the matrix TRS is applied at the origin for each character.
                    Vector3 offset = charMidBasline;

                    Vector3[] destinationVertices = textInfo.meshInfo[materialIndex].vertices;

                    destinationVertices[vertexIndex + 0] = sourceVertices[vertexIndex + 0] - offset;
                    destinationVertices[vertexIndex + 1] = sourceVertices[vertexIndex + 1] - offset;
                    destinationVertices[vertexIndex + 2] = sourceVertices[vertexIndex + 2] - offset;
                    destinationVertices[vertexIndex + 3] = sourceVertices[vertexIndex + 3] - offset;

                    //Vector3 jitterOffset = new Vector3(Random.Range(-.25f, .25f), Random.Range(-.25f, .25f), 0);

                    // Determine the random scale change for each character.
                    float randomScale = Random.Range(1f, 1.5f);

                    // Add modified scale and index
                    modifiedCharScale.Add(randomScale);
                    scaleSortingOrder.Add(modifiedCharScale.Count - 1);

                    // Setup the matrix for the scale change.
                    //matrix = Matrix4x4.TRS(jitterOffset, Quaternion.Euler(0, 0, Random.Range(-5f, 5f)), Vector3.one * randomScale);
                    matrix = Matrix4x4.TRS(new Vector3(0, 0, 0), Quaternion.identity, Vector3.one * randomScale);

                    destinationVertices[vertexIndex + 0] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 0]);
                    destinationVertices[vertexIndex + 1] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 1]);
                    destinationVertices[vertexIndex + 2] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 2]);
                    destinationVertices[vertexIndex + 3] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 3]);

                    destinationVertices[vertexIndex + 0] += offset;
                    destinationVertices[vertexIndex + 1] += offset;
                    destinationVertices[vertexIndex + 2] += offset;
                    destinationVertices[vertexIndex + 3] += offset;

                    // Restore Source UVS which have been modified by the sorting
                    Vector2[] sourceUVs0      = cachedMeshInfoVertexData[materialIndex].uvs0;
                    Vector2[] destinationUVs0 = textInfo.meshInfo[materialIndex].uvs0;

                    destinationUVs0[vertexIndex + 0] = sourceUVs0[vertexIndex + 0];
                    destinationUVs0[vertexIndex + 1] = sourceUVs0[vertexIndex + 1];
                    destinationUVs0[vertexIndex + 2] = sourceUVs0[vertexIndex + 2];
                    destinationUVs0[vertexIndex + 3] = sourceUVs0[vertexIndex + 3];

                    // Restore Source Vertex Colors
                    Color32[] sourceColors32      = cachedMeshInfoVertexData[materialIndex].colors32;
                    Color32[] destinationColors32 = textInfo.meshInfo[materialIndex].colors32;

                    destinationColors32[vertexIndex + 0] = sourceColors32[vertexIndex + 0];
                    destinationColors32[vertexIndex + 1] = sourceColors32[vertexIndex + 1];
                    destinationColors32[vertexIndex + 2] = sourceColors32[vertexIndex + 2];
                    destinationColors32[vertexIndex + 3] = sourceColors32[vertexIndex + 3];
                }

                // Push changes into meshes
                for (int i = 0; i < textInfo.meshInfo.Length; i++)
                {
                    //// Sort Quads based modified scale
                    scaleSortingOrder.Sort((a, b) => modifiedCharScale[a].CompareTo(modifiedCharScale[b]));

                    textInfo.meshInfo[i].SortGeometry(scaleSortingOrder);

                    // Updated modified vertex attributes
                    textInfo.meshInfo[i].mesh.vertices = textInfo.meshInfo[i].vertices;
                    textInfo.meshInfo[i].mesh.uv       = textInfo.meshInfo[i].uvs0;
                    textInfo.meshInfo[i].mesh.colors32 = textInfo.meshInfo[i].colors32;

                    m_TextComponent.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
                }

                yield return(new WaitForSeconds(0.1f));
            }
        }
示例#12
0
    /// <summary>
    /// Method to animate vertex colors of a TMP Text object.
    /// </summary>
    /// <returns></returns>
    public IEnumerator AnimateVertex()
    {
        // We force an update of the text object since it would only be updated at the end of the frame. Ie. before this code is executed on the first frame.
        // Alternatively, we could yield and wait until the end of the frame when the text object will be generated.
        m_TextComponent.ForceMeshUpdate();

        TMP_TextInfo textInfo = m_TextComponent.textInfo;

        Matrix4x4 matrix;

        int loopCount = 0;

        // Create an Array which contains pre-computed Angle Ranges and Speeds for a bunch of characters.
        VertexAnim[] vertexAnim = new VertexAnim[1024];
        for (int i = 0; i < 1024; i++)
        {
            vertexAnim[i].speed = Random.Range(1f, 3f);
        }

        // Cache the vertex data of the text object as the Jitter FX is applied to the original position of the characters.
        TMP_MeshInfo[] cachedMeshInfo = textInfo.CopyMeshInfoVertexData();

        while (true)
        {
            // Get new copy of vertex data if the text has changed.
            if (_hasTextChanged)
            {
                // Update the copy of the vertex data for the text object.
                cachedMeshInfo = textInfo.CopyMeshInfoVertexData();

                _hasTextChanged = false;
            }

            int characterCount = textInfo.characterCount;

            // If No Characters then just yield and wait for some text to be added
            while (characterCount == 0)
            {
                characterCount = textInfo.characterCount;
                yield return(null);
            }

            for (int i = 0; i < characterCount; i++)
            {
                TMP_CharacterInfo charInfo = textInfo.characterInfo[i];

                // Skip characters that are not visible and thus have no geometry to manipulate.
                if (!charInfo.isVisible)
                {
                    continue;
                }

                // Retrieve the pre-computed animation data for the given character.
                VertexAnim vertAnim = vertexAnim[i];

                // Get the index of the material used by the current character.
                int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;

                // Get the index of the first vertex used by this text element.
                int vertexIndex = textInfo.characterInfo[i].vertexIndex;

                // Get the cached vertices of the mesh used by this text element (character or sprite).
                Vector3[] sourceVertices = cachedMeshInfo[materialIndex].vertices;

                // Determine the center point of each character.
                Vector2 charMidBasline = (sourceVertices[vertexIndex + 0] + sourceVertices[vertexIndex + 2]) / 2;

                // Need to translate all 4 vertices of each quad to aligned with middle of character / baseline.
                // This is needed so the matrix TRS is applied at the origin for each character.
                Vector3 offset = charMidBasline;

                Vector3[] destinationVertices = textInfo.meshInfo[materialIndex].vertices;

                destinationVertices[vertexIndex + 0] = sourceVertices[vertexIndex + 0] - offset;
                destinationVertices[vertexIndex + 1] = sourceVertices[vertexIndex + 1] - offset;
                destinationVertices[vertexIndex + 2] = sourceVertices[vertexIndex + 2] - offset;
                destinationVertices[vertexIndex + 3] = sourceVertices[vertexIndex + 3] - offset;

                Vector3 jitterOffset = new Vector3(0, Mathf.Sin(Time.time * 5f + i), 0);

                matrix = Matrix4x4.TRS(jitterOffset * CurveScale, Quaternion.Euler(0, 0, 0), Vector3.one);

                destinationVertices[vertexIndex + 0] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 0]);
                destinationVertices[vertexIndex + 1] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 1]);
                destinationVertices[vertexIndex + 2] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 2]);
                destinationVertices[vertexIndex + 3] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 3]);

                destinationVertices[vertexIndex + 0] += offset;
                destinationVertices[vertexIndex + 1] += offset;
                destinationVertices[vertexIndex + 2] += offset;
                destinationVertices[vertexIndex + 3] += offset;

                vertexAnim[i] = vertAnim;
            }

            // Push changes into meshes
            for (int i = 0; i < textInfo.meshInfo.Length; i++)
            {
                textInfo.meshInfo[i].mesh.vertices = textInfo.meshInfo[i].vertices;
                m_TextComponent.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
            }

            loopCount += 1;

            yield return(new WaitForSeconds(0.1f));
        }
    }
示例#13
0
        /// <summary>
        /// Update
        /// </summary>
        protected void Update()
        {
            //if the text and the parameters are the same of the old frame, don't waste time in re-computing everything
            if (!m_forceUpdate && !m_TextComponent.havePropertiesChanged && !ParametersHaveChanged())
            {
                return;
            }

            m_forceUpdate = false;

            //during the loop, vertices represents the 4 vertices of a single character we're analyzing,
            //while matrix is the roto-translation matrix that will rotate and scale the characters so that they will
            //follow the curve
            Vector3[] vertices;
            Matrix4x4 matrix;

            //Generate the mesh and get information about the text and the characters
            m_TextComponent.ForceMeshUpdate();

            TMP_TextInfo textInfo       = m_TextComponent.textInfo;
            int          characterCount = textInfo.characterCount;

            //if the string is empty, no need to waste time
            if (characterCount == 0)
            {
                return;
            }

            //gets the bounds of the rectangle that contains the text
            float boundsMinX = m_TextComponent.bounds.min.x;
            float boundsMaxX = m_TextComponent.bounds.max.x;

            //for each character
            for (int i = 0; i < characterCount; i++)
            {
                //skip if it is invisible
                if (!textInfo.characterInfo[i].isVisible)
                {
                    continue;
                }

                //Get the index of the mesh used by this character, then the one of the material... and use all this data to get
                //the 4 vertices of the rect that encloses this character. Store them in vertices
                int vertexIndex   = textInfo.characterInfo[i].vertexIndex;
                int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
                vertices = textInfo.meshInfo[materialIndex].vertices;

                //Compute the baseline mid point for each character. This is the central point of the character.
                //we will use this as the point representing this character for the geometry transformations
                Vector3 charMidBaselinePos = new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2, textInfo.characterInfo[i].baseLine);

                //remove the central point from the vertices point. After this operation, every one of the four vertices
                //will just have as coordinates the offset from the central position. This will come handy when will deal with the rotations
                vertices[vertexIndex + 0] += -charMidBaselinePos;
                vertices[vertexIndex + 1] += -charMidBaselinePos;
                vertices[vertexIndex + 2] += -charMidBaselinePos;
                vertices[vertexIndex + 3] += -charMidBaselinePos;

                //compute the horizontal position of the character relative to the bounds of the box, in a range [0, 1]
                //where 0 is the left border of the text and 1 is the right border
                float zeroToOnePos = (charMidBaselinePos.x - boundsMinX) / (boundsMaxX - boundsMinX);

                //get the transformation matrix, that maps the vertices, seen as offset from the central character point, to their final
                //position that follows the curve
                matrix = ComputeTransformationMatrix(charMidBaselinePos, zeroToOnePos, textInfo, i);

                //apply the transformation, and obtain the final position and orientation of the 4 vertices representing this char
                vertices[vertexIndex + 0] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 0]);
                vertices[vertexIndex + 1] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 1]);
                vertices[vertexIndex + 2] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 2]);
                vertices[vertexIndex + 3] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 3]);
            }

            //Upload the mesh with the revised information
            m_TextComponent.UpdateVertexData();
        }
示例#14
0
 /// <summary>
 /// Computes the transformation matrix that maps the offsets of the vertices of each single character from
 /// the character's center to the final destinations of the vertices so that the text follows a curve
 /// </summary>
 /// <param name="charMidBaselinePos">Position of the central point of the character</param>
 /// <param name="zeroToOnePos">Horizontal position of the character relative to the bounds of the box, in a range [0, 1]</param>
 /// <param name="textInfo">Information on the text that we are showing</param>
 /// <param name="charIdx">Index of the character we have to compute the transformation for</param>
 /// <returns>Transformation matrix to be applied to all vertices of the text</returns>
 protected abstract Matrix4x4 ComputeTransformationMatrix(Vector3 charMidBaselinePos, float zeroToOnePos, TMP_TextInfo textInfo, int charIdx);
        void OnDrawGizmos()
        {
            // Update Text Statistics
            switch (m_textObjectType)
            {
            case objectType.TextMeshPro:
                TMP_TextInfo textInfo = m_TextMeshPro.textInfo;
                ObjectStats = "Characters: " + textInfo.characterCount + "   Words: " + textInfo.wordCount + "   Spaces: " + textInfo.spaceCount + "   Sprites: " + textInfo.spriteCount + "   Links: " + textInfo.linkCount
                              + "\nLines: " + textInfo.lineCount + "   Pages: " + textInfo.pageCount;
                break;

            case objectType.TextMeshProUI:
                textInfo    = m_TextMeshProUI.textInfo;
                ObjectStats = "Characters: " + textInfo.characterCount + "   Words: " + textInfo.wordCount + "   Spaces: " + textInfo.spaceCount + "   Sprites: " + textInfo.spriteCount + "   Links: " + textInfo.linkCount
                              + "\nLines: " + textInfo.lineCount + "   Pages: " + textInfo.pageCount;
                break;
            }

            // Draw Quads around each of the Characters
            #region Draw Characters
            if (ShowCharacters)
            {
                switch (m_textObjectType)
                {
                case objectType.TextMeshPro:
                    DrawCharacters(m_TextMeshPro);
                    break;

                case objectType.TextMeshProUI:
                    DrawCharacters(m_TextMeshProUI);
                    break;
                }
            }
            #endregion


            // Draw Quads around each of the words
            #region Draw Words
            if (ShowWords)
            {
                switch (m_textObjectType)
                {
                case objectType.TextMeshPro:
                    DrawWords(m_TextMeshPro);
                    break;

                case objectType.TextMeshProUI:
                    DrawWords(m_TextMeshProUI);
                    break;
                }
            }
            #endregion


            // Draw Quads around each of the words
            #region Draw Links
            if (ShowLinks)
            {
                switch (m_textObjectType)
                {
                case objectType.TextMeshPro:
                    DrawLinks(m_TextMeshPro);
                    break;

                case objectType.TextMeshProUI:
                    DrawLinks(m_TextMeshProUI);
                    break;
                }
            }
            #endregion


            // Draw Quads around each line
            #region Draw Lines
            if (ShowLines)
            {
                switch (m_textObjectType)
                {
                case objectType.TextMeshPro:
                    DrawLines(m_TextMeshPro);
                    break;

                case objectType.TextMeshProUI:
                    DrawLines(m_TextMeshProUI);
                    break;
                }
            }
            #endregion


            // Draw Quads around the bounds of the text
            #region Draw Bounds
            if (ShowBounds)
            {
                switch (m_textObjectType)
                {
                case objectType.TextMeshPro:
                    DrawBounds(m_TextMeshPro);
                    break;

                case objectType.TextMeshProUI:
                    DrawBounds(m_TextMeshProUI);
                    break;
                }
            }
            #endregion
        }
示例#16
0
        void OnDrawGizmos()
        {
            if (mTextComponent == null)
            {
                mTextComponent = gameObject.GetComponent <TMP_Text>();

                if (mTextComponent == null)
                {
                    return;
                }

                if (mTransform == null)
                {
                    mTransform = gameObject.GetComponent <Transform>();
                }
            }

            // Update Text Statistics
            TMP_TextInfo textInfo = mTextComponent.textInfo;

            objectStats = "Characters: " + textInfo.characterCount + "   Words: " + textInfo.wordCount + "   Spaces: " + textInfo.spaceCount + "   Sprites: " + textInfo.spriteCount + "   Links: " + textInfo.linkCount
                          + "\nLines: " + textInfo.lineCount + "   Pages: " + textInfo.pageCount;


            // Draw Quads around each of the Characters
            #region Draw Characters
            if (showCharacters)
            {
                DrawCharactersBounds();
            }
            #endregion


            // Draw Quads around each of the words
            #region Draw Words
            if (showWords)
            {
                DrawWordBounds();
            }
            #endregion


            // Draw Quads around each of the words
            #region Draw Links
            if (showLinks)
            {
                DrawLinkBounds();
            }
            #endregion


            // Draw Quads around each line
            #region Draw Lines
            if (showLines)
            {
                DrawLineBounds();
            }
            #endregion


            // Draw Quad around the bounds of the text
            #region Draw Bounds
            if (showMeshBounds)
            {
                DrawBounds();
            }
            #endregion

            // Draw Quad around the rendered region of the text.
            #region Draw Text Bounds
            if (showTextBounds)
            {
                DrawTextBounds();
            }
            #endregion
        }
示例#17
0
        /// <summary>
        /// Computes the transformation matrix that maps the offsets of the vertices of each single character from
        /// the character's center to the final destinations of the vertices so that the text follows a curve
        /// </summary>
        /// <param name="charMidBaselinePosfloat">Position of the central point of the character</param>
        /// <param name="zeroToOnePos">Horizontal position of the character relative to the bounds of the box, in a range [0, 1]</param>
        /// <param name="textInfo">Information on the text that we are showing</param>
        /// <param name="charIdx">Index of the character we have to compute the transformation for</param>
        /// <returns>Transformation matrix to be applied to all vertices of the text</returns>
        protected override Matrix4x4 ComputeTransformationMatrix(Vector3 charMidBaselinePos, float zeroToOnePos, TMP_TextInfo textInfo, int charIdx)
        {
            //compute the angle at which to show this character.
            //We want the string to be centered at the top point of the circle, so we first convert the position from a range [0, 1]
            //to a [-0.5, 0.5] one and then add m_angularOffset degrees, to make it centered on the desired point
            float angle = ((zeroToOnePos - 0.5f) * m_arcDegrees + m_angularOffset) * Mathf.Deg2Rad; //we need radians for sin and cos

            //compute the coordinates of the new position of the central point of the character. Use sin and cos since we are on a circle.
            //Notice that we have to do some extra calculations because we have to take in count that text may be on multiple lines
            float   x0 = Mathf.Cos(angle);
            float   y0 = Mathf.Sin(angle);
            float   radiusForThisLine  = m_radius - textInfo.lineInfo[0].lineExtents.max.y * textInfo.characterInfo[charIdx].lineNumber;
            Vector2 newMideBaselinePos = new Vector2(x0 * radiusForThisLine, -y0 * radiusForThisLine); //actual new position of the character

            //compute the trasformation matrix: move the points to the just found position, then rotate the character to fit the angle of the curve
            //(-90 is because the text is already vertical, it is as if it were already rotated 90 degrees)
            return(Matrix4x4.TRS(new Vector3(newMideBaselinePos.x, newMideBaselinePos.y, 0), Quaternion.AngleAxis(-Mathf.Atan2(y0, x0) * Mathf.Rad2Deg - 90, Vector3.forward), Vector3.one));
        }
        void OnDrawGizmos()
        {
            if (m_TextComponent == null)
            {
                m_TextComponent = GetComponent <TMP_Text>();

                if (m_TextComponent == null)
                {
                    return;
                }
            }

            m_Transform = m_TextComponent.transform;

            // Get a reference to the text object's textInfo
            m_TextInfo = m_TextComponent.textInfo;

            // Update Text Statistics
            ObjectStats = "Characters: " + m_TextInfo.characterCount + "   Words: " + m_TextInfo.wordCount + "   Spaces: " + m_TextInfo.spaceCount + "   Sprites: " + m_TextInfo.spriteCount + "   Links: " + m_TextInfo.linkCount
                          + "\nLines: " + m_TextInfo.lineCount + "   Pages: " + m_TextInfo.pageCount;

            // Get the handle size for drawing the various
            m_ScaleMultiplier = m_TextComponent.GetType() == typeof(TextMeshPro) ? 1 : 0.1f;
            m_HandleSize      = HandleUtility.GetHandleSize(m_Transform.position) * m_ScaleMultiplier;

            // Draw line metrics
            #region Draw Lines
            if (ShowLines)
            {
                DrawLineBounds();
            }
            #endregion

            // Draw word metrics
            #region Draw Words
            if (ShowWords)
            {
                DrawWordBounds();
            }
            #endregion

            // Draw character metrics
            #region Draw Characters
            if (ShowCharacters)
            {
                DrawCharactersBounds();
            }
            #endregion

            // Draw Quads around each of the words
            #region Draw Links
            if (ShowLinks)
            {
                DrawLinkBounds();
            }
            #endregion

            // Draw Quad around the bounds of the text
            #region Draw Bounds
            if (ShowMeshBounds)
            {
                DrawBounds();
            }
            #endregion

            // Draw Quad around the rendered region of the text.
            #region Draw Text Bounds
            if (ShowTextBounds)
            {
                DrawTextBounds();
            }
            #endregion
        }
示例#19
0
        /// <summary>
        /// Method to animate vertex colors of a TMP Text object.
        /// </summary>
        /// <returns></returns>
        IEnumerator AnimateVertexColors()
        {
            // We force an update of the text object since it would only be updated at the end of the frame. Ie. before this code is executed on the first frame.
            // Alternatively, we could yield and wait until the end of the frame when the text object will be generated.
            m_TextComponent.ForceMeshUpdate();

            TMP_TextInfo textInfo = m_TextComponent.textInfo;

            Matrix4x4 matrix;

            int loopCount = 0;

            hasTextChanged = true;

            // Create an Array which contains pre-computed Angle Ranges and Speeds for a bunch of characters.
            VertexAnim[] vertexAnim = new VertexAnim[1024];
            for (int i = 0; i < 1024; i++)
            {
                vertexAnim[i].angleRange = Random.Range(10f, 25f);
                vertexAnim[i].speed      = Random.Range(1f, 3f);
            }

            // Cache the vertex data of the text object as the Jitter FX is applied to the original position of the characters.
            TMP_MeshInfo[] cachedMeshInfo = textInfo.CopyMeshInfoVertexData();

            Color32[] newVertexColors;
            int       characterCount = textInfo.characterCount;

            for (int i = 0; i < characterCount; i++)
            {
                TMP_CharacterInfo charInfo = textInfo.characterInfo[i];
                int materialIndex          = charInfo.materialReferenceIndex;
                newVertexColors = textInfo.meshInfo[materialIndex].colors32;
                int vertexIndex = charInfo.vertexIndex;
                newVertexColors[vertexIndex + 0].a = 0;
                newVertexColors[vertexIndex + 1].a = 0;
                newVertexColors[vertexIndex + 2].a = 0;
                newVertexColors[vertexIndex + 3].a = 0;
            }


            while (true)
            {
                // If No Characters then just yield and wait for some text to be added
                if (characterCount == 0)
                {
                    yield return(new WaitForSeconds(0.25f));

                    continue;
                }



                if (currentCharacter < characterCount)
                {
                    int materialIndex = textInfo.characterInfo[currentCharacter].materialReferenceIndex;
                    newVertexColors = textInfo.meshInfo[materialIndex].colors32;
                    int vertexIndex = textInfo.characterInfo[currentCharacter].vertexIndex;
                    newVertexColors[vertexIndex + 0].a = 255;
                    newVertexColors[vertexIndex + 1].a = 255;
                    newVertexColors[vertexIndex + 2].a = 255;
                    newVertexColors[vertexIndex + 3].a = 255;
                    if (currentCharacter + 1 < characterCount)
                    {
                        currentCharacter += 1;
                    }
                    m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
                }


                for (int i = 0; i < characterCount; i++)
                {
                    TMP_CharacterInfo charInfo = textInfo.characterInfo[i];

                    // Skip characters that are not visible and thus have no geometry to manipulate.
                    //if (!charInfo.isVisible)
                    //continue;

                    // Retrieve the pre-computed animation data for the given character.
                    VertexAnim vertAnim = vertexAnim[i];

                    // Get the index of the material used by the current character.
                    int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;

                    // Get the index of the first vertex used by this text element.
                    int vertexIndex = textInfo.characterInfo[i].vertexIndex;

                    // Get the cached vertices of the mesh used by this text element (character or sprite).
                    Vector3[] sourceVertices = cachedMeshInfo[materialIndex].vertices;

                    // Determine the center point of each character at the baseline.
                    //Vector2 charMidBasline = new Vector2((sourceVertices[vertexIndex + 0].x + sourceVertices[vertexIndex + 2].x) / 2, charInfo.baseLine);
                    // Determine the center point of each character.
                    Vector2 charMidBasline = (sourceVertices[vertexIndex + 0] + sourceVertices[vertexIndex + 2]) / 2;

                    // Need to translate all 4 vertices of each quad to aligned with middle of character / baseline.
                    // This is needed so the matrix TRS is applied at the origin for each character.
                    Vector3 offset = charMidBasline;

                    Vector3[] destinationVertices = textInfo.meshInfo[materialIndex].vertices;

                    destinationVertices[vertexIndex + 0] = sourceVertices[vertexIndex + 0] - offset;
                    destinationVertices[vertexIndex + 1] = sourceVertices[vertexIndex + 1] - offset;
                    destinationVertices[vertexIndex + 2] = sourceVertices[vertexIndex + 2] - offset;
                    destinationVertices[vertexIndex + 3] = sourceVertices[vertexIndex + 3] - offset;

                    vertAnim.angle = Mathf.SmoothStep(-vertAnim.angleRange, vertAnim.angleRange, Mathf.PingPong(loopCount / 25f * vertAnim.speed, 1f));
                    Vector3 jitterOffset = new Vector3(Random.Range(-.25f, .25f), Random.Range(-.25f, .25f), 0);

                    matrix = Matrix4x4.TRS(jitterOffset * CurveScale, Quaternion.Euler(0, 0, Random.Range(-5f, 5f) * AngleMultiplier), Vector3.one);

                    destinationVertices[vertexIndex + 0] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 0]);
                    destinationVertices[vertexIndex + 1] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 1]);
                    destinationVertices[vertexIndex + 2] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 2]);
                    destinationVertices[vertexIndex + 3] = matrix.MultiplyPoint3x4(destinationVertices[vertexIndex + 3]);

                    destinationVertices[vertexIndex + 0] += offset;
                    destinationVertices[vertexIndex + 1] += offset;
                    destinationVertices[vertexIndex + 2] += offset;
                    destinationVertices[vertexIndex + 3] += offset;

                    vertexAnim[i] = vertAnim;
                }

                // Push changes into meshes
                for (int i = 0; i < textInfo.meshInfo.Length; i++)
                {
                    textInfo.meshInfo[i].mesh.vertices = textInfo.meshInfo[i].vertices;
                    m_TextComponent.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
                }
                loopCount += 1;

                yield return(new WaitForSeconds(0.05f));
            }
        }
    IEnumerator StartFall()
    {
        allFalling = true;
        // Reset curChar value if all the characters had previously started their motion.
        if (curChar == characterCount)
        {
            curChar = 0;
        }
        // Set the curve wrap modes. This can (and should) be done in the inspector.
        fallCurve.preWrapMode    = WrapMode.Clamp;
        fallCurve.postWrapMode   = WrapMode.Clamp;
        bounceCurve.preWrapMode  = WrapMode.Loop;
        bounceCurve.postWrapMode = WrapMode.Loop;
        // Generate the mesh and populate the textInfo with data we can use and manipulate.
        m_TextComponent.ForceMeshUpdate();
        // Store textInfo and characterCount values.
        textInfo       = m_TextComponent.textInfo;
        characterCount = textInfo.characterCount;
        // Get the index of the mesh used by this character.
        int matIndex = textInfo.characterInfo[curChar].materialReferenceIndex;
        // Get the index of the first vertex used by this text element.
        int vertIndex = textInfo.characterInfo[curChar].vertexIndex;

        Vector3[] verts;

        // Start fading in the elements.
        if (fadeInOnFall)
        {
            colorFadeScript.startFadeIn = true;
        }
        // Check the correct bools in the TMPTextColorFade script to make it have the correct order.
        if (randomOrder)
        {
            charOrder = handlerScript.randomOrder;
        }
        else
        {
            charOrder = handlerScript.leftRightOrder;
        }
        // Start randomly falling characters.
        while (curChar < characterCount)
        {
            // Instructing TextMesh Pro not to upload the mesh as we will be modifying it.
            m_TextComponent.renderMode = TextRenderFlags.DontRender;
            // Get the index of the mesh used by this character.
            matIndex = textInfo.characterInfo[charOrder[curChar]].materialReferenceIndex;
            // Get the index of the first vertex used by this text element.
            vertIndex = textInfo.characterInfo[charOrder[curChar]].vertexIndex;
            // Get the array of vertices used by this text element.
            verts = textInfo.meshInfo[matIndex].vertices;
            // Ignore "spaces" as they do not seem to have vertices they cause problems.
            // But it does count as a character so the delay between characters falling must still be applied.
            if (textInfo.characterInfo[charOrder[curChar]].character.ToString() != " ")
            {
                StartCoroutine(FallOnce(verts, matIndex, vertIndex, charOrder[curChar]));
            }
            curChar++;
            // Delay between every text character.
            yield return(new WaitForSeconds(timeBetweenChar));
        }
        //allFalling = true;
    }
示例#21
0
 private void TmpTextOnOnPreRenderText(TMP_TextInfo obj) => rectTransform.sizeDelta = new Vector2(lineLenght, tmpText.textBounds.size.y);
    /// <summary>
    ///  Method that makes a character fall.
    /// </summary>
    /// <param name="textComponent"></param>
    /// <returns></returns>
    IEnumerator FallOnce(Vector3[] vertices, int materialIndex, int vertexIndex, int currentCharacter)
    {
        float timer       = 0f;
        int   bounceCount = 1;
        bool  falling     = true;
        bool  bouncing    = false;

        float originalY0 = vertices[vertexIndex + 0].y;
        float originalY1 = vertices[vertexIndex + 1].y;
        float originalY2 = vertices[vertexIndex + 2].y;
        float originalY3 = vertices[vertexIndex + 3].y;

        while (falling)
        {
            timer += Time.deltaTime / fallDur;
            // Compute the baseline mid point for each character
            float yOffset = (fallCurve.Evaluate(timer) * fallCurveScale);
            // Apply offset to adjust our pivot point.
            vertices[vertexIndex + 0].y = originalY0 + yOffset;
            vertices[vertexIndex + 1].y = originalY1 + yOffset;
            vertices[vertexIndex + 2].y = originalY2 + yOffset;
            vertices[vertexIndex + 3].y = originalY3 + yOffset;
            // Upload the mesh with the revised information
            m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Vertices);
            // Store textInfo values.
            textInfo = m_TextComponent.textInfo;

            // When to force update the vertices.
            updateAfterCount++;

            if (timer >= 1)
            {
                falling = false;
                if (bounceAfterFall)
                {
                    bouncing = true;
                }
                else if (waveAfterFall && currentCharacter == handlerScript.leftRightOrder[characterCount - 1])
                {
                    waveScript.waveOn = true;
                }
                timer = 0f;
            }
            yield return(null);
        }

        while (bouncing)
        {
            timer += Time.deltaTime / bounceDur;

            if (timer >= 1f)
            {
                bounceCount++;
                timer = 0f;
            }
            // Compute the baseline mid point for each character
            float yOffset = ((bounceCurve.Evaluate(timer) * bounceCurveScale) / (bounceCount * bounceDampner));
            // Apply offset to adjust our pivot point.
            vertices[vertexIndex + 0].y = originalY0 + yOffset;
            vertices[vertexIndex + 1].y = originalY1 + yOffset;
            vertices[vertexIndex + 2].y = originalY2 + yOffset;
            vertices[vertexIndex + 3].y = originalY3 + yOffset;
            // Upload the mesh with the revised information
            m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Vertices);
            // Store textInfo values.
            textInfo = m_TextComponent.textInfo;

            // When to force update the vertices.
            updateAfterCount++;

            if (bounceCount >= bounces)
            {
                bouncing = false;
                if (startFromMid)
                {
                    curChar--;
                }
            }
            yield return(null);
        }
    }
        /// <summary>
        /// Draw rectangle around each of the links contained in the text.
        /// </summary>
        /// <param name="text"></param>
        void DrawLinkBounds()
        {
            TMP_TextInfo textInfo = m_TextComponent.textInfo;

            for (int i = 0; i < textInfo.linkCount; i++)
            {
                TMP_LinkInfo linkInfo = textInfo.linkInfo[i];

                bool isBeginRegion = false;

                Vector3 bottomLeft  = Vector3.zero;
                Vector3 topLeft     = Vector3.zero;
                Vector3 bottomRight = Vector3.zero;
                Vector3 topRight    = Vector3.zero;

                float maxAscender  = -Mathf.Infinity;
                float minDescender = Mathf.Infinity;

                Color32 linkColor = Color.cyan;

                // Iterate through each character of the link text
                for (int j = 0; j < linkInfo.linkTextLength; j++)
                {
                    int characterIndex = linkInfo.linkTextfirstCharacterIndex + j;
                    TMP_CharacterInfo currentCharInfo = textInfo.characterInfo[characterIndex];
                    int currentLine = currentCharInfo.lineNumber;

                    bool isCharacterVisible = characterIndex > m_TextComponent.maxVisibleCharacters ||
                                              currentCharInfo.lineNumber > m_TextComponent.maxVisibleLines ||
                                              (m_TextComponent.overflowMode == TextOverflowModes.Page && currentCharInfo.pageNumber + 1 != m_TextComponent.pageToDisplay) ? false : true;

                    // Track Max Ascender and Min Descender
                    maxAscender  = Mathf.Max(maxAscender, currentCharInfo.ascender);
                    minDescender = Mathf.Min(minDescender, currentCharInfo.descender);

                    if (isBeginRegion == false && isCharacterVisible)
                    {
                        isBeginRegion = true;

                        bottomLeft = new Vector3(currentCharInfo.bottomLeft.x, currentCharInfo.descender, 0);
                        topLeft    = new Vector3(currentCharInfo.bottomLeft.x, currentCharInfo.ascender, 0);

                        //Debug.Log("Start Word Region at [" + currentCharInfo.character + "]");

                        // If Link is one character
                        if (linkInfo.linkTextLength == 1)
                        {
                            isBeginRegion = false;

                            topLeft     = m_Transform.TransformPoint(new Vector3(topLeft.x, maxAscender, 0));
                            bottomLeft  = m_Transform.TransformPoint(new Vector3(bottomLeft.x, minDescender, 0));
                            bottomRight = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, minDescender, 0));
                            topRight    = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, maxAscender, 0));

                            // Draw Region
                            DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, linkColor);

                            //Debug.Log("End Word Region at [" + currentCharInfo.character + "]");
                        }
                    }

                    // Last Character of Link
                    if (isBeginRegion && j == linkInfo.linkTextLength - 1)
                    {
                        isBeginRegion = false;

                        topLeft     = m_Transform.TransformPoint(new Vector3(topLeft.x, maxAscender, 0));
                        bottomLeft  = m_Transform.TransformPoint(new Vector3(bottomLeft.x, minDescender, 0));
                        bottomRight = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, minDescender, 0));
                        topRight    = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, maxAscender, 0));

                        // Draw Region
                        DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, linkColor);

                        //Debug.Log("End Word Region at [" + currentCharInfo.character + "]");
                    }
                    // If Link is split on more than one line.
                    else if (isBeginRegion && currentLine != textInfo.characterInfo[characterIndex + 1].lineNumber)
                    {
                        isBeginRegion = false;

                        topLeft     = m_Transform.TransformPoint(new Vector3(topLeft.x, maxAscender, 0));
                        bottomLeft  = m_Transform.TransformPoint(new Vector3(bottomLeft.x, minDescender, 0));
                        bottomRight = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, minDescender, 0));
                        topRight    = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, maxAscender, 0));

                        // Draw Region
                        DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, linkColor);

                        maxAscender  = -Mathf.Infinity;
                        minDescender = Mathf.Infinity;
                        //Debug.Log("End Word Region at [" + currentCharInfo.character + "]");
                    }
                }

                //Debug.Log(wInfo.GetWord(m_TextMeshPro.textInfo.characterInfo));
            }
        }
    IEnumerator StartFallFromMid()
    {
        //int currentCharacter = 0;
        int currentCharacterLeft;
        int currentCharacterRight;

        space = 0;
        Vector3[] vertsLeft;
        Vector3[] vertsRight;
        Vector3[] verts;

        allFalling = true;
        // Reset curChar value if all the characters had previously started their motion.
        if (curChar >= characterCount)
        {
            curChar = 0;
        }
        // Set the curve wrap modes. This can (and should) be done in the inspector.
        fallCurve.preWrapMode    = WrapMode.Clamp;
        fallCurve.postWrapMode   = WrapMode.Clamp;
        bounceCurve.preWrapMode  = WrapMode.Loop;
        bounceCurve.postWrapMode = WrapMode.Loop;
        // Generate the mesh and populate the textInfo with data we can use and manipulate.
        m_TextComponent.ForceMeshUpdate();
        // Store textInfo and characterCount values.
        textInfo       = m_TextComponent.textInfo;
        characterCount = textInfo.characterCount;

        // Start fading in the elements.
        if (fadeInOnFall)
        {
            colorFadeScript.startFadeIn = true;
        }
        // Assign the left to right order for fall to wave purposes.
        charOrder = handlerScript.leftRightOrder;
        // Check if even with modulo.
        // Even.
        if (characterCount % 2 == 0)
        {
            currentCharacterLeft  = characterCount / 2 - 1;
            currentCharacterRight = currentCharacterLeft + 1;
        }
        // Odds.
        else
        {
            curChar = Mathf.CeilToInt(characterCount / 2);
            // Get the index of the material used by the current character.
            int materialIndex = textInfo.characterInfo[curChar].materialReferenceIndex;
            // Get the array of vertices used by this text element.
            verts = textInfo.meshInfo[materialIndex].vertices;
            // Get the index of the first vertex used by this text element.
            int vertexIndex = textInfo.characterInfo[curChar].vertexIndex;
            if (textInfo.characterInfo[curChar].character.ToString() != " ")
            {
                StartCoroutine(FallOnce(verts, materialIndex, vertexIndex, curChar));
                curChar++;
            }
            else
            {
                space++;
            }
            currentCharacterLeft  = curChar - 1;
            currentCharacterRight = curChar + 1;
        }
        // Fade in the rest of the characters. To the Left and to the Right at the same time.
        while (currentCharacterRight < characterCount)
        {
            // For the character to the left.
            // Get the index of the material used by the current character.
            int materialIndexLeft = textInfo.characterInfo[currentCharacterLeft].materialReferenceIndex;
            // Get the index of the first vertex used by this text element.
            int vertexIndexLeft = textInfo.characterInfo[currentCharacterLeft].vertexIndex;
            // Get the array of vertices used by this text element.
            vertsLeft = textInfo.meshInfo[materialIndexLeft].vertices;
            if (textInfo.characterInfo[currentCharacterLeft].character.ToString() != " ")
            {
                StartCoroutine(FallOnce(vertsLeft, materialIndexLeft, vertexIndexLeft, currentCharacterLeft));
                curChar++;
            }
            else
            {
                space++;
            }
            currentCharacterLeft--;

            // For the character to the right.
            // Get the index of the material used by the current character.
            int materialIndexRight = textInfo.characterInfo[currentCharacterRight].materialReferenceIndex;
            // Get the index of the first vertex used by this text element.
            int vertexIndexRight = textInfo.characterInfo[currentCharacterRight].vertexIndex;
            // Get the array of vertices used by this text element.
            vertsRight = textInfo.meshInfo[materialIndexRight].vertices;
            if (textInfo.characterInfo[currentCharacterRight].character.ToString() != " ")
            {
                StartCoroutine(FallOnce(vertsRight, materialIndexRight, vertexIndexRight, currentCharacterRight));
                curChar++;
            }
            else
            {
                space++;
            }
            currentCharacterRight++;

            yield return(new WaitForSeconds(timeBetweenChar));
        }
    }
        /// <summary>
        /// Draw Rectangles around each lines of the text.
        /// </summary>
        /// <param name="text"></param>
        void DrawLineBounds()
        {
            TMP_TextInfo textInfo = m_TextComponent.textInfo;

            for (int i = 0; i < textInfo.lineCount; i++)
            {
                TMP_LineInfo lineInfo = textInfo.lineInfo[i];

                bool isLineVisible = (lineInfo.characterCount == 1 && textInfo.characterInfo[lineInfo.firstCharacterIndex].character == 10) ||
                                     i > m_TextComponent.maxVisibleLines ||
                                     (m_TextComponent.overflowMode == TextOverflowModes.Page && textInfo.characterInfo[lineInfo.firstCharacterIndex].pageNumber + 1 != m_TextComponent.pageToDisplay) ? false : true;

                if (!isLineVisible)
                {
                    continue;
                }

                //if (!ShowLinesOnlyVisibleCharacters)
                //{
                // Get Bottom Left and Top Right position of each line
                float   ascender    = lineInfo.ascender;
                float   descender   = lineInfo.descender;
                float   baseline    = lineInfo.baseline;
                float   maxAdvance  = lineInfo.maxAdvance;
                Vector3 bottomLeft  = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.firstCharacterIndex].bottomLeft.x, descender, 0));
                Vector3 topLeft     = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.firstCharacterIndex].bottomLeft.x, ascender, 0));
                Vector3 topRight    = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.lastCharacterIndex].topRight.x, ascender, 0));
                Vector3 bottomRight = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.lastCharacterIndex].topRight.x, descender, 0));

                DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, Color.green);

                Vector3 bottomOrigin  = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.firstCharacterIndex].origin, descender, 0));
                Vector3 topOrigin     = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.firstCharacterIndex].origin, ascender, 0));
                Vector3 bottomAdvance = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.firstCharacterIndex].origin + maxAdvance, descender, 0));
                Vector3 topAdvance    = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.firstCharacterIndex].origin + maxAdvance, ascender, 0));

                DrawDottedRectangle(bottomOrigin, topOrigin, topAdvance, bottomAdvance, Color.green);

                Vector3 baselineStart = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.firstCharacterIndex].bottomLeft.x, baseline, 0));
                Vector3 baselineEnd   = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.lastCharacterIndex].topRight.x, baseline, 0));

                Gizmos.color = Color.cyan;
                Gizmos.DrawLine(baselineStart, baselineEnd);

                // Draw LineExtents
                Gizmos.color = Color.grey;
                Gizmos.DrawLine(m_Transform.TransformPoint(lineInfo.lineExtents.min), m_Transform.TransformPoint(lineInfo.lineExtents.max));

                //}
                //else
                //{
                //// Get Bottom Left and Top Right position of each line
                //float ascender = lineInfo.ascender;
                //float descender = lineInfo.descender;
                //Vector3 bottomLeft = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.firstVisibleCharacterIndex].bottomLeft.x, descender, 0));
                //Vector3 topLeft = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.firstVisibleCharacterIndex].bottomLeft.x, ascender, 0));
                //Vector3 topRight = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.lastVisibleCharacterIndex].topRight.x, ascender, 0));
                //Vector3 bottomRight = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.lastVisibleCharacterIndex].topRight.x, descender, 0));

                //DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, Color.green);

                //Vector3 baselineStart = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.firstVisibleCharacterIndex].bottomLeft.x, textInfo.characterInfo[lineInfo.firstVisibleCharacterIndex].baseLine, 0));
                //Vector3 baselineEnd = m_Transform.TransformPoint(new Vector3(textInfo.characterInfo[lineInfo.lastVisibleCharacterIndex].topRight.x, textInfo.characterInfo[lineInfo.lastVisibleCharacterIndex].baseLine, 0));

                //Gizmos.color = Color.cyan;
                //Gizmos.DrawLine(baselineStart, baselineEnd);
                //}
            }
        }
        public override void ModifyCharacter(CharacterData characterData, TMP_Text textComponent, TMP_TextInfo textInfo,
                                             float progress, TMP_MeshInfo[] meshInfo)
        {
            if (colors == null || colors.Length == 0)
            {
                return;
            }

            var materialIndex = characterData.MaterialIndex;

            newVertexColors = textInfo.meshInfo[materialIndex].colors32;

            var vertexIndex = characterData.VertexIndex;


            var   targetColor  = colors[characterData.Index % colors.Length];
            Color currentColor = newVertexColors[0];


            targetColor  = targetColor * curve.Evaluate(characterData.Progress);
            currentColor = currentColor * (1f - curve.Evaluate(characterData.Progress));

            newVertexColors[vertexIndex + 0] = currentColor + targetColor;
            newVertexColors[vertexIndex + 1] = currentColor + targetColor;
            newVertexColors[vertexIndex + 2] = currentColor + targetColor;
            newVertexColors[vertexIndex + 3] = currentColor + targetColor;
        }
示例#27
0
        private IEnumerator AnimateVertexColors()
        {
            this.m_TextComponent.ForceMeshUpdate();
            TMP_TextInfo textInfo = this.m_TextComponent.textInfo;

            Vector3[][] copyOfVertices = new Vector3[0][];
            this.hasTextChanged = true;
            for (;;)
            {
                if (this.hasTextChanged)
                {
                    if (copyOfVertices.Length < textInfo.meshInfo.Length)
                    {
                        copyOfVertices = new Vector3[textInfo.meshInfo.Length][];
                    }
                    for (int i = 0; i < textInfo.meshInfo.Length; i++)
                    {
                        int num = textInfo.meshInfo[i].vertices.Length;
                        copyOfVertices[i] = new Vector3[num];
                    }
                    this.hasTextChanged = false;
                }
                if (textInfo.characterCount == 0)
                {
                    yield return(new WaitForSeconds(0.25f));
                }
                else
                {
                    int lineCount = textInfo.lineCount;
                    for (int j = 0; j < lineCount; j++)
                    {
                        int        firstCharacterIndex = textInfo.lineInfo[j].firstCharacterIndex;
                        int        lastCharacterIndex  = textInfo.lineInfo[j].lastCharacterIndex;
                        Vector3    b = (textInfo.characterInfo[firstCharacterIndex].bottomLeft + textInfo.characterInfo[lastCharacterIndex].topRight) / 2f;
                        Quaternion q = Quaternion.Euler(0f, 0f, UnityEngine.Random.Range(-0.25f, 0.25f));
                        for (int k = firstCharacterIndex; k <= lastCharacterIndex; k++)
                        {
                            if (textInfo.characterInfo[k].isVisible)
                            {
                                int       materialReferenceIndex = textInfo.characterInfo[k].materialReferenceIndex;
                                int       vertexIndex            = textInfo.characterInfo[k].vertexIndex;
                                Vector3[] vertices = textInfo.meshInfo[materialReferenceIndex].vertices;
                                Vector3   b2       = (vertices[vertexIndex] + vertices[vertexIndex + 2]) / 2f;
                                copyOfVertices[materialReferenceIndex][vertexIndex]     = vertices[vertexIndex] - b2;
                                copyOfVertices[materialReferenceIndex][vertexIndex + 1] = vertices[vertexIndex + 1] - b2;
                                copyOfVertices[materialReferenceIndex][vertexIndex + 2] = vertices[vertexIndex + 2] - b2;
                                copyOfVertices[materialReferenceIndex][vertexIndex + 3] = vertices[vertexIndex + 3] - b2;
                                float     d      = UnityEngine.Random.Range(0.95f, 1.05f);
                                Matrix4x4 matrix = Matrix4x4.TRS(Vector3.one, Quaternion.identity, Vector3.one * d);
                                copyOfVertices[materialReferenceIndex][vertexIndex]      = matrix.MultiplyPoint3x4(copyOfVertices[materialReferenceIndex][vertexIndex]);
                                copyOfVertices[materialReferenceIndex][vertexIndex + 1]  = matrix.MultiplyPoint3x4(copyOfVertices[materialReferenceIndex][vertexIndex + 1]);
                                copyOfVertices[materialReferenceIndex][vertexIndex + 2]  = matrix.MultiplyPoint3x4(copyOfVertices[materialReferenceIndex][vertexIndex + 2]);
                                copyOfVertices[materialReferenceIndex][vertexIndex + 3]  = matrix.MultiplyPoint3x4(copyOfVertices[materialReferenceIndex][vertexIndex + 3]);
                                copyOfVertices[materialReferenceIndex][vertexIndex]     += b2;
                                copyOfVertices[materialReferenceIndex][vertexIndex + 1] += b2;
                                copyOfVertices[materialReferenceIndex][vertexIndex + 2] += b2;
                                copyOfVertices[materialReferenceIndex][vertexIndex + 3] += b2;
                                copyOfVertices[materialReferenceIndex][vertexIndex]     -= b;
                                copyOfVertices[materialReferenceIndex][vertexIndex + 1] -= b;
                                copyOfVertices[materialReferenceIndex][vertexIndex + 2] -= b;
                                copyOfVertices[materialReferenceIndex][vertexIndex + 3] -= b;
                                matrix = Matrix4x4.TRS(Vector3.one, q, Vector3.one);
                                copyOfVertices[materialReferenceIndex][vertexIndex]      = matrix.MultiplyPoint3x4(copyOfVertices[materialReferenceIndex][vertexIndex]);
                                copyOfVertices[materialReferenceIndex][vertexIndex + 1]  = matrix.MultiplyPoint3x4(copyOfVertices[materialReferenceIndex][vertexIndex + 1]);
                                copyOfVertices[materialReferenceIndex][vertexIndex + 2]  = matrix.MultiplyPoint3x4(copyOfVertices[materialReferenceIndex][vertexIndex + 2]);
                                copyOfVertices[materialReferenceIndex][vertexIndex + 3]  = matrix.MultiplyPoint3x4(copyOfVertices[materialReferenceIndex][vertexIndex + 3]);
                                copyOfVertices[materialReferenceIndex][vertexIndex]     += b;
                                copyOfVertices[materialReferenceIndex][vertexIndex + 1] += b;
                                copyOfVertices[materialReferenceIndex][vertexIndex + 2] += b;
                                copyOfVertices[materialReferenceIndex][vertexIndex + 3] += b;
                            }
                        }
                    }
                    for (int l = 0; l < textInfo.meshInfo.Length; l++)
                    {
                        textInfo.meshInfo[l].mesh.vertices = copyOfVertices[l];
                        this.m_TextComponent.UpdateGeometry(textInfo.meshInfo[l].mesh, l);
                    }
                    yield return(new WaitForSeconds(0.1f));
                }
            }
            yield break;
        }
        /// <summary>
        /// Method to draw rectangles around each word of the text.
        /// </summary>
        /// <param name="text"></param>
        void DrawWords(TextMeshProUGUI text)
        {
            TMP_TextInfo textInfo = text.textInfo;

            for (int i = 0; i < textInfo.wordCount; i++)
            {
                TMP_WordInfo wInfo = textInfo.wordInfo[i];

                bool isBeginRegion = false;

                Vector3 bottomLeft  = Vector3.zero;
                Vector3 topLeft     = Vector3.zero;
                Vector3 bottomRight = Vector3.zero;
                Vector3 topRight    = Vector3.zero;

                float maxAscender  = -Mathf.Infinity;
                float minDescender = Mathf.Infinity;

                Color wordColor = Color.green;

                // Iterate through each character of the word
                for (int j = 0; j < wInfo.characterCount; j++)
                {
                    int characterIndex = wInfo.firstCharacterIndex + j;
                    TMP_CharacterInfo currentCharInfo = textInfo.characterInfo[characterIndex];
                    int currentLine = currentCharInfo.lineNumber;

                    bool isCharacterVisible = characterIndex > text.maxVisibleCharacters ||
                                              currentCharInfo.lineNumber > text.maxVisibleLines ||
                                              (text.OverflowMode == TextOverflowModes.Page && currentCharInfo.pageNumber + 1 != text.pageToDisplay) ? false : true;

                    // Track Max Ascender and Min Descender
                    maxAscender  = Mathf.Max(maxAscender, currentCharInfo.ascender);
                    minDescender = Mathf.Min(minDescender, currentCharInfo.descender);

                    if (isBeginRegion == false && isCharacterVisible)
                    {
                        isBeginRegion = true;

                        bottomLeft = new Vector3(currentCharInfo.bottomLeft.x, currentCharInfo.descender, 0);
                        topLeft    = new Vector3(currentCharInfo.bottomLeft.x, currentCharInfo.ascender, 0);

                        //Debug.Log("Start Word Region at [" + currentCharInfo.character + "]");

                        // If Word is one character
                        if (wInfo.characterCount == 1)
                        {
                            isBeginRegion = false;

                            topLeft     = m_Transform.TransformPoint(new Vector3(topLeft.x, maxAscender, 0));
                            bottomLeft  = m_Transform.TransformPoint(new Vector3(bottomLeft.x, minDescender, 0));
                            bottomRight = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, minDescender, 0));
                            topRight    = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, maxAscender, 0));

                            // Draw Region
                            DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, wordColor);

                            //Debug.Log("End Word Region at [" + currentCharInfo.character + "]");
                        }
                    }

                    // Last Character of Word
                    if (isBeginRegion && j == wInfo.characterCount - 1)
                    {
                        isBeginRegion = false;

                        topLeft     = m_Transform.TransformPoint(new Vector3(topLeft.x, maxAscender, 0));
                        bottomLeft  = m_Transform.TransformPoint(new Vector3(bottomLeft.x, minDescender, 0));
                        bottomRight = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, minDescender, 0));
                        topRight    = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, maxAscender, 0));

                        // Draw Region
                        DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, wordColor);

                        //Debug.Log("End Word Region at [" + currentCharInfo.character + "]");
                    }
                    // If Word is split on more than one line.
                    else if (isBeginRegion && currentLine != textInfo.characterInfo[characterIndex + 1].lineNumber)
                    {
                        isBeginRegion = false;

                        topLeft     = m_Transform.TransformPoint(new Vector3(topLeft.x, maxAscender, 0));
                        bottomLeft  = m_Transform.TransformPoint(new Vector3(bottomLeft.x, minDescender, 0));
                        bottomRight = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, minDescender, 0));
                        topRight    = m_Transform.TransformPoint(new Vector3(currentCharInfo.topRight.x, maxAscender, 0));

                        // Draw Region
                        DrawRectangle(bottomLeft, topLeft, topRight, bottomRight, wordColor);
                        //Debug.Log("End Word Region at [" + currentCharInfo.character + "]");
                        maxAscender  = -Mathf.Infinity;
                        minDescender = Mathf.Infinity;
                    }
                }

                //Debug.Log(wInfo.GetWord(textInfo.characterInfo));
            }
        }
示例#29
0
        /// <suMouseManager.Instanceary>
        ///  Method to curve text along a Unity animation curve.
        /// </suMouseManager.Instanceary>
        /// <param name="textComponent"></param>
        /// <returns></returns>
        IEnumerator WarpText()
        {
            VertexCurve.preWrapMode  = WrapMode.Clamp;
            VertexCurve.postWrapMode = WrapMode.Clamp;

            //Mesh mesh = m_TextComponent.textInfo.meshInfo[0].mesh;

            Vector3[] vertices;
            Matrix4x4 matrix;

            m_TextComponent.havePropertiesChanged = true; // Need to force the TextMeshPro Object to be updated.
            CurveScale *= 10;
            float          old_CurveScale = CurveScale;
            AnimationCurve old_curve      = CopyAnimationCurve(VertexCurve);

            while (true)
            {
                if (!m_TextComponent.havePropertiesChanged && old_CurveScale == CurveScale && old_curve.keys[1].value == VertexCurve.keys[1].value)
                {
                    yield return(null);

                    continue;
                }

                old_CurveScale = CurveScale;
                old_curve      = CopyAnimationCurve(VertexCurve);

                m_TextComponent.ForceMeshUpdate(); // Generate the mesh and populate the textInfo with data we can use and manipulate.

                TMP_TextInfo textInfo       = m_TextComponent.textInfo;
                int          characterCount = textInfo.characterCount;


                if (characterCount == 0)
                {
                    continue;
                }

                //vertices = textInfo.meshInfo[0].vertices;
                //int lastVertexIndex = textInfo.characterInfo[characterCount - 1].vertexIndex;

                float boundsMinX = m_TextComponent.bounds.min.x;  //textInfo.meshInfo[0].mesh.bounds.min.x;
                float boundsMaxX = m_TextComponent.bounds.max.x;  //textInfo.meshInfo[0].mesh.bounds.max.x;



                for (int i = 0; i < characterCount; i++)
                {
                    if (!textInfo.characterInfo[i].isVisible)
                    {
                        continue;
                    }

                    int vertexIndex = textInfo.characterInfo[i].vertexIndex;

                    // Get the index of the mesh used by this character.
                    int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;

                    vertices = textInfo.meshInfo[materialIndex].vertices;

                    // Compute the baseline mid point for each character
                    Vector3 offsetToMidBaseline = new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2, textInfo.characterInfo[i].baseLine);
                    //float offsetY = VertexCurve.Evaluate((float)i / characterCount + loopCount / 50f); // Random.Range(-0.25f, 0.25f);

                    // Apply offset to adjust our pivot point.
                    vertices[vertexIndex + 0] += -offsetToMidBaseline;
                    vertices[vertexIndex + 1] += -offsetToMidBaseline;
                    vertices[vertexIndex + 2] += -offsetToMidBaseline;
                    vertices[vertexIndex + 3] += -offsetToMidBaseline;

                    // Compute the angle of rotation for each character based on the animation curve
                    float x0 = (offsetToMidBaseline.x - boundsMinX) / (boundsMaxX - boundsMinX); // Character's position relative to the bounds of the mesh.
                    float x1 = x0 + 0.0001f;
                    float y0 = VertexCurve.Evaluate(x0) * CurveScale;
                    float y1 = VertexCurve.Evaluate(x1) * CurveScale;

                    Vector3 horizontal = new Vector3(1, 0, 0);
                    //Vector3 normal = new Vector3(-(y1 - y0), (x1 * (boundsMaxX - boundsMinX) + boundsMinX) - offsetToMidBaseline.x, 0);
                    Vector3 tangent = new Vector3(x1 * (boundsMaxX - boundsMinX) + boundsMinX, y1) - new Vector3(offsetToMidBaseline.x, y0);

                    float   dot   = Mathf.Acos(Vector3.Dot(horizontal, tangent.normalized)) * 57.2957795f;
                    Vector3 cross = Vector3.Cross(horizontal, tangent);
                    float   angle = cross.z > 0 ? dot : 360 - dot;

                    matrix = Matrix4x4.TRS(new Vector3(0, y0, 0), Quaternion.Euler(0, 0, angle), Vector3.one);

                    vertices[vertexIndex + 0] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 0]);
                    vertices[vertexIndex + 1] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 1]);
                    vertices[vertexIndex + 2] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 2]);
                    vertices[vertexIndex + 3] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 3]);

                    vertices[vertexIndex + 0] += offsetToMidBaseline;
                    vertices[vertexIndex + 1] += offsetToMidBaseline;
                    vertices[vertexIndex + 2] += offsetToMidBaseline;
                    vertices[vertexIndex + 3] += offsetToMidBaseline;
                }


                // Upload the mesh with the revised information
                m_TextComponent.UpdateVertexData();

                yield return(new WaitForSeconds(0.025f));
            }
        }
示例#30
0
        /// <summary>
        /// Method to animate vertex colors of a TMP Text object.
        /// </summary>
        /// <returns></returns>
        IEnumerator AnimateVertexColors()
        {
            yield return(new WaitForSeconds(3f));

            // Need to force the text object to be generated so we have valid data to work with right from the start.
            m_TextComponent.ForceMeshUpdate();


            TMP_TextInfo textInfo = m_TextComponent.textInfo;

            Color32[] newVertexColors;

            int  currentCharacter       = 0;
            int  startingCharacterRange = currentCharacter;
            bool isRangeMax             = false;

            while (!isRangeMax)
            {
                int characterCount = textInfo.characterCount;

                // Spread should not exceed the number of characters.
                byte fadeSteps = (byte)Mathf.Max(1, 255 / RolloverCharacterSpread);


                for (int i = startingCharacterRange; i < currentCharacter + 1; i++)
                {
                    // Skip characters that are not visible
                    if (!textInfo.characterInfo[i].isVisible)
                    {
                        continue;
                    }

                    // Get the index of the material used by the current character.
                    int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;

                    // Get the vertex colors of the mesh used by this text element (character or sprite).
                    newVertexColors = textInfo.meshInfo[materialIndex].colors32;

                    // Get the index of the first vertex used by this text element.
                    int vertexIndex = textInfo.characterInfo[i].vertexIndex;

                    // Get the current character's alpha value.
                    byte alpha = (byte)Mathf.Clamp(newVertexColors[vertexIndex + 0].a - fadeSteps, 0, 255);

                    // Set new alpha values.
                    newVertexColors[vertexIndex + 0].a = alpha;
                    newVertexColors[vertexIndex + 1].a = alpha;
                    newVertexColors[vertexIndex + 2].a = alpha;
                    newVertexColors[vertexIndex + 3].a = alpha;

                    // Tint vertex colors
                    // Note: Vertex colors are Color32 so we need to cast to Color to multiply with tint which is Color.
                    newVertexColors[vertexIndex + 0] = (Color)newVertexColors[vertexIndex + 0] * ColorTint;
                    newVertexColors[vertexIndex + 1] = (Color)newVertexColors[vertexIndex + 1] * ColorTint;
                    newVertexColors[vertexIndex + 2] = (Color)newVertexColors[vertexIndex + 2] * ColorTint;
                    newVertexColors[vertexIndex + 3] = (Color)newVertexColors[vertexIndex + 3] * ColorTint;

                    if (alpha == 0)
                    {
                        startingCharacterRange += 1;

                        if (startingCharacterRange == characterCount)
                        {
                            // Update mesh vertex data one last time.
                            m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);

                            yield return(new WaitForSeconds(1.0f));

                            // Reset the text object back to original state.
                            m_TextComponent.ForceMeshUpdate();

                            yield return(new WaitForSeconds(1.0f));

                            // Reset our counters.
                            currentCharacter       = 0;
                            startingCharacterRange = 0;
                            //isRangeMax = true; // Would end the coroutine.
                        }
                    }
                }

                // Upload the changed vertex colors to the Mesh.
                m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);

                if (currentCharacter + 1 < characterCount)
                {
                    currentCharacter += 1;
                }

                yield return(new WaitForSeconds(0.25f - FadeSpeed * 0.01f));
            }
        }