Пример #1
0
    IEnumerator TMPJitter(int start, int end, float AngleMultiplier, float CurveScale)
    {
        bool hasTextChanged;

        // 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_TextMeshPro.ForceMeshUpdate();
        yield return(null);

        TMP_TextInfo textInfo = m_TextMeshPro.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();

        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
            if (characterCount < end - start)
            {
                yield return(new WaitForSeconds(0.25f));

                continue;
            }


            for (int i = start; i <= end; 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_TextMeshPro.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
            }

            loopCount += 1;

            yield return(new WaitForSeconds(0.1f));
        }
    }
Пример #2
0
    IEnumerator AnimateDangling()
    {
        Matrix4x4 matrix;

        Vector3[] vertices;

        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].angleRange = Random.Range(DanglingRange.x, DanglingRange.y);
            vertexAnim[i].speed      = Random.Range(DanglingSpeed.x, DanglingSpeed.y);
        }

        m_TextComponent.renderMode = TextRenderFlags.DontRender;

        while (loopCount < 10000)
        {
            m_TextComponent.ForceMeshUpdate();
            vertices = m_TextComponent.textInfo.meshInfo[0].vertices;

            int characterCount = m_TextComponent.textInfo.characterCount;

            for (int i = 0; i < characterCount; i++)
            {
                // Setup initial random values
                VertexAnim        vertAnim = vertexAnim[i];
                TMP_CharacterInfo charInfo = m_TextComponent.textInfo.characterInfo[i];

                // Skip Characters that are not visible
                if (!charInfo.isVisible)
                {
                    continue;
                }

                int vertexIndex = charInfo.vertexIndex;

                Vector2 charMidTopline = new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2, charInfo.topRight.y);
                // Vector2 charMidBasline = new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2, charInfo.baseLine);

                // Need to translate all 4 vertices of each quad to aligned with middle of character / baseline.
                Vector3 offset = charMidTopline;
                // Vector3 offset = charMidBasline;

                vertices[vertexIndex + 0] += -offset;
                vertices[vertexIndex + 1] += -offset;
                vertices[vertexIndex + 2] += -offset;
                vertices[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(Vector3.zero, Quaternion.Euler(0, 0, vertexAnim[i].angle), Vector3.one);
                //matrix = Matrix4x4.TRS(jitterOffset, Quaternion.identity, Vector3.one);
                //matrix = Matrix4x4.TRS(jitterOffset, Quaternion.Euler(0, 0, Random.Range(-5f, 5f)), 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] += offset;
                vertices[vertexIndex + 1] += offset;
                vertices[vertexIndex + 2] += offset;
                vertices[vertexIndex + 3] += offset;

                vertexAnim[i] = vertAnim;
            }

            loopCount += 1;

            //m_TextComponent.mesh.vertices = vertices;
            //m_TextComponent.mesh.uv = m_TextComponent.textInfo.meshInfo[0].uvs0;
            //m_TextComponent.mesh.uv2 = m_TextComponent.textInfo.meshInfo[0].uvs2;
            //m_TextComponent.mesh.colors32 = m_TextComponent.textInfo.meshInfo[0].colors32;

            var textInfo = m_TextComponent.textInfo;
            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);
            }


            //Debug.Log("Vertex Attributes Modified.");
            yield return(new WaitForSeconds(DangleRefresh));
        }
    }
Пример #3
0
    IEnumerator AnimateReveal()
    {
        Matrix4x4 matrix;

        Vector3[] vertices;

        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].angleRange = Random.Range(90f, 90f);
            vertexAnim[i].speed      = Random.Range(1f, 3f);
        }

        m_TextComponent.renderMode = TextRenderFlags.DontRender;

        int direction = 1;

        m_TextComponent.ForceMeshUpdate();
        vertices = m_TextComponent.textInfo.meshInfo[0].vertices;

        while (loopCount < 10000)
        {
            //m_TextMeshPro.ForceMeshUpdate();
            //vertices = m_TextMeshPro.textInfo.meshInfo.vertices;

            int characterCount = m_TextComponent.textInfo.characterCount;

            for (int i = 0; i < characterCount; i++)
            {
                // Setup initial random values
                VertexAnim        vertAnim = vertexAnim[i];
                TMP_CharacterInfo charInfo = m_TextComponent.textInfo.characterInfo[i];

                // Skip Characters that are not visible
                if (!charInfo.isVisible)
                {
                    continue;
                }

                int vertexIndex = charInfo.vertexIndex;

                Vector2 charMidTopline = new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2, charInfo.topRight.y);
                // Vector2 charMidBasline = new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2, charInfo.baseLine);

                // Need to translate all 4 vertices of each quad to aligned with middle of character / baseline.
                Vector3 offset = charMidTopline;
                // Vector3 offset = charMidBasline;

                float angle = 0;

                while (angle < 90)
                {
                    vertices[vertexIndex + 0] += -offset;
                    vertices[vertexIndex + 1] += -offset;
                    vertices[vertexIndex + 2] += -offset;
                    vertices[vertexIndex + 3] += -offset;

                    matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0, 15 * direction, 0), 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] += offset;
                    vertices[vertexIndex + 1] += offset;
                    vertices[vertexIndex + 2] += offset;
                    vertices[vertexIndex + 3] += offset;

                    //m_TextComponent.mesh.vertices = vertices;
                    //m_TextComponent.mesh.uv = m_TextComponent.textInfo.meshInfo[0].uvs0;
                    //m_TextComponent.mesh.uv2 = m_TextComponent.textInfo.meshInfo[0].uvs2;
                    //m_TextComponent.mesh.colors32 = m_TextComponent.textInfo.meshInfo[0].colors32;


                    var textInfo = m_TextComponent.textInfo;
                    for (int j = 0; j < textInfo.meshInfo.Length; j++)
                    {
                        textInfo.meshInfo[j].mesh.vertices = textInfo.meshInfo[j].vertices;
                        m_TextComponent.UpdateGeometry(textInfo.meshInfo[j].mesh, j);
                    }

                    angle += 15;

                    yield return(null);
                    //vertexAnim[i] = vertAnim;
                }
            }

            loopCount += 1;

            direction *= -1;


            //Debug.Log("Vertex Attributes Modified.");
            yield return(new WaitForSeconds(0.1f));
        }
    }
