Пример #1
0
    private IEnumerator AnimateText(string actor, string text)
    {
        isAnimatingText = true;
        TMP_Text dialogueBox = textMeshPro.GetComponent <TextMeshProUGUI>();

        dialogueBox.text = StripAllCommands(text);
        dialogueBox.ForceMeshUpdate();

        dialogueBox.fontSize  = FontSize;
        dialogueBox.alignment = TextAlignmentOptions.TopJustified;

        specialCommands = BuildSpecialCommandList(text);

        //Count how many characters we have in our new dialogue line.
        TMP_TextInfo textInfo        = dialogueBox.textInfo;
        int          totalCharacters = dialogueBox.textInfo.characterCount;

        LoadImage(actor);

        //Base color for our text.
        Color32 c0 = dialogueBox.color;

        //Shake text if true.
        if (isTextShaking)
        {
            StartCoroutine(ShakingText(dialogueBox));
        }

        //We now hide text based on each character's alpha value
        HideText(dialogueBox);

        var i = 0;

        while (i < totalCharacters)
        {
            //If we change the text live on runtime in our inspector, adjust the character count!
            if (hasTextChanged)
            {
                totalCharacters = textInfo.characterCount; // Update visible character count.
                hasTextChanged  = false;
            }

            if (specialCommands.Count > 0)
            {
                CheckForCommands(i, dialogueBox);
            }

            //Instead of incrementing maxVisibleCharacters or add the current character to our string, we do this :

            // 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).
            //Color of all characters' vertices.
            var newVertexColors = textInfo.meshInfo[materialIndex].colors32;

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

            // Only change the vertex color if the text element is visible. (It's visible, only the alpha color is 0)
            if (textInfo.characterInfo[i].isVisible && isColorizing == false)
            {
                UpdateVertexColors(newVertexColors, vertexIndex, c0, dialogueBox);
            }
            else if (textInfo.characterInfo[i].isVisible && isColorizing == true)
            {
                UpdateVertexColors(newVertexColors, vertexIndex, c1, dialogueBox);
            }

            i++;

            if (!skip)
            {
                yield return(new WaitForSeconds(SpeedText));
            }
        }

        Debug.Log("Done animating!");
        isAnimatingText = false;
        yield return(null);
    }
Пример #2
0
        public override void SetQuestion(Question q, UnityAction <Question> answeredEvent, UISkinData skinData)
        {
            base.SetQuestion(q, answeredEvent, skinData);
            radioListQuestion     = question as RadioListQuestion;
            instructionsText.text = question.instructions;
            idText.text           = question.id;


            toggles = new List <Toggle>();
            //VariableGridLayoutGroup gridLayout;
            //LayoutGroup layoutGroup;

            //if(radioListQuestion.horizontal) {
            //	layoutGroup = itemsUI.gameObject.AddComponent<HorizontalLayoutGroup>();
            //	layoutGroup.childAlignment = TextAnchor.MiddleCenter;
            //	layoutGroup.padding.left = 1;
            //	layoutGroup.padding.right = 1;
            //	layoutGroup.padding.top = 1;
            //	layoutGroup.padding.bottom = 1;
            //} else {
            //	layoutGroup = itemsUI.gameObject.AddComponent<VerticalLayoutGroup>();
            //	layoutGroup.childAlignment = TextAnchor.MiddleCenter;
            //	layoutGroup.padding.left = 1;
            //	layoutGroup.padding.right = 1;
            //	layoutGroup.padding.top = 1;
            //	layoutGroup.padding.bottom = 1;
            //}
            VariableGridLayoutGroup gridLayoutGroup = itemsUI.gameObject.AddComponent <VariableGridLayoutGroup>();

            gridLayoutGroup.childAlignment  = TextAnchor.MiddleCenter;
            gridLayoutGroup.padding.left    = 1;
            gridLayoutGroup.padding.right   = 1;
            gridLayoutGroup.padding.top     = 1;
            gridLayoutGroup.padding.bottom  = 1;
            gridLayoutGroup.spacing         = new Vector2(0, skinData.fontSizeBody);
            gridLayoutGroup.constraint      = VariableGridLayoutGroup.Constraint.FixedColumnCount;
            gridLayoutGroup.constraintCount = 2;


            for (int i = 0; i < radioListQuestion.labels.Length; i++)
            {
                //GameObject container = new GameObject("container",typeof(RectTransform));
                //container.AddComponent<HorizontalLayoutGroup>();
                GameObject label = Instantiate(labelPrefab);

                LayoutElement labelLayout = label.GetComponent <LayoutElement>();
                labelLayout.flexibleWidth  = skinData.canvasSize.x * 0.6f;                // 10;
                labelLayout.preferredWidth = skinData.canvasSize.x * 0.75f;
                labelLayout.minWidth       = -1;
                labelLayout.minHeight      = -1;


                //labelLayout.flexibleWidth = 10;
                //labelLayout.preferredWidth = 12;
                //labelLayout.minWidth = -1;
                //labelLayout.minHeight = -1;

                TMP_Text text = label.GetComponent <TMP_Text>();
                text.text = radioListQuestion.labels[i];
                //text.autoSizeTextContainer = true;
                //text.enableAutoSizing = true;
                text.ForceMeshUpdate(true);

                text.GetComponent <SkinText>().textFormat = TextFormat.Body;

                text.margin = new Vector4(text.fontSize, 0, 0, 0);

                GameObject    radioItem    = Instantiate(radioItemPrefab);
                Toggle        toggle       = radioItem.GetComponent <Toggle>();
                LayoutElement toggleLayout = toggle.GetComponent <LayoutElement>();
                toggleLayout.flexibleWidth = 1;

                toggle.SetIsOnWithoutNotify(false);
                toggles.Add(toggle);
                toggle.onValueChanged.AddListener((val) => {
                    OnItemSelected(toggle, radioListQuestion.id, val);
                });
                //container.transform.parent = itemsUI;
                radioItem.transform.parent = itemsUI;
                label.transform.parent     = itemsUI;


                //container.transform.localPosition = Vector3.zero;
                //container.transform.localRotation = Quaternion.identity;
                //container.transform.localScale = Vector3.one;

                label.transform.localPosition = Vector3.zero;
                label.transform.localRotation = Quaternion.identity;
                label.transform.localScale    = Vector3.one;              // label.transform.parent.localScale;

                radioItem.transform.localPosition = Vector3.zero;
                radioItem.transform.localRotation = Quaternion.identity;
                radioItem.transform.localScale    = Vector3.one;             // radioItem.transform.parent.localScale;

                if (label.GetComponent <Button>())
                {
                    Button btn = label.GetComponent <Button>();
                    btn.onClick.AddListener(() => {
                        toggle.isOn = !toggle.isOn;
                    });
                }
            }
            LayoutRebuilder.ForceRebuildLayoutImmediate(itemsUI);
            //Canvas.ForceUpdateCanvases();
        }
