void Update() { text.ForceMeshUpdate(); TMP_TextInfo info = text.textInfo; float start = 3f; float end = 481f - start; float dist = end - start; foreach (TMP_CharacterInfo character in info.characterInfo) { if (!character.isVisible) { continue; } Vector3[] verts = info.meshInfo[character.materialReferenceIndex].vertices; float y = curve.Evaluate((verts[character.vertexIndex].x - start) / dist); for (int i = 0; i < 4; i++) { verts[character.vertexIndex + i] = verts[character.vertexIndex + i] + new Vector3(0, y * 100, 0); } } for (int i = 0; i < info.meshInfo.Length; i++) { TMP_MeshInfo meshInfo = info.meshInfo[i]; meshInfo.mesh.vertices = meshInfo.vertices; text.UpdateGeometry(meshInfo.mesh, i); } }
private void ResetVertices() { if (_cachedMeshInfo == null) { return; } TMP_TextInfo textInfo = _textComponent.textInfo; for (int i = 0; i < textInfo.characterCount; i++) { TMP_CharacterInfo charInfo = textInfo.characterInfo[i]; int materialIndex = charInfo.materialReferenceIndex; Vector3[] destinationVertices = textInfo.meshInfo[materialIndex].vertices; int vertexIndex = charInfo.vertexIndex; for (int j = 0; j < 4; j++) { Vector3 original = _cachedMeshInfo[materialIndex].vertices[vertexIndex + j]; destinationVertices[vertexIndex + j] = original; } } for (int i = 0; i < textInfo.meshInfo.Length; i++) { TMP_MeshInfo meshInfo = textInfo.meshInfo[i]; meshInfo.mesh.vertices = meshInfo.vertices; _textComponent.UpdateGeometry(meshInfo.mesh, i); } }
/// <summary> /// 頂点データのキャッシュ /// </summary> /// <returns>成功判定</returns> private bool UpdateCachedVertex() { // 頂点キャッシュの確保 if (this.baseVertices == null) { this.baseVertices = new Vector3[textInfo.materialCount][]; } if (this.baseColors == null) { this.baseColors = new Color32[textInfo.materialCount][]; } if (this.animatedVertices == null) { this.animatedVertices = new Vector3[textInfo.materialCount][]; } if (this.animatedColors == null) { this.animatedColors = new Color32[textInfo.materialCount][]; } // 頂点キャッシュの内容更新 for (int i = 0; i < textInfo.materialCount; i++) { TMP_MeshInfo meshInfo = textInfo.meshInfo[i]; if (meshInfo.vertices == null || meshInfo.colors32 == null) { return(false); } // 要素数に変更があった場合は配列再確保 if (this.animatedVertices[i] == null || this.animatedVertices[i].Length != meshInfo.vertices.Length) { this.animatedVertices[i] = new Vector3[meshInfo.vertices.Length]; } if (this.animatedColors[i] == null || this.animatedColors[i].Length != meshInfo.colors32.Length) { this.animatedColors[i] = new Color32[meshInfo.colors32.Length]; } // MeshInfo 内の配列がごっそり変わった場合は参照切り替え & コピー if (this.baseVertices[i] != meshInfo.vertices) { this.baseVertices[i] = meshInfo.vertices; System.Array.Copy(meshInfo.vertices, this.animatedVertices[i], meshInfo.vertices.Length); } if (this.baseColors[i] != meshInfo.colors32) { this.baseColors[i] = meshInfo.colors32; System.Array.Copy(meshInfo.colors32, this.animatedColors[i], meshInfo.colors32.Length); } } return(true); }
public void UpdateVerticies(TMP_MeshInfo meshInfo) { meshInfo.vertices[vertexIndex + 1] = baseVertices.topLeft; meshInfo.vertices[vertexIndex + 2] = baseVertices.topRight; meshInfo.vertices[vertexIndex + 0] = baseVertices.bottomLeft; meshInfo.vertices[vertexIndex + 3] = baseVertices.bottomRight; }
void ResizeWords(TMP_WordInfo wInfo) { for (int charIndex = wInfo.firstCharacterIndex; charIndex < wInfo.firstCharacterIndex + wInfo.characterCount; charIndex++) { // Get the index of the material / sub text object used by this character. int materialIndex = m_TextMeshPro.textInfo.characterInfo[charIndex].materialReferenceIndex; // Get the index of the first vertex of the selected character. int vertexIndex = m_TextMeshPro.textInfo.characterInfo[charIndex].vertexIndex; // Get a reference to the vertices array. Vector3[] vertices = m_TextMeshPro.textInfo.meshInfo[materialIndex].vertices; // Determine the center point of the character. Vector2 charMidBasline = (vertices[vertexIndex + 0] + vertices[vertexIndex + 2]) / 2; // Need to translate all 4 vertices of the character 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; // Translate the character to the middle baseline. vertices[vertexIndex + 0] = vertices[vertexIndex + 0] - offset; vertices[vertexIndex + 1] = vertices[vertexIndex + 1] - offset; vertices[vertexIndex + 2] = vertices[vertexIndex + 2] - offset; vertices[vertexIndex + 3] = vertices[vertexIndex + 3] - offset; float zoomFactor = 1.5f; // Setup the Matrix for the scale change. m_matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one * zoomFactor); // Apply Matrix operation on the given character. vertices[vertexIndex + 0] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 0]); vertices[vertexIndex + 1] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 1]); vertices[vertexIndex + 2] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 2]); vertices[vertexIndex + 3] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 3]); // Translate the character back to its original position. vertices[vertexIndex + 0] = vertices[vertexIndex + 0] + offset; vertices[vertexIndex + 1] = vertices[vertexIndex + 1] + offset; vertices[vertexIndex + 2] = vertices[vertexIndex + 2] + offset; vertices[vertexIndex + 3] = vertices[vertexIndex + 3] + offset; // Get a reference to the meshInfo of the selected character. TMP_MeshInfo meshInfo = m_TextMeshPro.textInfo.meshInfo[materialIndex]; // Get the index of the last character's vertex attributes. int lastVertexIndex = vertices.Length - 4; // Swap the current character's vertex attributes with those of the last element in the vertex attribute arrays. // We do this to make sure this character is rendered last and over other characters. meshInfo.SwapVertexData(vertexIndex, lastVertexIndex); } // Need to update the appropriate m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All); }
public Character(TMP_CharacterInfo characterInfo, TMP_MeshInfo meshInfo) { vertexIndex = characterInfo.vertexIndex; baseVertices = new MeshVertices( topLeft: meshInfo.vertices[vertexIndex + 1], topRight: meshInfo.vertices[vertexIndex + 2], bottomLeft: meshInfo.vertices[vertexIndex + 0], bottomRight: meshInfo.vertices[vertexIndex + 3] ); }
/// <summary> /// /// </summary> /// <param name="mesh"></param> /// <param name="newVertices"></param> /// <param name="meshInfo"></param> private void UpdateMesh(Mesh mesh, Vector3[] newVertices, TMP_MeshInfo meshInfo) { mesh.vertices = newVertices; mesh.uv = meshInfo.uvs0; mesh.uv2 = meshInfo.uvs2; mesh.colors32 = meshInfo.colors32; mesh.RecalculateBounds(); canvasRenderer.SetMesh(mesh); }
private IEnumerator AnimationCoroutine() { TMP_TextInfo textInfo = _textComponent.textInfo; while (true) { foreach (TMP_LinkInfo linkInfo in _links) { int firstIndex = linkInfo.linkTextfirstCharacterIndex; int lastIndex = linkInfo.linkTextLength + firstIndex; for (int i = firstIndex; i < lastIndex; i++) { TMP_CharacterInfo charInfo = textInfo.characterInfo[i]; if (!charInfo.isVisible) { continue; } float jitterX = Random.Range(0f, jitterRange) - jitterRange / 2; float jitterY = Random.Range(0f, jitterRange) - jitterRange / 2; int materialIndex = charInfo.materialReferenceIndex; Vector3[] destinationVertices = textInfo.meshInfo[materialIndex].vertices; int vertexIndex = charInfo.vertexIndex; for (int j = 0; j < 4; j++) { Vector3 original = _cachedMeshInfo[materialIndex].vertices[vertexIndex + j]; destinationVertices[vertexIndex + j] = original + new Vector3(jitterX, jitterY, 0); } } for (int i = 0; i < textInfo.meshInfo.Length; i++) { TMP_MeshInfo meshInfo = textInfo.meshInfo[i]; meshInfo.mesh.vertices = meshInfo.vertices; _textComponent.UpdateGeometry(meshInfo.mesh, i); } } yield return(new WaitForFixedUpdate()); } }
public void ShowEverythingWithoutAnimation() { StopAllCoroutines(); // TODO call all actions and emotions foreach (var command in m_Commands) { EvaluateTag(command); } text = m_ProcessedMessage; _nRevealedCharacters = m_ProcessedMessage.Length; TextAnimInfo[] textAnimInfo = SeparateOutTextAnimInfo(m_Commands); for (int i = 0; i < textInfo.characterCount; i++) { TMP_CharacterInfo charInfo = textInfo.characterInfo[i]; int vertexIndex = charInfo.vertexIndex; int materialIndex = charInfo.materialReferenceIndex; Color32[] destinationColors = textInfo.meshInfo[materialIndex].colors32; Color32 theColor = m_OriginalColors[materialIndex][vertexIndex]; theColor.a = 255; ShowCharacterColor(theColor, vertexIndex, ref destinationColors); ShowCharacterSize(m_CachedMeshInfo, textAnimInfo, materialIndex, i, vertexIndex, 1); } UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32); for (int i = 0; i < textInfo.meshInfo.Length; i++) { TMP_MeshInfo theInfo = textInfo.meshInfo[i]; theInfo.mesh.vertices = theInfo.vertices; UpdateGeometry(theInfo.mesh, i); } _isRevealing = false; allRevealed.Invoke(); }
private void UpdateWave() { // Value restrictions if (_loopDuration <= 0) { _loopDuration = 1; } _waveDuration = Mathf.Clamp(_waveDuration, 0, _loopDuration); // Modify vertics (position of text) TMP_TextInfo tInfo = _text.textInfo; Dictionary <int, Vector3[]> newVertices = new Dictionary <int, Vector3[]>(); // key = materialReferenceIndex for (int i = 0; i < tInfo.characterCount; i++) { int characterIndex = i; TMP_CharacterInfo cInfo = tInfo.characterInfo[i]; // Clone original vector data int meshInfoIndex = cInfo.materialReferenceIndex; if (!newVertices.ContainsKey(meshInfoIndex)) { Vector3[] oriVertices = tInfo.meshInfo[cInfo.materialReferenceIndex].vertices.Clone() as Vector3[]; newVertices.Add(meshInfoIndex, oriVertices); } // Skip handling if not visible if (!cInfo.isVisible) { continue; } // Calculation of wave value float delay = _startDelay + _nextCharacterInterval * characterIndex; float validTime = _passedTime - delay; float wave = 0; if (validTime > 0) { if (_loopDuration == 0) { _loopDuration = 1; } validTime %= _loopDuration; if (validTime <= _waveDuration) { float degree = (validTime / _waveDuration) * Mathf.PI; wave = _waveHeight * Mathf.Sin(degree); } } // Over write vertor value Vector3[] vertices = newVertices[meshInfoIndex]; for (int j = 0; j < 4; j++) { Vector3 oriVertice = vertices[cInfo.vertexIndex + j]; vertices[cInfo.vertexIndex + j] = oriVertice + new Vector3(0, wave, 0); } } // Update mesh for (int i = 0; i < tInfo.meshInfo.Length; i++) { if (!newVertices.ContainsKey(i)) { continue; } TMP_MeshInfo mInfo = tInfo.meshInfo[i]; mInfo.mesh.vertices = newVertices[i]; _text.UpdateGeometry(mInfo.mesh, i); } }
/// <summary> /// /// </summary> /// <param name="meshInfoIndex"></param> private void UpdateVertexPositionsWarp(int meshInfoIndex) { TMP_MeshInfo meshInfo = textInfo.meshInfo[meshInfoIndex]; Mesh mesh = meshInfo.mesh; bool isValidMeshInfo = IsValidMeshInfo(meshInfo); if (!isValidMeshInfo) { return; } ForceMeshUpdate(); // Generate the mesh and populate the textInfo with data we can use and manipulate. int characterCount = textInfo.characterCount; if (characterCount == 0) { return; } float finalCurveScale = scaleMultiplierPerCharacter * characterCount; Vector3[] vertices = meshInfo.vertices; float boundsMinX = bounds.min.x; float boundsMaxX = bounds.max.x; for (int i = 0; i < characterCount; i++) { if (!textInfo.characterInfo[i].isVisible) { continue; } int vertexIndex = textInfo.characterInfo[i].vertexIndex; // Compute the baseline mid point for each character Vector3 offsetToMidBaseline = new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2, textInfo.characterInfo[i].baseLine); // 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) * finalCurveScale; float y1 = vertexCurve.Evaluate(x1) * finalCurveScale; Vector3 horizontal = new Vector3(1, 0, 0); Vector3 tangent = new Vector3(x1 * (boundsMaxX - boundsMinX) + boundsMinX, y1) - new Vector3(offsetToMidBaseline.x, y0); float dot = Mathf.Acos(Vector3.Dot(horizontal, tangent.normalized)) * ONE_RAD_IN_DEGREES; Vector3 cross = Vector3.Cross(horizontal, tangent); float angle = cross.z > 0 ? dot : 360 - dot; Matrix4x4 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; } UpdateMesh(mesh, vertices, meshInfo); }
/// <summary> /// /// </summary> /// <param name="meshInfo"></param> /// <returns></returns> private bool IsValidMeshInfo(TMP_MeshInfo meshInfo) { return(mesh != null && meshInfo.vertices != null && meshInfo.vertexCount > 0 && meshInfo.uvs0 != null && meshInfo.uvs2 != null && meshInfo.colors32 != null); }
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); } }
void LateUpdate() { if (isHoveringObject) { // Check if Mouse Intersects any of the characters. If so, assign a random color. #region Handle Character Selection int charIndex = TMP_TextUtilities.FindIntersectingCharacter(m_TextMeshPro, Input.mousePosition, m_Camera, true); // Undo Swap and Vertex Attribute changes. if (charIndex == -1 || charIndex != m_lastIndex) { RestoreCachedVertexAttributes(m_lastIndex); m_lastIndex = -1; } if (charIndex != -1 && charIndex != m_lastIndex && (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))) { m_lastIndex = charIndex; // Get the index of the material / sub text object used by this character. int materialIndex = m_TextMeshPro.textInfo.characterInfo[charIndex].materialReferenceIndex; // Get the index of the first vertex of the selected character. int vertexIndex = m_TextMeshPro.textInfo.characterInfo[charIndex].vertexIndex; // Get a reference to the vertices array. Vector3[] vertices = m_TextMeshPro.textInfo.meshInfo[materialIndex].vertices; // Determine the center point of the character. Vector2 charMidBasline = (vertices[vertexIndex + 0] + vertices[vertexIndex + 2]) / 2; // Need to translate all 4 vertices of the character 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; // Translate the character to the middle baseline. vertices[vertexIndex + 0] = vertices[vertexIndex + 0] - offset; vertices[vertexIndex + 1] = vertices[vertexIndex + 1] - offset; vertices[vertexIndex + 2] = vertices[vertexIndex + 2] - offset; vertices[vertexIndex + 3] = vertices[vertexIndex + 3] - offset; float zoomFactor = 1.5f; // Setup the Matrix for the scale change. m_matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one * zoomFactor); // Apply Matrix operation on the given character. vertices[vertexIndex + 0] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 0]); vertices[vertexIndex + 1] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 1]); vertices[vertexIndex + 2] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 2]); vertices[vertexIndex + 3] = m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 3]); // Translate the character back to its original position. vertices[vertexIndex + 0] = vertices[vertexIndex + 0] + offset; vertices[vertexIndex + 1] = vertices[vertexIndex + 1] + offset; vertices[vertexIndex + 2] = vertices[vertexIndex + 2] + offset; vertices[vertexIndex + 3] = vertices[vertexIndex + 3] + offset; // Change Vertex Colors of the highlighted character Color32 c = new Color32(255, 255, 192, 255); // Get a reference to the vertex color Color32[] vertexColors = m_TextMeshPro.textInfo.meshInfo[materialIndex].colors32; vertexColors[vertexIndex + 0] = c; vertexColors[vertexIndex + 1] = c; vertexColors[vertexIndex + 2] = c; vertexColors[vertexIndex + 3] = c; // Get a reference to the meshInfo of the selected character. TMP_MeshInfo meshInfo = m_TextMeshPro.textInfo.meshInfo[materialIndex]; // Get the index of the last character's vertex attributes. int lastVertexIndex = vertices.Length - 4; // Swap the current character's vertex attributes with those of the last element in the vertex attribute arrays. // We do this to make sure this character is rendered last and over other characters. meshInfo.SwapVertexData(vertexIndex, lastVertexIndex); // Need to update the appropriate m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All); } #endregion #region Word Selection Handling //Check if Mouse intersects any words and if so assign a random color to that word. int wordIndex = TMP_TextUtilities.FindIntersectingWord(m_TextMeshPro, Input.mousePosition, m_Camera); // Clear previous word selection. if (m_TextPopup_RectTransform != null && m_selectedWord != -1 && (wordIndex == -1 || wordIndex != m_selectedWord)) { TMP_WordInfo wInfo = m_TextMeshPro.textInfo.wordInfo[m_selectedWord]; // Iterate through each of the characters of the word. for (int i = 0; i < wInfo.characterCount; i++) { int characterIndex = wInfo.firstCharacterIndex + i; // Get the index of the material / sub text object used by this character. int meshIndex = m_TextMeshPro.textInfo.characterInfo[characterIndex].materialReferenceIndex; // Get the index of the first vertex of this character. int vertexIndex = m_TextMeshPro.textInfo.characterInfo[characterIndex].vertexIndex; // Get a reference to the vertex color Color32[] vertexColors = m_TextMeshPro.textInfo.meshInfo[meshIndex].colors32; Color32 c = vertexColors[vertexIndex + 0].Tint(1.33333f); vertexColors[vertexIndex + 0] = c; vertexColors[vertexIndex + 1] = c; vertexColors[vertexIndex + 2] = c; vertexColors[vertexIndex + 3] = c; } // Update Geometry m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All); m_selectedWord = -1; } // Word Selection Handling if (wordIndex != -1 && wordIndex != m_selectedWord && !(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))) { m_selectedWord = wordIndex; TMP_WordInfo wInfo = m_TextMeshPro.textInfo.wordInfo[wordIndex]; // Iterate through each of the characters of the word. for (int i = 0; i < wInfo.characterCount; i++) { int characterIndex = wInfo.firstCharacterIndex + i; // Get the index of the material / sub text object used by this character. int meshIndex = m_TextMeshPro.textInfo.characterInfo[characterIndex].materialReferenceIndex; int vertexIndex = m_TextMeshPro.textInfo.characterInfo[characterIndex].vertexIndex; // Get a reference to the vertex color Color32[] vertexColors = m_TextMeshPro.textInfo.meshInfo[meshIndex].colors32; Color32 c = vertexColors[vertexIndex + 0].Tint(0.75f); vertexColors[vertexIndex + 0] = c; vertexColors[vertexIndex + 1] = c; vertexColors[vertexIndex + 2] = c; vertexColors[vertexIndex + 3] = c; } // Update Geometry m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All); } #endregion #region Example of Link Handling // Check if mouse intersects with any links. int linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextMeshPro, Input.mousePosition, m_Camera); // Clear previous link selection if one existed. if ((linkIndex == -1 && m_selectedLink != -1) || linkIndex != m_selectedLink) { m_TextPopup_RectTransform.gameObject.SetActive(false); m_selectedLink = -1; } // Handle new Link selection. if (linkIndex != -1 && linkIndex != m_selectedLink) { m_selectedLink = linkIndex; TMP_LinkInfo linkInfo = m_TextMeshPro.textInfo.linkInfo[linkIndex]; // Debug.Log("Link ID: \"" + linkInfo.GetLinkID() + "\" Link Text: \"" + linkInfo.GetLinkText() + "\""); // Example of how to retrieve the Link ID and Link Text. Vector3 worldPointInRectangle; RectTransformUtility.ScreenPointToWorldPointInRectangle(m_TextMeshPro.rectTransform, Input.mousePosition, m_Camera, out worldPointInRectangle); switch (linkInfo.GetLinkID()) { case "id_01": // 100041637: // id_01 m_TextPopup_RectTransform.position = worldPointInRectangle; m_TextPopup_RectTransform.gameObject.SetActive(true); m_TextPopup_TMPComponent.text = k_LinkText + " ID 01"; break; case "id_02": // 100041638: // id_02 m_TextPopup_RectTransform.position = worldPointInRectangle; m_TextPopup_RectTransform.gameObject.SetActive(true); m_TextPopup_TMPComponent.text = k_LinkText + " ID 02"; break; } } #endregion } else { // Restore any character that may have been modified if (m_lastIndex != -1) { RestoreCachedVertexAttributes(m_lastIndex); m_lastIndex = -1; } } }
public IEnumerator RevealNextParagraph(List <DialogueCommand> commands) { _isRevealing = true; // float secondsPerCharacter = 1f / 10f; float secondsPerCharacter = charsPerSecond; float timeOfLastCharacter = 0; TextAnimInfo[] textAnimInfo = SeparateOutTextAnimInfo(commands); foreach (TMP_MeshInfo meshInfo in textInfo.meshInfo) { if (meshInfo.vertices != null) { for (int j = 0; j < meshInfo.vertices.Length; j++) { meshInfo.vertices[j] = Vector3.zero; } } } text = m_ProcessedMessage; ForceMeshUpdate(); m_CachedMeshInfo = textInfo.CopyMeshInfoVertexData(); m_OriginalColors = new Color32[textInfo.meshInfo.Length][]; for (int i = 0; i < m_OriginalColors.Length; i++) { Color32[] theColors = textInfo.meshInfo[i].colors32; m_OriginalColors[i] = new Color32[theColors.Length]; Array.Copy(theColors, m_OriginalColors[i], theColors.Length); } // The amount of characters in the processed message. 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 visibleCharacterIndex = 0; while (true) { // while (_nRevealedCharacters < _originalString.Length && _originalString[_nRevealedCharacters] == '\n') // _nRevealedCharacters += 1; if (m_StopAnimating) { for (int i = visibleCharacterIndex; i < charCount; i++) { charAnimStartTimes[i] = Time.unscaledTime; } visibleCharacterIndex = charCount; FinishAnimating(); } if (ShouldShowNextCharacter(secondsPerCharacter, timeOfLastCharacter)) { if (_nRevealedCharacters <= charCount) { ExecuteCommandsForCurrentIndex(commands, visibleCharacterIndex, ref secondsPerCharacter, ref timeOfLastCharacter); if (visibleCharacterIndex < charCount && ShouldShowNextCharacter(secondsPerCharacter, timeOfLastCharacter)) { charAnimStartTimes[visibleCharacterIndex] = Time.unscaledTime; onCharReveal.Invoke(m_ProcessedMessage[visibleCharacterIndex]); visibleCharacterIndex++; timeOfLastCharacter = Time.unscaledTime; if (visibleCharacterIndex == charCount) { FinishAnimating(); } } } } 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 < visibleCharacterIndex ? m_OriginalColors[materialIndex][vertexIndex] : Clear; float charAnimStartTime = charAnimStartTimes[j]; float charSize = 0; if (charAnimStartTime >= 0) { float timeSinceAnimStart = Time.unscaledTime - charAnimStartTime; theColor.a = (byte)Mathf.Min(255, 255 * CHAR_FADE_SPEED * timeSinceAnimStart); charSize = Mathf.Min(1, timeSinceAnimStart / CHAR_ANIM_TIME); } ShowCharacterColor(theColor, vertexIndex, ref destinationColors); ShowCharacterSize(m_CachedMeshInfo, textAnimInfo, materialIndex, j, vertexIndex, charSize); } } UpdateVertexData(TMP_VertexDataUpdateFlags.Colors32); for (int i = 0; i < textInfo.meshInfo.Length; i++) { TMP_MeshInfo theInfo = textInfo.meshInfo[i]; theInfo.mesh.vertices = theInfo.vertices; UpdateGeometry(theInfo.mesh, i); } yield return(null); } }
private void LateUpdate() { if (this.isHoveringObject) { int num = TMP_TextUtilities.FindIntersectingCharacter(this.m_TextMeshPro, Input.mousePosition, this.m_Camera, true); if (num == -1 || num != this.m_lastIndex) { this.RestoreCachedVertexAttributes(this.m_lastIndex); this.m_lastIndex = -1; } if (num != -1 && num != this.m_lastIndex && (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))) { this.m_lastIndex = num; int materialReferenceIndex = this.m_TextMeshPro.textInfo.characterInfo[num].materialReferenceIndex; int vertexIndex = this.m_TextMeshPro.textInfo.characterInfo[num].vertexIndex; Vector3[] vertices = this.m_TextMeshPro.textInfo.meshInfo[materialReferenceIndex].vertices; Vector2 v = (vertices[vertexIndex] + vertices[vertexIndex + 2]) / 2f; Vector3 b = v; vertices[vertexIndex] -= b; vertices[vertexIndex + 1] = vertices[vertexIndex + 1] - b; vertices[vertexIndex + 2] = vertices[vertexIndex + 2] - b; vertices[vertexIndex + 3] = vertices[vertexIndex + 3] - b; float d = 1.5f; this.m_matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one * d); vertices[vertexIndex] = this.m_matrix.MultiplyPoint3x4(vertices[vertexIndex]); vertices[vertexIndex + 1] = this.m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 1]); vertices[vertexIndex + 2] = this.m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 2]); vertices[vertexIndex + 3] = this.m_matrix.MultiplyPoint3x4(vertices[vertexIndex + 3]); vertices[vertexIndex] += b; vertices[vertexIndex + 1] = vertices[vertexIndex + 1] + b; vertices[vertexIndex + 2] = vertices[vertexIndex + 2] + b; vertices[vertexIndex + 3] = vertices[vertexIndex + 3] + b; Color32 color = new Color32(byte.MaxValue, byte.MaxValue, 192, byte.MaxValue); Color32[] colors = this.m_TextMeshPro.textInfo.meshInfo[materialReferenceIndex].colors32; colors[vertexIndex] = color; colors[vertexIndex + 1] = color; colors[vertexIndex + 2] = color; colors[vertexIndex + 3] = color; TMP_MeshInfo tmp_MeshInfo = this.m_TextMeshPro.textInfo.meshInfo[materialReferenceIndex]; int dst = vertices.Length - 4; tmp_MeshInfo.SwapVertexData(vertexIndex, dst); this.m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All); } int num2 = TMP_TextUtilities.FindIntersectingWord(this.m_TextMeshPro, Input.mousePosition, this.m_Camera); if (this.m_TextPopup_RectTransform != null && this.m_selectedWord != -1 && (num2 == -1 || num2 != this.m_selectedWord)) { TMP_WordInfo tmp_WordInfo = this.m_TextMeshPro.textInfo.wordInfo[this.m_selectedWord]; for (int i = 0; i < tmp_WordInfo.characterCount; i++) { int num3 = tmp_WordInfo.firstCharacterIndex + i; int materialReferenceIndex2 = this.m_TextMeshPro.textInfo.characterInfo[num3].materialReferenceIndex; int vertexIndex2 = this.m_TextMeshPro.textInfo.characterInfo[num3].vertexIndex; Color32[] colors2 = this.m_TextMeshPro.textInfo.meshInfo[materialReferenceIndex2].colors32; Color32 color2 = colors2[vertexIndex2].Tint(1.33333f); colors2[vertexIndex2] = color2; colors2[vertexIndex2 + 1] = color2; colors2[vertexIndex2 + 2] = color2; colors2[vertexIndex2 + 3] = color2; } this.m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All); this.m_selectedWord = -1; } if (num2 != -1 && num2 != this.m_selectedWord && !Input.GetKey(KeyCode.LeftShift) && !Input.GetKey(KeyCode.RightShift)) { this.m_selectedWord = num2; TMP_WordInfo tmp_WordInfo2 = this.m_TextMeshPro.textInfo.wordInfo[num2]; for (int j = 0; j < tmp_WordInfo2.characterCount; j++) { int num4 = tmp_WordInfo2.firstCharacterIndex + j; int materialReferenceIndex3 = this.m_TextMeshPro.textInfo.characterInfo[num4].materialReferenceIndex; int vertexIndex3 = this.m_TextMeshPro.textInfo.characterInfo[num4].vertexIndex; Color32[] colors3 = this.m_TextMeshPro.textInfo.meshInfo[materialReferenceIndex3].colors32; Color32 color3 = colors3[vertexIndex3].Tint(0.75f); colors3[vertexIndex3] = color3; colors3[vertexIndex3 + 1] = color3; colors3[vertexIndex3 + 2] = color3; colors3[vertexIndex3 + 3] = color3; } this.m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All); } int num5 = TMP_TextUtilities.FindIntersectingLink(this.m_TextMeshPro, Input.mousePosition, this.m_Camera); if ((num5 == -1 && this.m_selectedLink != -1) || num5 != this.m_selectedLink) { this.m_TextPopup_RectTransform.gameObject.SetActive(false); this.m_selectedLink = -1; } if (num5 != -1 && num5 != this.m_selectedLink) { this.m_selectedLink = num5; TMP_LinkInfo tmp_LinkInfo = this.m_TextMeshPro.textInfo.linkInfo[num5]; Vector3 zero = Vector3.zero; RectTransformUtility.ScreenPointToWorldPointInRectangle(this.m_TextMeshPro.rectTransform, Input.mousePosition, this.m_Camera, out zero); string linkID = tmp_LinkInfo.GetLinkID(); if (linkID != null) { if (!(linkID == "id_01")) { if (linkID == "id_02") { this.m_TextPopup_RectTransform.position = zero; this.m_TextPopup_RectTransform.gameObject.SetActive(true); this.m_TextPopup_TMPComponent.text = "You have selected link <#ffff00> ID 02"; } } else { this.m_TextPopup_RectTransform.position = zero; this.m_TextPopup_RectTransform.gameObject.SetActive(true); this.m_TextPopup_TMPComponent.text = "You have selected link <#ffff00> ID 01"; } } } } else if (this.m_lastIndex != -1) { this.RestoreCachedVertexAttributes(this.m_lastIndex); this.m_lastIndex = -1; } }
private void UpdateColor() { // Update gradient info Gradient gradient = new Gradient(); GradientColorKey[] colorKey = new GradientColorKey[2]; colorKey[0].color = _colorHead; colorKey[0].time = 0.0f; colorKey[1].color = _colorTail; colorKey[1].time = 1.0f; GradientAlphaKey[] alphaKey = new GradientAlphaKey[2]; alphaKey[0].alpha = _colorHead.a; alphaKey[0].time = 0.0f; alphaKey[1].alpha = _colorTail.a; alphaKey[1].time = 1.0f; gradient.SetKeys(colorKey, alphaKey); // Modify colors TMP_TextInfo tInfo = _text.textInfo; Dictionary <int, Color[]> newColors = new Dictionary <int, Color[]>(); // key = materialReferenceIndex int characterCount = tInfo.characterCount; for (int i = 0; i < characterCount; i++) { TMP_CharacterInfo cInfo = tInfo.characterInfo[i]; // Clone original color data int meshInfoIndex = cInfo.materialReferenceIndex; if (!newColors.ContainsKey(meshInfoIndex)) { Color32[] oriColors32 = tInfo.meshInfo[cInfo.materialReferenceIndex].colors32.Clone() as Color32[]; Color[] oriColors = new Color[oriColors32.Length]; for (int j = 0; j < oriColors32.Length; j++) { oriColors[j] = oriColors32[j]; } newColors.Add(meshInfoIndex, oriColors); } // Skip handling if not visible if (!cInfo.isVisible) { continue; } // Calculation of color value float time = 0 + (1.0f / characterCount) * i; if (characterCount > 1) { time = 0 + (1.0f / (characterCount - 1)) * i; } Color c = gradient.Evaluate(time); // Over write color value Color[] colors = newColors[meshInfoIndex]; for (int j = 0; j < 4; j++) { colors[cInfo.vertexIndex + j] = c; } } // Update mesh for (int i = 0; i < tInfo.meshInfo.Length; i++) { if (!newColors.ContainsKey(i)) { continue; } TMP_MeshInfo mInfo = tInfo.meshInfo[i]; mInfo.mesh.colors = newColors[i]; _text.UpdateGeometry(mInfo.mesh, i); } }