Пример #4
0
        IEnumerator StraightLine(string text)
        {
            float height = 0;

            meshPro.text = text;
            meshPro.ForceMeshUpdate();
            //メッシュ情報をキャシュー
            cachedMeshInfo = textInfo.CopyMeshInfoVertexData();
            Color32 c0           = tmpText.color;
            float   terminalTime = 0;
            float   lifeCycle    = 10 + text.Length * 0.1f;
            float   angle        = 0;

            pingpongAngle      = Mathf.Abs(pingpongAngle);
            pingpongAngleSpeed = Mathf.Abs(pingpongAngleSpeed);

            VertexAnim[] vertexAnim = new VertexAnim[1024];
            for (int i = 0; i < 1024; i++)
            {
                vertexAnim[i].angleRange = Random.Range(pingpongAngle * 0.6f, pingpongAngle);
                vertexAnim[i].speed      = Random.Range(pingpongAngleSpeed * 0.6f, pingpongAngleSpeed);
            }

            while (terminalTime < lifeCycle)
            {
                //文字をカメラに向いて

                /*
                 * transform.LookAt(-Camera.main.transform.position, transform.position.normalized);
                 * var wideScale = (Mathf.Abs(Camera.main.transform.localPosition.z) - EarthRadiu) * WideScaleFactor;
                 * wideScale = Mathf.Min(wideScale, MaxWideScale);
                 * transform.localScale = new Vector3(wideScale, wideScale, wideScale);*/
                height += MoveUpdateInterval * spiralUpSpeed;

                /*
                 * if (pingpongAngle != 0)
                 * {
                 *      angle += MoveUpdateInterval * angleDirect * pingpongAngleSpeed;
                 * if (angle>= pingpongAngle)
                 * {
                 *              angleDirect = -1;
                 *      }else if (angle <= -pingpongAngle)
                 * {
                 *              angleDirect = 1;
                 *      }
                 * }*/

                angle = Mathf.PingPong(height * pingpongAngleSpeed, pingpongAngle) - pingpongAngle / 2;

                for (int i = 0; i < textInfo.characterCount; i++)
                {
                    int       materialIndex       = textInfo.characterInfo[i].materialReferenceIndex;
                    int       vertexIndex         = textInfo.characterInfo[i].vertexIndex;
                    Vector3[] sourceVertices      = cachedMeshInfo[materialIndex].vertices;
                    Vector3[] destinationVertices = textInfo.meshInfo[materialIndex].vertices;

                    VertexAnim vertAnim = vertexAnim[i % vertexAnim.Length];

                    vertAnim.angle = Mathf.PingPong(height * vertAnim.speed, vertAnim.angleRange) - vertAnim.angleRange / 2;

                    /*
                     * destinationVertices[vertexIndex + 0] = sourceVertices[vertexIndex] + new Vector3(-height, 0, 0);
                     * destinationVertices[vertexIndex + 1] = sourceVertices[vertexIndex + 1] + new Vector3(-height, 0, 0);
                     * destinationVertices[vertexIndex + 2] = sourceVertices[vertexIndex + 2] + new Vector3(-height, 0, 0);
                     * destinationVertices[vertexIndex + 3] = sourceVertices[vertexIndex + 3] + new Vector3(-height, 0, 0);
                     */
                    var forward         = Vector3.Cross((sourceVertices[1] - sourceVertices[vertexIndex]).normalized, (sourceVertices[vertexIndex + 2] - sourceVertices[vertexIndex]).normalized);
                    var averagePosition = (sourceVertices[vertexIndex] + sourceVertices[vertexIndex + 1] + sourceVertices[vertexIndex + 2] + sourceVertices[vertexIndex + 3]) / 4;
                    destinationVertices[vertexIndex + 0] = averagePosition + Quaternion.AngleAxis(vertAnim.angle, forward) * (sourceVertices[vertexIndex] - averagePosition) + new Vector3(-height, 0, 0);
                    destinationVertices[vertexIndex + 1] = averagePosition + Quaternion.AngleAxis(vertAnim.angle, forward) * (sourceVertices[vertexIndex + 1] - averagePosition) + new Vector3(-height, 0, 0);
                    destinationVertices[vertexIndex + 2] = averagePosition + Quaternion.AngleAxis(vertAnim.angle, forward) * (sourceVertices[vertexIndex + 2] - averagePosition) + new Vector3(-height, 0, 0);
                    destinationVertices[vertexIndex + 3] = averagePosition + Quaternion.AngleAxis(vertAnim.angle, forward) * (sourceVertices[vertexIndex + 3] - averagePosition) + new Vector3(-height, 0, 0);

                    var newVertexColors = textInfo.meshInfo[materialIndex].colors32;
                    //各キャラクターの頂点の色を頂点透明度を高さの元ついてスムーズに変更
                    if (textInfo.characterInfo[i].isVisible)
                    {
                        float alpha           = 1f;
                        float characterHeight = Mathf.Max(-destinationVertices[vertexIndex + 0].x, 0);
                        //高さが一番下未満と一番上を超えた場合。
                        if (characterHeight <= displayStartHeight || characterHeight > vanishEndHeight)
                        {
                            alpha = 0;
                        }
                        //displayStartHeightからdisplayEndHeight徐々に表示
                        else if (characterHeight > displayStartHeight && characterHeight < displayEndHeight)
                        {
                            alpha = (characterHeight - displayStartHeight) / (displayEndHeight - displayStartHeight);
                        }
                        //vanishStartHeightからvanishEndHeight徐々に非表示
                        else if (characterHeight > vanishStartHeight && characterHeight < vanishEndHeight)
                        {
                            alpha = (vanishEndHeight - characterHeight) / (vanishEndHeight - vanishStartHeight);
                        }
                        c0 = new Color32(newVertexColors[vertexIndex].r, newVertexColors[vertexIndex].g, newVertexColors[vertexIndex].b, (byte)(alpha * 255));
                        newVertexColors[vertexIndex + 0] = c0;
                        newVertexColors[vertexIndex + 1] = c0;
                        newVertexColors[vertexIndex + 2] = c0;
                        newVertexColors[vertexIndex + 3] = c0;
                    }
                }
                //変形した頂点をTextMeshProに入れ
                for (int i = 0; i < textInfo.meshInfo.Length; i++)
                {
                    textInfo.meshInfo[i].mesh.vertices = textInfo.meshInfo[i].vertices;
                    tmpText.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
                }
                //TextMeshProの色更新
                tmpText.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
                yield return(new WaitForSeconds(MoveUpdateInterval));

                terminalTime += MoveUpdateInterval;
                if (terminalTime >= lifeCycle)
                {
                    if (isLoop)
                    {
                        ResetVertics();
                        height       = 0;
                        terminalTime = 0;
                    }
                }
            }
            onTerminal?.Invoke();
            Destroy(gameObject);
        }