Пример #3
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.
            _mTextComponent.ForceMeshUpdate();

            TMP_TextInfo textInfo = _mTextComponent.textInfo;

            Matrix4x4 matrix;

            Vector3[][] 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 (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;
                }

                int lineCount = textInfo.lineCount;

                // Iterate through each line of the text.
                for (int i = 0; i < lineCount; i++)
                {
                    int first = textInfo.lineInfo[i].firstCharacterIndex;
                    int 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 (int 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.
                        int materialIndex = textInfo.characterInfo[j].materialReferenceIndex;

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

                        // Get the vertices of the mesh used by this text element (character or sprite).
                        Vector3[] 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.
                        float 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 (int i = 0; i < textInfo.meshInfo.Length; i++)
                {
                    textInfo.meshInfo[i].mesh.vertices = copyOfVertices[i];
                    _mTextComponent.UpdateGeometry(textInfo.meshInfo[i].mesh, i);
                }

                yield return(new WaitForSeconds(0.1f));
            }
        }
Пример #4
0
    IEnumerator RevealText()
    {
        m_TextComponent.ForceMeshUpdate();

        if (runningEffect != null)
        {
            StopCoroutine(runningEffect);
        }
        runningEffect = AnimateVertexColors();
        StartCoroutine(runningEffect);

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

        Color32[] newVertexColors;

        // Turn everything invisible
        for (int i = 0; i < numCharacters; i++)
        {
            int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
            newVertexColors = textInfo.meshInfo[materialIndex].colors32;
            int vertexIndex = textInfo.characterInfo[i].vertexIndex;

            // Set new alpha values.
            newVertexColors[vertexIndex + 0].a = 0;
            newVertexColors[vertexIndex + 1].a = 0;
            newVertexColors[vertexIndex + 2].a = 0;
            newVertexColors[vertexIndex + 3].a = 0;
        }
        m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);

        for (int i = 0; i < numCharacters; i++)
        {
            if (disabled || finished)
            {
                break;
            }

            if (!textInfo.characterInfo[i].isVisible)
            {
                continue;
            }

            int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
            newVertexColors = textInfo.meshInfo[materialIndex].colors32;
            int vertexIndex = textInfo.characterInfo[i].vertexIndex;

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

            m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
            yield return(new WaitForSecondsRealtime(0.03f / speedMultiplier));
        }

        finished = true;

        dialogueHUD.OnDialogueRevealEnd();
    }
Пример #5
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));
            }
        }
Пример #6
0
 public void onTextStarted()
 {
     textField.ForceMeshUpdate();
     //Vector2 preferredWidth = textField.GetPreferredValues(textField.text,);
     Resize(textField.renderedWidth, textField.renderedHeight);
 }
Пример #7
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;

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

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

                    float   angle        = Mathf.Sin(Time.time * 10 + i * 0.8f) * 5;
                    float   x            = Mathf.Sin(Time.time * 8 + i * 0.8f) * ScaleX;
                    float   y            = Mathf.Sin(Time.time * 11 + i * 0.8f) * ScaleY;
                    Vector3 jitterOffset = new Vector3(x, y, 0);

                    matrix = Matrix4x4.TRS(jitterOffset, Quaternion.Euler(0, 0, angle * 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;
                }

                // 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(null);
                //                yield return new WaitForSeconds(0.1f);
            }
        }