Пример #5
0
    public IEnumerator TextJitter(int[] jitterIndices, float speedMultiplier)
    {
        List <TMP_WordInfo> wInfo;

        wInfo = new List <TMP_WordInfo>();

        //Pre determine the vertexAnim variables for the text jitter effect
        //THIS MAY CAUSE LAG
        vertexAnim = null;
        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);
        }
        //Lag over


        while (true)
        {
            if (!cE.isColoring && !hasTextChanged)
            {
                dM.dialogueText.ForceMeshUpdate(true);
            }
            else
            {
                cE.ColorText(dM.mD.colorIndices.ToArray());
            }

            wInfo.Clear();

            foreach (int wordIndex in jitterIndices)
            {
                print("WORDINDEX: " + wordIndex);

                //Add each word's wordInfo
                wInfo.Add(dM.dialogueText.textInfo.wordInfo[wordIndex]);
            }

            Matrix4x4 matrix;

            int loopCount = 0;
            hasTextChanged = true;

            List <TMP_MeshInfo[]> cachedMeshInfo;
            cachedMeshInfo = new List <TMP_MeshInfo[]>();
            cachedMeshInfo.Clear();

            foreach (TMP_WordInfo wordInfo in wInfo)
            {
                cachedMeshInfo.Add(wordInfo.textComponent.textInfo.CopyMeshInfoVertexData());
            }

            if (hasTextChanged)
            {
                foreach (TMP_WordInfo wordInfo in wInfo)
                {
                    cachedMeshInfo.Add(wordInfo.textComponent.textInfo.CopyMeshInfoVertexData());
                }

                hasTextChanged = false;
            }

            foreach (TMP_WordInfo info in wInfo)
            {
                foreach (TMP_MeshInfo[] cMI in cachedMeshInfo)
                {
                    int characterCount = info.characterCount;

                    if (characterCount == 0)
                    {
                        yield return(new WaitForSeconds(0.25f));

                        continue;
                    }

                    for (int i = 0; i < characterCount; i++)
                    {
                        int charIndex = info.firstCharacterIndex + i;

                        TMP_CharacterInfo charInfo = dM.dialogueText.textInfo.characterInfo[charIndex];

                        if (!charInfo.isVisible)
                        {
                            continue;
                        }

                        VertexAnim vertAnim = vertexAnim[charIndex];

                        int materialIndex = dM.dialogueText.textInfo.characterInfo[charIndex].materialReferenceIndex;

                        int vertexIndex = dM.dialogueText.textInfo.characterInfo[charIndex].vertexIndex;

                        Vector3[] sourceVertices = cMI[materialIndex].vertices;

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

                        Vector3 offset = charMidBasline;

                        Vector3[] destinationVertices = dM.dialogueText.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;
                    }
                }
            }

            for (int i = 0; i < dM.dialogueText.textInfo.meshInfo.Length; i++)
            {
                dM.dialogueText.textInfo.meshInfo[i].mesh.vertices = dM.dialogueText.textInfo.meshInfo[i].vertices;
                dM.dialogueText.UpdateGeometry(dM.dialogueText.textInfo.meshInfo[i].mesh, i);
            }

            loopCount += 1;

            yield return(new WaitForSeconds(speedMultiplier));
        }
    }
        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.

            textMeshPro.ForceMeshUpdate();

            TMP_TextInfo textInfo = textMeshPro.textInfo;

            Matrix4x4 matrix;

            int loopCount = 0;
            hasTextChanged = true;

            // Create an Array which contains pre-computed Angle Ranges and Speeds for a bunch of characters.
            
            for (int i = 0; i < 1024; i++)
            {
                vertexAnim[i].damage = false;
                vertexAnim[i].offset = letterOffset;
                vertexAnim[i].alpha = 0;
            }

            // 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();
            characterCount = 1;
            Color32[] newVertexColors;




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

                int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;

                newVertexColors = textInfo.meshInfo[materialIndex].colors32;

                Color32 colorAlpha = new Color32(255, 255, 255, 0);
                newVertexColors[vertexIndex + 0] = colorAlpha;
                newVertexColors[vertexIndex + 1] = colorAlpha;
                newVertexColors[vertexIndex + 2] = colorAlpha;
                newVertexColors[vertexIndex + 3] = colorAlpha;

            }




            while (true)
            {
                textMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
                // 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;
                }


                actualTime += 1;
                if (actualTime == letterInterval && characterCount < textInfo.characterCount)
                {
                    characterCount += 1;
                    actualTime = 0;
                }

                if(characterCount == textInfo.characterCount)
                    mouth.DesactivateMouth();

                //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;
                }


                // =======================================================

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

                    Vector3 position = new Vector3(0, vertAnim.offset, 0);
                    matrix = Matrix4x4.TRS(position, Quaternion.identity, Vector3.one);

                    vertAnim.offset *= letterCurveSpeed;

                    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;



                    // ====================== Couleur ====================== //
                    if (vertAnim.alpha != 255)
                    {
                        vertAnim.alpha += alphaSpeed;
                        if (vertAnim.alpha > 255f)
                        {
                            vertAnim.alpha = 255f;
                        }

                        newVertexColors = textInfo.meshInfo[materialIndex].colors32;
                        Color32 colorAlpha;
                        if (vertexAnim[i].damage == true)
                            colorAlpha = new Color32(damageColor.r, damageColor.g, damageColor.b, (byte)vertexAnim[i].alpha);
                        else
                            colorAlpha = new Color32(255, 255, 255, (byte)vertexAnim[i].alpha);
                        newVertexColors[vertexIndex + 0] = colorAlpha;
                        newVertexColors[vertexIndex + 1] = colorAlpha;
                        newVertexColors[vertexIndex + 2] = colorAlpha;
                        newVertexColors[vertexIndex + 3] = colorAlpha;
                    }

                    //textMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
                    // ====================== Couleur ====================== //



                    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;
                    textMeshPro.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
                }

                loopCount += 1;

                yield return null;//new WaitForSeconds(0.1f);
            }
        }
Пример #7
0
    public IEnumerator ApplyEffects(string sentence, List <List <int> > colorIndices, int[] waveIndices, int[] jitterIndices)
    {
        int loopCount         = 0;
        int lastLoopCount     = 0;
        int currentCharTyping = 0;

        float lastTime = Time.time;

        List <TMP_WordInfo> jitterInfo;

        jitterInfo = new List <TMP_WordInfo>();

        if (jitterIndices.Length > 0)
        {
            vertexAnim = null;
            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);
            }
        }

        List <TMP_WordInfo> waveInfo;

        waveInfo = new List <TMP_WordInfo>();

        if (type)
        {
            dM.dialogueText.text = "";

            yield return(new WaitUntil(() => dM.dB.isOpen));

            dM.isTyping = true;
            dM.tdCheck  = false;

            dM.dialogueText.text = sentence;
            dM.dialogueText.maxVisibleCharacters = sentence.ToCharArray().Length;

            dM.dialogueText.ForceMeshUpdate(true);

            ColorAllCharacters(0);
        }
        else
        {
            dM.dialogueText.text = sentence;
        }

        while (true)
        {
            if (type && currentCharTyping < sentence.ToCharArray().Length)
            {
                int waitCycles = 2;

                if (currentCharTyping > 0)
                {
                    char lastCharTyped = sentence.ToCharArray()[currentCharTyping - 1];
                    char thisChar      = sentence.ToCharArray()[currentCharTyping];

                    if (lastCharTyped != '.' || lastCharTyped != ',' || lastCharTyped != '?' || lastCharTyped != '!')
                    {
                        waitCycles = 2;

                        if (sentence.ToCharArray()[currentCharTyping] == ' ')
                        {
                            currentCharTyping++;
                        }
                    }

                    else
                    {
                        waitCycles = 5;
                    }
                }

                if (lastLoopCount + waitCycles <= loopCount)
                {
                    TMP_TextInfo typeInfo = dM.dialogueText.textInfo;

                    Color32 typeColor = typeInfo.textComponent.color;

                    typeColor.a = 255;

                    for (int x = 0; x < colorIndices.Count; x++)
                    {
                        TMP_TextInfo colorDialogueInfo = dM.dialogueText.textInfo;

                        if (colorIndices[x].Count != 0)
                        {
                            for (int y = 0; y < colorIndices[x].Count; y++)
                            {
                                TMP_WordInfo ColorWordInfo = colorDialogueInfo.wordInfo[colorIndices[x][y]];

                                for (int z = 0; z < ColorWordInfo.characterCount; z++)
                                {
                                    if (currentCharTyping == ColorWordInfo.firstCharacterIndex + z)
                                    {
                                        typeColor = colors[x];
                                    }
                                }
                            }
                        }
                    }

                    int typeMeshIndex   = dM.dialogueText.textInfo.characterInfo[currentCharTyping].materialReferenceIndex;
                    int typeVertexIndex = dM.dialogueText.textInfo.characterInfo[currentCharTyping].vertexIndex;

                    if (dM.dialogueText.text.ToCharArray()[currentCharTyping] == sentence.ToCharArray()[currentCharTyping])
                    {
                        Color32[] typeVertexColors = dM.dialogueText.textInfo.meshInfo[typeMeshIndex].colors32;

                        typeVertexColors[typeVertexIndex + 0] = typeColor;
                        typeVertexColors[typeVertexIndex + 1] = typeColor;
                        typeVertexColors[typeVertexIndex + 2] = typeColor;
                        typeVertexColors[typeVertexIndex + 3] = typeColor;

                        dM.dialogueText.UpdateVertexData(TMP_VertexDataUpdateFlags.All);
                    }
                    else
                    {
                        print("error");
                    }

                    if (currentCharTyping < sentence.ToCharArray().Length)
                    {
                        currentCharTyping++;
                    }

                    lastLoopCount = loopCount;
                }
            }

            if (currentCharTyping >= sentence.ToCharArray().Length)
            {
                dM.isTyping = false;
                dM.tdCheck  = true;

                type = false;

                currentCharTyping = 0;
            }

            if (!type)
            {
                for (int x = 0; x < colorIndices.Count; x++)
                {
                    TMP_TextInfo colorDialogueInfo = dM.dialogueText.textInfo;

                    if (colorIndices[x].Count != 0)
                    {
                        for (int y = 0; y < colorIndices[x].Count; y++)
                        {
                            TMP_WordInfo ColorWordInfo = colorDialogueInfo.wordInfo[colorIndices[x][y]];

                            for (int z = 0; z < ColorWordInfo.characterCount; z++)
                            {
                                int colorTypeMeshIndex   = dM.dialogueText.textInfo.characterInfo[ColorWordInfo.firstCharacterIndex + z].materialReferenceIndex;
                                int colorTypeVertexIndex = dM.dialogueText.textInfo.characterInfo[ColorWordInfo.firstCharacterIndex + z].vertexIndex;

                                Color32[] colorTypeVertexColors = dM.dialogueText.textInfo.meshInfo[colorTypeMeshIndex].colors32;

                                colorTypeVertexColors[colorTypeVertexIndex + 0] = colors[x];
                                colorTypeVertexColors[colorTypeVertexIndex + 1] = colors[x];
                                colorTypeVertexColors[colorTypeVertexIndex + 2] = colors[x];
                                colorTypeVertexColors[colorTypeVertexIndex + 3] = colors[x];

                                dM.dialogueText.UpdateVertexData(TMP_VertexDataUpdateFlags.All);
                            }
                        }
                    }
                }

                if (dM.isTyping && !type)
                {
                    dM.isTyping = false;
                    dM.tdCheck  = true;

                    ColorAllCharacters(255);
                }
            }

            if (jitterIndices.Length > 0 && dM.dialogueText.textInfo.wordCount >= jitterIndices[0])
            {
                jitterInfo.Clear();

                foreach (int jitterIndex in jitterIndices)
                {
                    jitterInfo.Add(dM.dialogueText.textInfo.wordInfo[jitterIndex]);
                }

                Matrix4x4 jitterMatrix;

                hasTextChanged = true;

                List <TMP_MeshInfo[]> cachedJitterMeshInfo;
                cachedJitterMeshInfo = new List <TMP_MeshInfo[]>();

                foreach (TMP_WordInfo wordInfo in jitterInfo)
                {
                    cachedJitterMeshInfo.Add(wordInfo.textComponent.textInfo.CopyMeshInfoVertexData());
                }

                if (hasTextChanged)
                {
                    foreach (TMP_WordInfo wordInfo in jitterInfo)
                    {
                        cachedJitterMeshInfo.Add(wordInfo.textComponent.textInfo.CopyMeshInfoVertexData());
                    }

                    hasTextChanged = false;
                }

                foreach (TMP_WordInfo info in jitterInfo)
                {
                    foreach (TMP_MeshInfo[] cMI in cachedJitterMeshInfo)
                    {
                        int jitterCharacterCount = info.characterCount;

                        if (jitterCharacterCount == 0)
                        {
                            yield return(new WaitForSeconds(0.25f));

                            continue;
                        }

                        for (int i = 0; i < jitterCharacterCount; i++)
                        {
                            int jitterCharIndex = info.firstCharacterIndex + i;

                            TMP_CharacterInfo jitterCharInfo = dM.dialogueText.textInfo.characterInfo[jitterCharIndex];

                            if (!jitterCharInfo.isVisible)
                            {
                                continue;
                            }

                            VertexAnim vertAnim = vertexAnim[jitterCharIndex];

                            int jitterMaterialIndex = dM.dialogueText.textInfo.characterInfo[jitterCharIndex].materialReferenceIndex;

                            int jitterVertexIndex = dM.dialogueText.textInfo.characterInfo[jitterCharIndex].vertexIndex;

                            Vector3[] jitterSourceVertices = cMI[jitterMaterialIndex].vertices;

                            Vector2 jitterCharMidBasline = (jitterSourceVertices[jitterVertexIndex + 0] + jitterSourceVertices[jitterVertexIndex + 2]) / 2;

                            Vector3 jitterOffset = jitterCharMidBasline;

                            Vector3[] jitterDestinationVertices = dM.dialogueText.textInfo.meshInfo[jitterMaterialIndex].vertices;

                            if (loopCount == 0)
                            {
                                SetInitialCoordinates(jitterCharIndex, jitterOffset);
                            }

                            jitterDestinationVertices[jitterVertexIndex + 0] = jitterSourceVertices[jitterVertexIndex + 0] - jitterOffset;
                            jitterDestinationVertices[jitterVertexIndex + 1] = jitterSourceVertices[jitterVertexIndex + 1] - jitterOffset;
                            jitterDestinationVertices[jitterVertexIndex + 2] = jitterSourceVertices[jitterVertexIndex + 2] - jitterOffset;
                            jitterDestinationVertices[jitterVertexIndex + 3] = jitterSourceVertices[jitterVertexIndex + 3] - jitterOffset;

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

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

                            jitterDestinationVertices[jitterVertexIndex + 0] = jitterMatrix.MultiplyPoint3x4(jitterDestinationVertices[jitterVertexIndex + 0]);
                            jitterDestinationVertices[jitterVertexIndex + 1] = jitterMatrix.MultiplyPoint3x4(jitterDestinationVertices[jitterVertexIndex + 1]);
                            jitterDestinationVertices[jitterVertexIndex + 2] = jitterMatrix.MultiplyPoint3x4(jitterDestinationVertices[jitterVertexIndex + 2]);
                            jitterDestinationVertices[jitterVertexIndex + 3] = jitterMatrix.MultiplyPoint3x4(jitterDestinationVertices[jitterVertexIndex + 3]);

                            jitterDestinationVertices[jitterVertexIndex + 0].y += initialYVal[jitterCharIndex];
                            jitterDestinationVertices[jitterVertexIndex + 1].y += initialYVal[jitterCharIndex];
                            jitterDestinationVertices[jitterVertexIndex + 2].y += initialYVal[jitterCharIndex];
                            jitterDestinationVertices[jitterVertexIndex + 3].y += initialYVal[jitterCharIndex];

                            jitterDestinationVertices[jitterVertexIndex + 0].x += initialXVal[jitterCharIndex];
                            jitterDestinationVertices[jitterVertexIndex + 1].x += initialXVal[jitterCharIndex];
                            jitterDestinationVertices[jitterVertexIndex + 2].x += initialXVal[jitterCharIndex];
                            jitterDestinationVertices[jitterVertexIndex + 3].x += initialXVal[jitterCharIndex];

                            jitterDestinationVertices[jitterVertexIndex + 0] += jitterEffectOffset;
                            jitterDestinationVertices[jitterVertexIndex + 1] += jitterEffectOffset;
                            jitterDestinationVertices[jitterVertexIndex + 2] += jitterEffectOffset;
                            jitterDestinationVertices[jitterVertexIndex + 3] += jitterEffectOffset;

                            vertexAnim[i] = vertAnim;
                        }
                    }
                }
            }

            if (waveIndices.Length > 0 && dM.dialogueText.textInfo.wordCount >= waveIndices[0])
            {
                waveInfo.Clear();

                foreach (int waveIndex in waveIndices)
                {
                    //Add each word's wordInfo
                    waveInfo.Add(dM.dialogueText.textInfo.wordInfo[waveIndex]);
                }

                Matrix4x4 waveMatrix;

                hasTextChanged = true;

                List <TMP_MeshInfo[]> cachedWaveMeshInfo;
                cachedWaveMeshInfo = new List <TMP_MeshInfo[]>();
                cachedWaveMeshInfo.Clear();

                foreach (TMP_WordInfo wordInfo in waveInfo)
                {
                    cachedWaveMeshInfo.Add(wordInfo.textComponent.textInfo.CopyMeshInfoVertexData());
                }

                if (hasTextChanged)
                {
                    foreach (TMP_WordInfo wordInfo in waveInfo)
                    {
                        cachedWaveMeshInfo.Add(wordInfo.textComponent.textInfo.CopyMeshInfoVertexData());
                    }

                    hasTextChanged = false;
                }

                foreach (TMP_WordInfo info in waveInfo)
                {
                    int waveCharacterCount = info.characterCount;

                    foreach (TMP_MeshInfo[] cMI in cachedWaveMeshInfo)
                    {
                        if (waveCharacterCount == 0)
                        {
                            yield return(new WaitForSeconds(0.25f));

                            continue;
                        }

                        for (int i = 0; i < waveCharacterCount; i++)
                        {
                            int waveCharIndex = info.firstCharacterIndex + i;

                            TMP_CharacterInfo waveCharInfo = dM.dialogueText.textInfo.characterInfo[waveCharIndex];

                            if (!waveCharInfo.isVisible)
                            {
                                continue;
                            }

                            int waveMaterialIndex = dM.dialogueText.textInfo.characterInfo[waveCharIndex].materialReferenceIndex;

                            int waveVertexIndex = dM.dialogueText.textInfo.characterInfo[waveCharIndex].vertexIndex;

                            Vector3[] waveSourceVertices = cMI[waveMaterialIndex].vertices;

                            Vector2 waveCharMidBasline = (waveSourceVertices[waveVertexIndex + 0] + waveSourceVertices[waveVertexIndex + 2]) / 2;

                            Vector3 waveOffset = waveCharMidBasline;

                            Vector3[] waveDestinationVertices = dM.dialogueText.textInfo.meshInfo[waveMaterialIndex].vertices;

                            if (loopCount == 0)
                            {
                                SetInitialCoordinates(waveCharIndex, waveOffset);
                            }

                            waveDestinationVertices[waveVertexIndex + 0] = waveSourceVertices[waveVertexIndex + 0] - waveOffset;
                            waveDestinationVertices[waveVertexIndex + 1] = waveSourceVertices[waveVertexIndex + 1] - waveOffset;
                            waveDestinationVertices[waveVertexIndex + 2] = waveSourceVertices[waveVertexIndex + 2] - waveOffset;
                            waveDestinationVertices[waveVertexIndex + 3] = waveSourceVertices[waveVertexIndex + 3] - waveOffset;

                            Vector3 waveEffectOffset = new Vector3(0, Mathf.Cos((waveCharIndex * waveFrequency) - Time.time * 6) * 2, 0);

                            waveMatrix = Matrix4x4.TRS(waveEffectOffset, Quaternion.Euler(0, 0, 0), Vector3.one);

                            waveDestinationVertices[waveVertexIndex + 0] = waveMatrix.MultiplyPoint3x4(waveDestinationVertices[waveVertexIndex + 0]);
                            waveDestinationVertices[waveVertexIndex + 1] = waveMatrix.MultiplyPoint3x4(waveDestinationVertices[waveVertexIndex + 1]);
                            waveDestinationVertices[waveVertexIndex + 2] = waveMatrix.MultiplyPoint3x4(waveDestinationVertices[waveVertexIndex + 2]);
                            waveDestinationVertices[waveVertexIndex + 3] = waveMatrix.MultiplyPoint3x4(waveDestinationVertices[waveVertexIndex + 3]);

                            waveDestinationVertices[waveVertexIndex + 0].y += waveEffectOffset.y;
                            waveDestinationVertices[waveVertexIndex + 1].y += waveEffectOffset.y;
                            waveDestinationVertices[waveVertexIndex + 2].y += waveEffectOffset.y;
                            waveDestinationVertices[waveVertexIndex + 3].y += waveEffectOffset.y;


                            waveDestinationVertices[waveVertexIndex + 0].y += initialYVal[waveCharIndex];
                            waveDestinationVertices[waveVertexIndex + 1].y += initialYVal[waveCharIndex];
                            waveDestinationVertices[waveVertexIndex + 2].y += initialYVal[waveCharIndex];
                            waveDestinationVertices[waveVertexIndex + 3].y += initialYVal[waveCharIndex];

                            waveDestinationVertices[waveVertexIndex + 0].x += waveOffset.x;
                            waveDestinationVertices[waveVertexIndex + 1].x += waveOffset.x;
                            waveDestinationVertices[waveVertexIndex + 2].x += waveOffset.x;
                            waveDestinationVertices[waveVertexIndex + 3].x += waveOffset.x;
                        }
                    }
                }
            }

            for (int i = 0; i < dM.dialogueText.textInfo.meshInfo.Length; i++)
            {
                dM.dialogueText.textInfo.meshInfo[i].mesh.vertices = dM.dialogueText.textInfo.meshInfo[i].vertices;
                dM.dialogueText.UpdateGeometry(dM.dialogueText.textInfo.meshInfo[i].mesh, i);
            }

            loopCount += 1;

            lastTime = Time.time;

            yield return(new WaitForSecondsRealtime(0.01f));
        }
    }