Пример #8
0
    IEnumerator AnimateVertexColors()
    {
        // Force the text object to update right away so we can have geometry to modify right from the start.
        m_TextComponent.ForceMeshUpdate();

        TMP_TextInfo textInfo = m_TextComponent.textInfo;

        Color32[] newVertexColors;
        Color32   c0 = m_TextComponent.color;
        int       currentCharacterWave = 0;

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

            if (!active)
            {
                for (int currentCharacter = 0; currentCharacter < characterCount; currentCharacter++)
                {
                    int materialIndex = textInfo.characterInfo[currentCharacter].materialReferenceIndex;
                    newVertexColors = textInfo.meshInfo[materialIndex].colors32;
                    int vertexIndex = textInfo.characterInfo[currentCharacter].vertexIndex;

                    if (!textInfo.characterInfo[currentCharacter].isVisible)
                    {
                        continue;
                    }


                    int r = 255;
                    int g = 255;
                    int b = 255;
                    int a = 255;

                    c0 = new Color32((byte)r, (byte)g, (byte)b, (byte)a);

                    newVertexColors[vertexIndex + 0] = c0;
                    newVertexColors[vertexIndex + 1] = c0;
                    newVertexColors[vertexIndex + 2] = c0;
                    newVertexColors[vertexIndex + 3] = c0;
                    m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
                }
            }
            else
            {
                int materialIndex = textInfo.characterInfo[currentCharacterWave].materialReferenceIndex;
                newVertexColors = textInfo.meshInfo[materialIndex].colors32;
                int vertexIndex = textInfo.characterInfo[currentCharacterWave].vertexIndex;

                if (textInfo.characterInfo[currentCharacterWave].isVisible)
                {
                    int r = (int)((Mathf.Sin(Time.time) + 1) / 2 * 255 / 2);
                    int g = (int)((Mathf.Cos(Time.time) + 1) / 2 * 255 / 2);
                    int b = 255;
                    int a = 255;

                    c0 = new Color32((byte)r, (byte)g, (byte)b, (byte)a);


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

                    // New function which pushes (all) updated vertex data to the appropriate meshes when using either the Mesh Renderer or CanvasRenderer.
                    m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);

                    // This last process could be done to only update the vertex data that has changed as opposed to all of the vertex data but it would require extra steps and knowing what type of renderer is used.
                    // These extra steps would be a performance optimization but it is unlikely that such optimization will be necessary.
                }

                currentCharacterWave = (currentCharacterWave + 1) % characterCount;
            }

            yield return(new WaitForSeconds(0.005f));
        }
    }
        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);
            }
        }
Пример #10
0
    IEnumerator Showing()
    {
        tmpTextObject.ForceMeshUpdate();

        //Taken from a text mesh pro example

        TMP_TextInfo textInfo = tmpTextObject.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 / textSpeed);


            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;


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

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

                        yield return(new WaitForSeconds(1.0f));

                        // Reset the text object back to original state.
                        tmpTextObject.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.
            tmpTextObject.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);

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

            yield return(new WaitForSeconds(0.25f - fadeSpeed * 0.01f));
        }
    }
Пример #11
0
        /// <summary>
        ///  Method to curve text along a Unity animation curve.
        /// </summary>
        /// <param name="textComponent"></param>
        /// <returns></returns>
        IEnumerator WarpText()
        {
            //HERE IS THE LINE THAT F***S EVERYTHING UP !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            // VertexCurve.preWrapMode = WrapMode.Loop;
            // VertexCurve.postWrapMode = WrapMode.Loop;

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

            float _time = 0;

            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.color = color;

                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 + _time * SpeedMultiplier) * CurveScale;
                    float y1 = VertexCurve.Evaluate(x1 + _time * SpeedMultiplier) * 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 WaitForSecondsRealtime(0.025f));

                _time += 0.025f;
            }
        }
Пример #12
0
    void UpdateCurveMesh()
    {
        textComponent.ForceMeshUpdate();

        TMP_TextInfo textInfo       = textComponent.textInfo;
        int          characterCount = textInfo.characterCount;

        if (characterCount == 0)
        {
            return;
        }

        Vector3 baseline                = new Vector3();
        Vector3 prevAngleDirection      = new Vector3();
        Vector3 prevOffsetToMidBaseline = new Vector3();

        Vector3[] vertices;
        Matrix4x4 matrix;
        float     defaultBaseLine = 0;
        float     maxBaseLine     = float.MinValue;
        float     minBaseLine     = float.MaxValue;
        bool      isFirst         = true;

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

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

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

            //文字の真ん中の点と文字の基準となるベースラインの高さを取得
            Vector3 offsetToMidBaseline = new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2, textInfo.characterInfo[i].baseLine);

            //文字の中央の下が原点となるように頂点を移動(これから回転と移動をさせるため)
            vertices[vertexIndex + 0] += -offsetToMidBaseline;
            vertices[vertexIndex + 1] += -offsetToMidBaseline;
            vertices[vertexIndex + 2] += -offsetToMidBaseline;
            vertices[vertexIndex + 3] += -offsetToMidBaseline;

            //曲線の傾き(agnle)の計算
            float   x0             = (float)(i + 1) / (characterCount + 1);
            float   x1             = x0 + 0.0001f;
            float   y0             = vertexCurve.Evaluate(x0);
            float   y1             = vertexCurve.Evaluate(x1);
            Vector3 horizontal     = new Vector3(1, 0, 0);
            Vector3 tangent        = new Vector3(0.0001f, (y1 - y0));
            Vector3 angleDirection = tangent.normalized;
            float   angle          = Mathf.Acos(Vector3.Dot(horizontal, angleDirection)) * Mathf.Rad2Deg;
            Vector3 cross          = Vector3.Cross(horizontal, tangent);
            angle = cross.z > 0 ? angle : 360 - angle;

            //angle回転させた頂点位置の計算
            matrix = Matrix4x4.Rotate(Quaternion.Euler(0, 0, angle));
            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]);

            //文字間の計算
            float characterSpace;
            if (isFirst)
            {
                baseline        = offsetToMidBaseline;
                defaultBaseLine = baseline.y;
                characterSpace  = 0;
                isFirst         = false;
            }
            else
            {
                characterSpace = (offsetToMidBaseline - prevOffsetToMidBaseline).magnitude;
            }
            prevOffsetToMidBaseline = offsetToMidBaseline;

            //文字位置を計算して移動
            baseline = baseline + (angleDirection + prevAngleDirection).normalized * characterSpace;
            vertices[vertexIndex + 0] += baseline;
            vertices[vertexIndex + 1] += baseline;
            vertices[vertexIndex + 2] += baseline;
            vertices[vertexIndex + 3] += baseline;

            prevAngleDirection = angleDirection;

            minBaseLine = Mathf.Min(minBaseLine, baseline.y);
            maxBaseLine = Mathf.Max(maxBaseLine, baseline.y);
        }

        //揃えの計算
        if (hAlignment != TextAlignment.Left || vAlignment != TextVAlignment.Base)
        {
            float hOffset = 0;
            if (hAlignment == TextAlignment.Center)
            {
                hOffset = (prevOffsetToMidBaseline.x - baseline.x) * 0.5f;
            }
            else if (hAlignment == TextAlignment.Right)
            {
                hOffset = (prevOffsetToMidBaseline.x - baseline.x);
            }

            float vOffset = 0;
            if (vAlignment == TextVAlignment.Bottom)
            {
                vOffset = defaultBaseLine - minBaseLine;
            }
            else if (vAlignment == TextVAlignment.Top)
            {
                vOffset = defaultBaseLine - maxBaseLine;
            }

            Vector3 alignOffset = new Vector3(hOffset, vOffset, 0);

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

                int vertexIndex   = textInfo.characterInfo[i].vertexIndex;
                int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
                vertices = textInfo.meshInfo[materialIndex].vertices;

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

        textComponent.UpdateVertexData();
    }