Пример #8
0
    IEnumerator AnimateVertex()
    {
        textComponent.ForceMeshUpdate();

        var textInfo = textComponent.textInfo;

        Matrix4x4 matrix;

        int loopCount = 0;

        hasTextChanged = true;

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

        TMP_MeshInfo[] cachedMeshInfo = textInfo.CopyMeshInfoVertexData();

        while (true)
        {
            if (hasTextChanged)
            {
                cachedMeshInfo = textInfo.CopyMeshInfoVertexData();
                hasTextChanged = false;
            }

            int characterCount = textInfo.characterCount;

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

                if (!charInfo.isVisible)
                {
                    continue;
                }

                VertexAnim vertAnim      = vertexAnim[i];
                int        materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
                int        vertexIndex   = textInfo.characterInfo[i].vertexIndex;

                Vector3[] sourceVertices = cachedMeshInfo[materialIndex].vertices;

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

                Vector3 offset = charMidBaseLine;

                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 wobblingOffset = new Vector3(
                    Random.Range(-0.25f, 0.25f),
                    Random.Range(-0.25f, 0.25f), 0);

                matrix = Matrix4x4.TRS(
                    wobblingOffset * 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;
            }

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

            loopCount += 1;

            yield return(new WaitForSeconds(1f * SpeedMultiplier));
        }
    }