Пример #13
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));
        }
    }
Пример #14
0
    void Update()
    {
        if (mode == 0)
        {
            // Set the TMP object to show all of the currentDialog string, so we can
            // calculate line lengths in order to show characters one at a time.
            tmp.text            = currentDialog;
            tmp.maxVisibleLines = 3;
            // Need to call this for GetTextInfo() to work.
            tmp.ForceMeshUpdate();
            mode = 1;

            // Use the lastCharacterIndex of each line to split up the source string into lines,
            // in order to manage line display
            TMP_LineInfo[] lineInfoList = tmp.GetTextInfo(tmp.text).lineInfo;
            lineStrings = new List <string>();

            foreach (TMP_LineInfo lineInfo in lineInfoList)
            {
                int last  = lineInfo.lastCharacterIndex;
                int first = lineInfo.firstCharacterIndex;

                // Not sure why but lineinfo has garbage at the end where first/last are zero, so stop in this case.
                if (first == 0 && last == 0)
                {
                    break;
                }

                // sometimes line infos go past whats visible idk why
                if (first >= currentDialog.Length)
                {
                    break;
                }

                lineStrings.Add(currentDialog.Substring(first, (last - first) + 1));
            }

            // Keeps track of where to start pulling lines out of lineStrings
            currentLineIndex = 0;

            setLines(tmp, lineStrings, currentLineIndex, tmp.maxVisibleLines);

            tmp.maxVisibleCharacters = 0;
        }
        else if (mode == 1)
        {
            tmp.maxVisibleCharacters++;

            if (tmp.maxVisibleCharacters >= tmp.GetTextInfo(tmp.text).characterCount)
            {
                mode = 2;
            }
        }
        else if (mode == 2 && Input.GetButtonDown("Jump"))
        {
            // remove the first line.
            currentLineIndex++;

            // If this is true then the last line of dialogue already finished, so exit (or reset in this case.)
            if (currentLineIndex > lineStrings.Count - tmp.maxVisibleLines)
            {
                mode     = 3;
                tmp.text = "";
            }
            else
            {
                setLines(tmp, lineStrings, currentLineIndex, tmp.maxVisibleLines);
                tmp.maxVisibleCharacters = tmp.GetTextInfo(tmp.text).lineInfo[tmp.maxVisibleLines - 2].lastCharacterIndex;
                mode = 1;
            }
        }
        else if (mode == 3)
        {
            // Do nothing, text is done for now.
        }
    }
Пример #15
0
        public override void SetQuestion(Question q, UnityAction <Question> answeredEvent, UISkinData skinData)
        {
            base.SetQuestion(q, answeredEvent, skinData);

            instructionsText.text = question.instructions;
            idText.text           = question.id;

            toggles              = new List <Toggle>();
            checkQuestion        = (question as CheckListQuestion);
            gridLayout.startAxis = VariableGridLayoutGroup.Axis.Horizontal;


            int factor = checkQuestion.questions.Length / maxQuestionsVertical;

            factor = (factor == 0 ? 1 : factor);

            //if(checkQuestion.horizontal) {
            //	gridLayout.constraint = VariableGridLayoutGroup.Constraint.FixedRowCount;
            //	gridLayout.constraintCount = 1;
            //	gridLayout.childAlignment = TextAnchor.MiddleCenter;
            //}else{
            gridLayout.constraint = VariableGridLayoutGroup.Constraint.FixedColumnCount;

            gridLayout.constraintCount = 2 * factor;
            gridLayout.childAlignment  = TextAnchor.MiddleCenter;
            gridLayout.spacing         = spacing;

            maxWidth  = maxTextWidth / factor;
            maxHeight = maxTextHeight / factor;
            //}

            for (int i = 0; i < checkQuestion.questions.Length; i++)
            {
                //GameObject labeledItem = Instantiate(checkItemLabeledPrefab);
                //GameObject checkItem = labeledItem.transform.Find("Checkbox").gameObject;

                GameObject checkItem = Instantiate(checkItemPrefab);
                Toggle     toggle    = checkItem.GetComponent <Toggle>();
                toggle.isOn = false;
                toggle.onValueChanged.AddListener(HandleToggleValueChanged);

                LayoutElement toggleLayout = toggle.GetComponent <LayoutElement>();
                toggleLayout.enabled   = true;
                toggleLayout.minWidth  = skinData.toggleSize.x;
                toggleLayout.minHeight = skinData.toggleSize.y;

                toggles.Add(toggle);


                //GameObject label = labeledItem.transform.Find("QuestionLabelInteractive").gameObject;
                GameObject label = Instantiate(labelPrefab);
                TMP_Text   text  = label.GetComponent <TMP_Text>();
                text.text   = checkQuestion.questions[i].text;
                text.margin = new Vector4(-spacing.x / 4f, 0, 0, 0);

                text.autoSizeTextContainer = true;
                //text.enableAutoSizing = true;
                text.ForceMeshUpdate(true);


                LayoutElement labelLayout = label.GetComponent <LayoutElement>();
                //float w = text.preferredWidth * preferredWidthScaler;
                //float h = text.preferredHeight * preferredHeightScaler;
                ////labelLayout.preferredWidth = - 1;
                ////labelLayout.preferredHeight = - 1;
                //labelLayout.preferredWidth = -1; //Mathf.Clamp(w,0,maxWidth);
                //labelLayout.preferredHeight = -1; // Mathf.Clamp(h,0,maxHeight);
                if (factor == 1)
                {
                    labelLayout.flexibleWidth  = skinData.canvasSize.x * 0.6f;                    // 10;
                    labelLayout.preferredWidth = skinData.canvasSize.x * 0.75f;
                    labelLayout.minWidth       = -1;
                    labelLayout.minHeight      = -1;
                }

                if (label.GetComponent <Button>())
                {
                    Button btn = label.GetComponent <Button>();
                    btn.onClick.AddListener(() => {
                        toggle.isOn = !toggle.isOn;
                    });
                }

                //labeledItem.transform.parent = itemsUI;
                checkItem.transform.parent = itemsUI;
                label.transform.parent     = itemsUI;

                label.transform.localPosition = new Vector3(0, 0, skinData.radioZOffset);
                label.transform.localRotation = Quaternion.identity;
                label.transform.localScale    = label.transform.parent.localScale;

                checkItem.transform.localPosition = new Vector3(0, 0, skinData.radioZOffset);
                //checkItem.transform.localPosition = Vector3.zero;
                checkItem.transform.localRotation = Quaternion.identity;
                checkItem.transform.localScale    = label.transform.parent.localScale;
            }
            LayoutRebuilder.ForceRebuildLayoutImmediate(itemsUI);
        }