Пример #9
0
    private IEnumerator ShakeText(int startIndex, int endIndex)
    {
        textBoxDialogue.ForceMeshUpdate();
        textChanged = true;
        TMP_TextInfo textInfo = textBoxDialogue.textInfo;
        Matrix4x4    matrix;
        int          loopCount = 0;

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

        TMP_MeshInfo[] cachedMeshInfo = textInfo.CopyMeshInfoVertexData();

        while (true)
        {
            if (textChanged)
            {
                cachedMeshInfo = textInfo.CopyMeshInfoVertexData();
                textChanged    = false;
            }
            int charCount = textInfo.characterCount;
            if (charCount == 0)
            {
                yield return(new WaitForSeconds(typewriterTime));

                continue;
            }

            for (int i = startIndex; i < endIndex; i++)
            {
                TMP_CharacterInfo charInfo = textInfo.characterInfo[i];
                if (!charInfo.isVisible)
                {
                    continue;
                }

                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;
                textBoxDialogue.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
            }
            loopCount += 1;

            yield return(new WaitForSeconds(0.1f));

            yield return(new WaitForEndOfFrame());
        }
    }
Пример #10
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;
            Vector3[][] copyOfVertices = new Vector3[0][];

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

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

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

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

                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 vertices of the mesh used by this text element (character or sprite).
                    Vector3[] sourceVertices = textInfo.meshInfo[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);
                    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;

                    copyOfVertices[materialIndex][vertexIndex + 0] = sourceVertices[vertexIndex + 0] - offset;
                    copyOfVertices[materialIndex][vertexIndex + 1] = sourceVertices[vertexIndex + 1] - offset;
                    copyOfVertices[materialIndex][vertexIndex + 2] = sourceVertices[vertexIndex + 2] - offset;
                    copyOfVertices[materialIndex][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);

                    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]);

                    copyOfVertices[materialIndex][vertexIndex + 0] += offset;
                    copyOfVertices[materialIndex][vertexIndex + 1] += offset;
                    copyOfVertices[materialIndex][vertexIndex + 2] += offset;
                    copyOfVertices[materialIndex][vertexIndex + 3] += offset;

                    vertexAnim[i] = vertAnim;
                }

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

                loopCount += 1;

                yield return new WaitForSeconds(0.1f);
            }
        }