Пример #16
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();
        }
Пример #17
0
 public void TypeInstantly(TMP_Text textMeshPro)
 {
     StopCoroutine(revealTextCoroutine);
     textMeshPro.maxVisibleCharacters = totalVisibleCharacters;
     textMeshPro.ForceMeshUpdate();
 }
 void RevealCharacters(TMP_Text textComponent)
 {
     textComponent.ForceMeshUpdate();
     textComponent.maxVisibleCharacters = textComponent.textInfo.characterCount;
 }
Пример #19
0
 private float CalculateHeight()
 {
     content.ForceMeshUpdate();
     return(Mathf.Clamp(content.textInfo.lineCount * SIZE_PER_LINE, 120, 600));
 }
Пример #20
0
        /// <summary>
        ///  Method to curve text along a Unity animation curve.
        /// </summary>
        /// <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;
            float          old_ShearValue = ShearAmount;
            AnimationCurve old_curve      = CopyAnimationCurve(VertexCurve);

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

                    continue;
                }

                old_CurveScale = CurveScale;
                old_curve      = CopyAnimationCurve(VertexCurve);
                old_ShearValue = ShearAmount;

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

                /*
                 * if(characterCount < 12)
                 * {
                 *  int rem = 12 - characterCount;
                 *  int addFront = rem / 2;
                 *  int addBack = addFront + rem % 2;
                 *
                 * }
                 */
                //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;
                    }
                    if (textInfo.characterInfo[i].character == '$')
                    {
                        //Debug.Log("Char was a $");
                        // Get the index of the material used by the current character.
                        int a = textInfo.characterInfo[i].materialReferenceIndex;

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

                        // Get the index of the first vertex used by this text element.
                        int     vI = textInfo.characterInfo[i].vertexIndex;
                        Color32 c0 = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255), (byte)Random.Range(0, 255), 0);

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

                        // New function which pushes (all) updated vertex data to the appropriate meshes when using either the Mesh Renderer or CanvasRenderer.
                        m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
                    }

                    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;

                    // Apply the Shearing FX
                    float   shear_value = ShearAmount * 0.01f;
                    Vector3 topShear    = new Vector3(shear_value * (textInfo.characterInfo[i].topRight.y - textInfo.characterInfo[i].baseLine), 0, 0);
                    Vector3 bottomShear = new Vector3(shear_value * (textInfo.characterInfo[i].baseLine - textInfo.characterInfo[i].bottomRight.y), 0, 0);

                    vertices[vertexIndex + 0] += -bottomShear;
                    vertices[vertexIndex + 1] += topShear;
                    vertices[vertexIndex + 2] += topShear;
                    vertices[vertexIndex + 3] += -bottomShear;


                    // 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(null); // new WaitForSeconds(0.025f);
            }
        }