Пример #11
0
    IEnumerator TextJitter()
    {
        List <TMP_WordInfo> wInfo;

        wInfo = new List <TMP_WordInfo>();

        int[] wordsToJitter;

        wordsToJitter = null;

        if (jitterWords != null)
        {
            wordsToJitter = jitterWords.ToArray();
        }
        else
        {
            wordsToJitter = textFX[sentenceCount].jitterIndexes;
        }

        while (true)
        {
            if (sentenceCount < textFX.Length)
            {
                if (textFX[sentenceCount].wordColors.keyWords.Length != 0)
                {
                    SetTextColor(keyColor, textFX[sentenceCount].wordColors.keyWords);
                }
                else if (textFX[sentenceCount].wordColors.characterWords.Length != 0)
                {
                    SetTextColor(characterColor, textFX[sentenceCount].wordColors.characterWords);
                }
                else if (textFX[sentenceCount].wordColors.redWords.Length != 0)
                {
                    SetTextColor(redColor, textFX[sentenceCount].wordColors.redWords);
                }
                else if (textFX[sentenceCount].wordColors.mechanicWords.Length != 0)
                {
                    SetTextColor(mechanicColor, textFX[sentenceCount].wordColors.mechanicWords);
                }
                else
                {
                    dialogueText.ForceMeshUpdate(true);
                }
            }

            wInfo.Clear();

            foreach (int wordIndex in wordsToJitter)
            {
                //Add each word's wordInfo
                wInfo.Add(dialogueText.textInfo.wordInfo[wordIndex]);
            }

            Matrix4x4 matrix;

            int loopCount = 0;
            hasTextChanged = true;

            List <TMP_MeshInfo[]> cachedMeshInfo;
            cachedMeshInfo = new List <TMP_MeshInfo[]>();
            cachedMeshInfo.Clear();

            foreach (TMP_WordInfo wordInfo in wInfo)
            {
                cachedMeshInfo.Add(wordInfo.textComponent.textInfo.CopyMeshInfoVertexData());
            }

            if (hasTextChanged)
            {
                foreach (TMP_WordInfo wordInfo in wInfo)
                {
                    cachedMeshInfo.Add(wordInfo.textComponent.textInfo.CopyMeshInfoVertexData());
                }

                hasTextChanged = false;
            }

            foreach (TMP_WordInfo info in wInfo)
            {
                foreach (TMP_MeshInfo[] cMI in cachedMeshInfo)
                {
                    int characterCount = info.characterCount;

                    if (characterCount == 0)
                    {
                        yield return(new WaitForSeconds(0.25f));

                        continue;
                    }

                    for (int i = 0; i < characterCount; i++)
                    {
                        int charIndex = info.firstCharacterIndex + i;

                        TMP_CharacterInfo charInfo = dialogueText.textInfo.characterInfo[charIndex];

                        if (!charInfo.isVisible)
                        {
                            continue;
                        }

                        VertexAnim vertAnim = vertexAnim[charIndex];

                        int materialIndex = dialogueText.textInfo.characterInfo[charIndex].materialReferenceIndex;

                        int vertexIndex = dialogueText.textInfo.characterInfo[charIndex].vertexIndex;

                        Vector3[] sourceVertices = cMI[materialIndex].vertices;

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

                        Vector3 offset = charMidBasline;

                        Vector3[] destinationVertices = dialogueText.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;
                    }
                }
            }
            for (int i = 0; i < dialogueText.textInfo.meshInfo.Length; i++)
            {
                dialogueText.textInfo.meshInfo[i].mesh.vertices = dialogueText.textInfo.meshInfo[i].vertices;
                dialogueText.UpdateGeometry(dialogueText.textInfo.meshInfo[i].mesh, i);
            }

            loopCount += 1;

            yield return(new WaitForSeconds(0.1f));
        }
    }