Пример #21
0
        /// <summary>
        /// Method to animate vertex colors of a TMP Text object.
        /// </summary>
        /// <returns></returns>
        IEnumerator AnimateVertexColors()
        {
            // Need to force the text object to be generated so we have valid data to work with right from the start.
            m_TextComponent.ForceMeshUpdate();

            yield return(new WaitForSeconds(0.1f));

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

                            Destroy(this.gameObject);

                            // 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));
            }
            Destroy(this.gameObject);
        }
        private void OnDrawGizmos()
        {
            if (m_TextComponent == null)
            {
                m_TextComponent = GetComponent <TMP_Text>();

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

            m_TextComponent.ForceMeshUpdate();

            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
        }
Пример #23
0
    void UpdateCurveMesh()
    {
        textComponent.ForceMeshUpdate();

        TMP_TextInfo textInfo       = textComponent.textInfo;
        int          characterCount = textInfo.characterCount;

        if (characterCount == 0)
        {
            return;
        }

        float boundsMinX = textComponent.bounds.min.x;
        float boundsMaxX = textComponent.bounds.max.x;

        Vector3[] vertices;
        Matrix4x4 matrix;

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

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

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

            //文字の真ん中の点と文字の基準となるベースラインの高さを取得
            Vector3 offsetToMidBaseline = new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2, textInfo.characterInfo[i].baseLine);

            //文字の中央の下が原点となるように頂点を移動(これから回転と移動をさせるため)
            vertices[vertexIndex + 0] += -offsetToMidBaseline;
            vertices[vertexIndex + 1] += -offsetToMidBaseline;
            vertices[vertexIndex + 2] += -offsetToMidBaseline;
            vertices[vertexIndex + 3] += -offsetToMidBaseline;

            //カーブの傾きに沿って,文字サイズかけてどの程度傾けるかを計算
            //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;
            //float charSize = boundsMaxX - boundsMinX;
            //Vector3 horizontal = new Vector3(1, 0, 0);
            //Vector3 tangent = new Vector3(charSize * 0.0001f, y1 - y0);
            //float angle = Mathf.Acos(Vector3.Dot(horizontal, tangent.normalized)) * Mathf.Rad2Deg;
            //Vector3 cross = Vector3.Cross(horizontal, tangent);
            //angle = cross.z > 0 ? angle : 360 - angle;

            float x0 = (offsetToMidBaseline.x - boundsMinX) / (boundsMaxX - boundsMinX);             // Character's position relative to the bounds of the mesh.
            float y0 = vertexCurve.Evaluate(x0) * curveScale;

            //angle回転させて,baseをy0だけあげるた頂点位置の計算
            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;
        }

        textComponent.UpdateVertexData();
    }
    IEnumerator AnimateVertices()
    {
        //Debug.Log("start");
        animating = true;
        if (!initialized)
        {
            yield return(new WaitForEndOfFrame());
        }
        // 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;

        // Cache the vertex data of the text object as the translate FX is applied to the original position of the characters.
        TMP_MeshInfo[] cachedMeshInfo = textInfo.CopyMeshInfoVertexData();
        Color32[]      newVertexColors;
        Color32        c0 = m_TextComponent.color;

        //start time of this whole animation
        float animStartTime = Time.time;


        while (animating)
        {
            int characterCount = textInfo.characterCount;
            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 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 cached vertices of the mesh used by this text element (character or sprite).
                Vector3[] sourceVertices = cachedMeshInfo[materialIndex].vertices;

                // calculate the pivot for each character. default to center
                Vector2 charPivot = Vector2.zero;
                switch (pivot)
                {
                case LetterPivot.baselineCenter:
                    charPivot = new Vector2((sourceVertices[vertexIndex + 0].x + sourceVertices[vertexIndex + 2].x) / 2, charInfo.baseLine);
                    break;

                case LetterPivot.baselineLeft:
                    charPivot = new Vector2(sourceVertices[vertexIndex + 0].x, charInfo.baseLine);
                    break;

                case LetterPivot.baselineRight:
                    charPivot = new Vector2(sourceVertices[vertexIndex + 0].x + sourceVertices[vertexIndex + 2].x, charInfo.baseLine);
                    break;

                default:
                    //center
                    charPivot = (sourceVertices[vertexIndex + 0] + sourceVertices[vertexIndex + 2]) / 2;
                    break;
                }

                // 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 = charPivot;

                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;

                //progress through the animation
                float p = Mathf.Clamp01((Time.time - (animStartTime + (i * letterDelay))) / duration);

                //ANIMATION MAGIC HAPPENS HERE
                Vector3    currentTranslate = LetterTranslateFunction(p, i, characterCount);
                Quaternion currentRotate    = LetterRotateFunction(p, i, characterCount);
                Vector3    currentScale     = LetterScaleFunction(p, i, characterCount);
                //ok magic's over pass in that magic
                matrix = Matrix4x4.TRS(currentTranslate, currentRotate, currentScale);

                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;

                //apply color animation
                // Only change the vertex color if the text element is visible.
                if (textInfo.characterInfo[i].isVisible)
                {
                    //color animation magic happens here!!!
                    c0 = LetterColorFunction(c0, p, i, characterCount);
                    //kk magic's over pass it all to the verticies
                    newVertexColors[vertexIndex + 0] = c0;
                    newVertexColors[vertexIndex + 1] = c0;
                    newVertexColors[vertexIndex + 2] = c0;
                    newVertexColors[vertexIndex + 3] = c0;

                    // New function which pushes (all) updated vertex data to the appropriate meshes when using either the Mesh Renderer or CanvasRenderer.
                    m_TextComponent.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);

                    // This last process could be done to only update the vertex data that has changed as opposed to all of the vertex data but it would require extra steps and knowing what type of renderer is used.
                    // These extra steps would be a performance optimization but it is unlikely that such optimization will be necessary.
                }

                //if the last character has finished its animation progression, set animating to false
                if (i == characterCount - 1 && p >= 1f)
                {
                    animating = false;
                    //Debug.Log("stopped");
                    OnAnimationComplete();
                }
            }

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

            yield return(new WaitForEndOfFrame());
        }
    }
Пример #25
0
    public void CreateWordList(int currentLetter)
    {
        words = new List <string>();

        foreach (string w in wp.parsedWords[currentLetter])
        {
            words.Add(w);
        }
        panel_start        = true;
        current_word_index = 0;
        panel_count        = 0;
        TypeInput[] ip = FindObjectsOfType <TypeInput>();
        foreach (TypeInput t in ip)
        {
            Destroy(t.transform.parent.gameObject);
        }


        while (current_word_index < words.Count)
        {
            if (panel_start)
            {
                space_in_line = new List <int>();
                Debug.Log("create");
                panel_start   = false;
                current_panel = Instantiate(template_panel);

                current_panel.transform.SetParent(parent.transform, false);
                panel                     = current_panel.GetComponent <TextPanel>();
                panel.order_num           = panel_count;
                panel.user_panel.orderNum = panel.order_num;
            }
            else
            {
                for (int i = current_word_index; i <= words.Count; i++)
                {
                    current_word_index = i;
                    if (current_word_index == words.Count)
                    {
                        break;
                    }

                    Debug.Log(panel);
                    TMP_Text tempText     = panel.panel_text;
                    string   beforeChange = panel.panel_text.text;
                    tempText.text += words[current_word_index];

                    tempText.ForceMeshUpdate();

                    if (words[current_word_index].Contains("\n"))
                    {
                        string[] b = words[current_word_index].Split('\n');
                        panel.panel_text.text = beforeChange + b[0];
                        words.Insert(current_word_index + 1, b[1]);
                        panel_start = true;
                        panel_count++;
                        current_word_index++;
                        break;
                    }
                    else if (tempText.isTextOverflowing && !words[current_word_index].Contains("\n"))
                    {
                        Debug.Log("Overflow at " + words[current_word_index]);
                        panel.panel_text.text = beforeChange;
                        GameManager.instance.space_breaks.Add(space_in_line);
                        current_space_index = 0;
                        //current_word_index -= 1;
                        panel_start = true;
                        panel_count++;
                        break;
                    }



                    if (i != words.Count - 1)
                    {
                        panel.panel_text.text += " ";
                    }

                    panel.panel_text = tempText;
                }
                if (current_word_index == 150)
                {
                    break;
                }
            }
        }
    }
Пример #26
0
        public void AdjustDiacriticPositions()
        {
            m_TextComponent = gameObject.GetComponent <TMP_Text>();
            m_TextComponent.ForceMeshUpdate();
            textInfo = m_TextComponent.textInfo;

            int characterCount = textInfo.characterCount;

            if (characterCount > 1)
            {
                int newYOffset   = 0;
                int charPosition = 1;

                if (ArabicAlphabetHelper.GetHexUnicodeFromChar(textInfo.characterInfo[0].character) == "0627" &&
                    ArabicAlphabetHelper.GetHexUnicodeFromChar(textInfo.characterInfo[1].character) == "064B")
                {
                    newYOffset = 10;
                }

                if (ArabicAlphabetHelper.GetHexUnicodeFromChar(textInfo.characterInfo[0].character) == "0623" &&
                    ArabicAlphabetHelper.GetHexUnicodeFromChar(textInfo.characterInfo[1].character) == "064E")
                {
                    newYOffset = 16;
                }

                if (ArabicAlphabetHelper.GetHexUnicodeFromChar(textInfo.characterInfo[0].character) == "0639" &&
                    ArabicAlphabetHelper.GetHexUnicodeFromChar(textInfo.characterInfo[1].character) == "0650")
                {
                    newYOffset = -25;
                }

                if (newYOffset != 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();

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

                    // Get the index of the first vertex used by this text element.
                    int vertexIndex = textInfo.characterInfo[charPosition].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.
                    float   dy     = (sourceVertices[vertexIndex + 2].y - sourceVertices[vertexIndex + 0].y);
                    Vector3 offset = new Vector3(0f, dy, 0f);

                    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;

                    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("DIACRITIC: diacritic pos fixed for " +
                    //                              ArabicAlphabetHelper.GetHexUnicodeFromChar(textInfo.characterInfo[1].character) + " by " + newYOffset);
                }


                //for (int i = 0; i < characterCount; i++) {
                //    Debug.Log("DIACRITIC: " + i
                //              //+ "index: " + textInfo.characterInfo[i].index
                //              + " char: " + textInfo.characterInfo[i].character.ToString()
                //              + " UNICODE: " + ArabicAlphabetHelper.GetHexUnicodeFromChar(textInfo.characterInfo[i].character)
                //    );
                //}
            }
        }
Пример #27
0
        /// <summary>
        ///     Method to curve text along a Unity animation curve.
        /// </summary>
        /// <param name="textComponent"></param>
        /// <returns></returns>
        private 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;
            var old_CurveScale = CurveScale;
            var 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.

                var textInfo       = m_TextComponent.textInfo;
                var characterCount = textInfo.characterCount;


                if (characterCount == 0)
                {
                    continue;
                }

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

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


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

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

                    // Get the index of the mesh used by this character.
                    var 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
                    var x0 = (offsetToMidBaseline.x - boundsMinX) /
                             (boundsMaxX - boundsMinX); // Character's position relative to the bounds of the mesh.
                    var x1 = x0 + 0.0001f;
                    var y0 = VertexCurve.Evaluate(x0) * CurveScale;
                    var y1 = VertexCurve.Evaluate(x1) * CurveScale;

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

                    var dot   = Mathf.Acos(Vector3.Dot(horizontal, tangent.normalized)) * 57.2957795f;
                    var cross = Vector3.Cross(horizontal, tangent);
                    var 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));
            }
        }