Пример #12
0
        //Jitters the part of the text
        public IEnumerator Jitter(RPGTalkJitter jitter)
        {
#if RPGTalk_TMP
            if (TMPText == null)
            {
                Debug.LogError("Only TextMeshPro users can use the Jitter Tag");
                yield return(null);
            }


            TMP_TextInfo textInfo = TMPText.textInfo;
            // 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();
            int            characterCount = textInfo.characterCount;

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

            int loopCount = 0;

            Matrix4x4 matrix;

            while (true)
            {
                int repeatUntil = jitter.jitterPosition + jitter.numberOfCharacters;


                // yield until we have all the characters in the jitter
                while (characterCount < repeatUntil)
                {
                    // Update the copy of the vertex data for the text object.
                    cachedMeshInfo = textInfo.CopyMeshInfoVertexData();
                    characterCount = textInfo.characterCount;


                    yield return(new WaitForEndOfFrame());

                    continue;
                }



                for (int i = jitter.jitterPosition; i < repeatUntil; 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;

                    // If we dont have the vertices yet, don't do it
                    if (sourceVertices.Length < vertexIndex + 3)
                    {
                        continue;
                    }

                    // 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 * jitter.jitter, Quaternion.Euler(0, 0, Random.Range(-5f, 5f) * jitter.angle), 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;
                    TMPText.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
                }

                loopCount += 1;

                yield return(new WaitForSeconds(0.1f));
            }
#else
            Debug.LogError("Only TextMeshPro users can use the Jitter Tag");
            yield return(null);
#endif
        }