Пример #28
0
    public IEnumerator AnimateTextIn(List <DialogueCommand> commands, string processedMessage, AudioClip voice_sound, Action onFinish)
    {
        textAnimating = true;
        float secondsPerCharacter = 1f / 150f;
        float timeOfLastCharacter = 0;

        TextAnimInfo[] textAnimInfo = SeparateOutTextAnimInfo(commands);
        TMP_TextInfo   textInfo     = textBox.textInfo;

        for (int i = 0; i < textInfo.meshInfo.Length; i++) //Clear the mesh
        {
            TMP_MeshInfo meshInfer = textInfo.meshInfo[i];
            if (meshInfer.vertices != null)
            {
                for (int j = 0; j < meshInfer.vertices.Length; j++)
                {
                    meshInfer.vertices[j] = vecZero;
                }
            }
        }

        textBox.text = processedMessage;
        textBox.ForceMeshUpdate();

        TMP_MeshInfo[] cachedMeshInfo = textInfo.CopyMeshInfoVertexData();
        Color32[][]    originalColors = new Color32[textInfo.meshInfo.Length][];
        for (int i = 0; i < originalColors.Length; i++)
        {
            Color32[] theColors = textInfo.meshInfo[i].colors32;
            originalColors[i] = new Color32[theColors.Length];
            Array.Copy(theColors, originalColors[i], theColors.Length);
        }
        int charCount = textInfo.characterCount;

        float[] charAnimStartTimes = new float[charCount];
        for (int i = 0; i < charCount; i++)
        {
            charAnimStartTimes[i] = -1; //indicate the character as not yet started animating.
        }
        int visableCharacterIndex = 0;

        while (true)
        {
            if (stopAnimating)
            {
                for (int i = visableCharacterIndex; i < charCount; i++)
                {
                    charAnimStartTimes[i] = Time.unscaledTime;
                }
                visableCharacterIndex = charCount;
                FinishAnimating(onFinish);
            }
            if (ShouldShowNextCharacter(secondsPerCharacter, timeOfLastCharacter))
            {
                if (visableCharacterIndex <= charCount)
                {
                    ExecuteCommandsForCurrentIndex(commands, visableCharacterIndex, ref secondsPerCharacter, ref timeOfLastCharacter);
                    if (visableCharacterIndex < charCount && ShouldShowNextCharacter(secondsPerCharacter, timeOfLastCharacter))
                    {
                        charAnimStartTimes[visableCharacterIndex] = Time.unscaledTime;
                        PlayDialogueSound(voice_sound);
                        visableCharacterIndex++;
                        timeOfLastCharacter = Time.unscaledTime;
                        if (visableCharacterIndex == charCount)
                        {
                            FinishAnimating(onFinish);
                        }
                    }
                }
            }
            for (int j = 0; j < charCount; j++)
            {
                TMP_CharacterInfo charInfo = textInfo.characterInfo[j];
                if (charInfo.isVisible) //Invisible characters have a vertexIndex of 0 because they have no vertices and so they should be ignored to avoid messing up the first character in the string whic also has a vertexIndex of 0
                {
                    int       vertexIndex       = charInfo.vertexIndex;
                    int       materialIndex     = charInfo.materialReferenceIndex;
                    Color32[] destinationColors = textInfo.meshInfo[materialIndex].colors32;
                    Color32   theColor          = j < visableCharacterIndex ? originalColors[materialIndex][vertexIndex] : clear;
                    destinationColors[vertexIndex + 0] = theColor;
                    destinationColors[vertexIndex + 1] = theColor;
                    destinationColors[vertexIndex + 2] = theColor;
                    destinationColors[vertexIndex + 3] = theColor;

                    Vector3[] sourceVertices      = cachedMeshInfo[materialIndex].vertices;
                    Vector3[] destinationVertices = textInfo.meshInfo[materialIndex].vertices;
                    float     charSize            = 0;
                    float     charAnimStartTime   = charAnimStartTimes[j];
                    if (charAnimStartTime >= 0)
                    {
                        float timeSinceAnimStart = Time.unscaledTime - charAnimStartTime;
                        charSize = Mathf.Min(1, timeSinceAnimStart / CHAR_ANIM_TIME);
                    }

                    Vector3 animPosAdjustment = GetAnimPosAdjustment(textAnimInfo, j, textBox.fontSize, Time.unscaledTime);
                    Vector3 offset            = (sourceVertices[vertexIndex + 0] + sourceVertices[vertexIndex + 2]) / 2;
                    destinationVertices[vertexIndex + 0] = ((sourceVertices[vertexIndex + 0] - offset) * charSize) + offset + animPosAdjustment;
                    destinationVertices[vertexIndex + 1] = ((sourceVertices[vertexIndex + 1] - offset) * charSize) + offset + animPosAdjustment;
                    destinationVertices[vertexIndex + 2] = ((sourceVertices[vertexIndex + 2] - offset) * charSize) + offset + animPosAdjustment;
                    destinationVertices[vertexIndex + 3] = ((sourceVertices[vertexIndex + 3] - offset) * charSize) + offset + animPosAdjustment;
                }
            }
            textBox.UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32);
            for (int i = 0; i < textInfo.meshInfo.Length; i++)
            {
                TMP_MeshInfo theInfo = textInfo.meshInfo[i];
                theInfo.mesh.vertices = theInfo.vertices;
                textBox.UpdateGeometry(theInfo.mesh, i);
            }
            yield return(null);
        }
    }
Пример #29
0
    // Shaking example taken from the TextMeshPro demo.
    private IEnumerator ShakeTextAt(int startIndex, int endIndex)
    {
        // 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.
        Text.ForceMeshUpdate();

        TMP_TextInfo textInfo = Text.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 == 0)
            {
                yield return(new WaitForSeconds(0.25f));

                continue;
            }


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

            loopCount += 1;

            yield return(new WaitForSeconds(0.1f));
        }
    }
Пример #30
0
 private void StripCommandsFromTextAndCreateCommandList(string text)
 {
     SentenceUIObject.text = StripAllCommands(text);
     SentenceUIObject.ForceMeshUpdate();
     specialCommands = BuildSpecialCommandList(text);
 }