Vector Type Conversion Fix

Created on: January 24, 2025

Answered using O1 by Chat01

Question

fix this Assets\TextMesh Pro\Examples & Extras\Scripts\VertexZoom.cs(118,49): error CS0029: Cannot implicitly convert type 'UnityEngine.Vector4[]' to 'UnityEngine.Vector2[]' and Assets\TextMesh Pro\Examples & Extras\Scripts\VertexZoom.cs(143,52): error CS0029: Cannot implicitly convert type 'UnityEngine.Vector4[]' to 'UnityEngine.Vector2[]'

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace TMPro.Examples
{
public class VertexZoom : MonoBehaviour
{
public float AngleMultiplier = 1.0f;
public float SpeedMultiplier = 1.0f;
public float CurveScale = 1.0f;

text
private TMP_Text m_TextComponent; private bool hasTextChanged; void Awake() { m_TextComponent = GetComponent<TMP_Text>(); } void OnEnable() { // Subscribe to text changed event. TMPro_EventManager.TEXT_CHANGED_EVENT.Add(ON_TEXT_CHANGED); } void OnDisable() { // Unsubscribe from text changed event. TMPro_EventManager.TEXT_CHANGED_EVENT.Remove(ON_TEXT_CHANGED); } void Start() { StartCoroutine(AnimateVertexColors()); } void ON_TEXT_CHANGED(Object obj) { if (obj == m_TextComponent) hasTextChanged = true; } /// <summary> /// Animates the vertex colors of the TMP Text object. /// </summary> IEnumerator AnimateVertexColors() { m_TextComponent.ForceMeshUpdate(); TMP_TextInfo textInfo = m_TextComponent.textInfo; TMP_MeshInfo[] cachedMeshInfoVertexData = textInfo.CopyMeshInfoVertexData(); List<float> modifiedCharScale = new List<float>(); List<int> scaleSortingOrder = new List<int>(); hasTextChanged = true; while (true) { if (hasTextChanged) { cachedMeshInfoVertexData = textInfo.CopyMeshInfoVertexData(); hasTextChanged = false; } int characterCount = textInfo.characterCount; if (characterCount == 0) { yield return new WaitForSeconds(0.25f); continue; } modifiedCharScale.Clear(); scaleSortingOrder.Clear(); for (int i = 0; i < characterCount; i++) { TMP_CharacterInfo charInfo = textInfo.characterInfo[i]; if (!charInfo.isVisible) continue; int materialIndex = charInfo.materialReferenceIndex; int vertexIndex = charInfo.vertexIndex; Vector3[] sourceVertices = cachedMeshInfoVertexData[materialIndex].vertices; Vector3[] destinationVertices = textInfo.meshInfo[materialIndex].vertices; Vector2 charMidBaseline = (sourceVertices[vertexIndex + 0] + sourceVertices[vertexIndex + 2]) / 2; Vector3 offset = charMidBaseline; // Apply transformations 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 randomScale = Random.Range(1f, 1.5f); modifiedCharScale.Add(randomScale); scaleSortingOrder.Add(modifiedCharScale.Count - 1); Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero, 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 UVs Vector4[] sourceUVs0 = cachedMeshInfoVertexData[materialIndex].uvs0; Vector2[] destinationUVs0 = textInfo.meshInfo[materialIndex].uvs0; destinationUVs0[vertexIndex + 0] = new Vector2(sourceUVs0[vertexIndex + 0].x, sourceUVs0[vertexIndex + 0].y); destinationUVs0[vertexIndex + 1] = new Vector2(sourceUVs0[vertexIndex + 1].x, sourceUVs0[vertexIndex + 1].y); destinationUVs0[vertexIndex + 2] = new Vector2(sourceUVs0[vertexIndex + 2].x, sourceUVs0[vertexIndex + 2].y); destinationUVs0[vertexIndex + 3] = new Vector2(sourceUVs0[vertexIndex + 3].x, sourceUVs0[vertexIndex + 3].y); // Restore 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 the meshes for (int i = 0; i < textInfo.meshInfo.Length; i++) { scaleSortingOrder.Sort((a, b) => modifiedCharScale[a].CompareTo(modifiedCharScale[b])); textInfo.meshInfo[i].SortGeometry(scaleSortingOrder); 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); } } }

}

Thought

Addressing type mismatch

I’m digging into an error where Vector4[] in the source conflicts with Vector2[] in the destination, possibly due to different TMP versions. Converting each Vector4 to Vector2 or adjusting types could resolve this.

Assessing library updates

I'm examining the impact of library updates, which could affect compatibility. Migrating the code to align with the latest library version seems crucial, especially with potential changes in property types.

Aligning array types

I’m examining the importance of matching the array types of uvs0 in the code. Adjusting these to Vector2[] or Vector4[] ensures compatibility with the latest TMP version.

Aligning property types

I’m working on tweaking mesh.uv to sync with uvs0 as Vector2[], ensuring compatibility with the latest TMP version. This adjustment aims to prevent compilation errors.

Ensuring smooth compatibility

I’m adjusting the type of uvs0 to Vector2[] and suggesting direct assignment to avoid compilation issues. This method ensures both arrays match and your code functions properly.

Ensuring type alignment

I’m focusing on ensuring both arrays are Vector2[] to prevent type mismatch. This involves adjusting line 118 to match sourceUVs0 and digitizing assignments for smooth code execution.

Ensuring type compatibility

I’m working on matching uvs0 types to prevent mismatches, especially between Vector4[] and Vector2[]. Adjusting function calls and type assignments is crucial for smooth code execution.

Streamlining functionality

I’m unifying uvs0 to Vector2[], enhancing consistency and avoiding type mismatches. This adjustment simplifies assignments and ensures compatibility with mesh.uv, leading to smoother code execution.

Aligning type declarations

Switching Vector4[] to Vector2[] ensures consistent uvs0 usage, especially for assignments to mesh.uv, aligning with vector handling. This change streamlines the code and boosts clarity.

Aligning array types

Switching both uvs0 declarations to Vector2[] simplifies assigning destinationUVs0 and textInfo.meshInfo[materialIndex].uvs0, ensuring smooth execution and compatibility.

Thought about Vector4 to Vector2 conversion for 53 seconds

Answer

These errors occur because in newer versions of TextMesh Pro, the uvs0 array is typed as Vector2[], whereas in older versions it was sometimes Vector4[]. In your code, you are mixing Vector4[] and Vector2[], causing the compiler error:

Cannot implicitly convert type 'UnityEngine.Vector4[]' to 'UnityEngine.Vector2[]'

Quick Fix

  1. Change the sourceUVs0 type from Vector4[] to Vector2[] so that it matches the destination’s type.
  2. Use direct Vector2 assignment (rather than creating a new Vector2 if not necessary).

In other words, near line 118, replace:

csharp
Vector4[] sourceUVs0 = cachedMeshInfoVertexData[materialIndex].uvs0; Vector2[] destinationUVs0 = textInfo.meshInfo[materialIndex].uvs0;

with:

csharp
Vector2[] sourceUVs0 = cachedMeshInfoVertexData[materialIndex].uvs0; Vector2[] destinationUVs0 = textInfo.meshInfo[materialIndex].uvs0;

Then, to restore the UVs, you can simply do:

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

This way, both source and destination are Vector2[], matching what mesh.uv expects later in the code, and the compiler error goes away.


Explanation

  • Why the error? Unity’s Mesh.uv property is a Vector2[]. If textInfo.meshInfo[...].uvs0 is returning a Vector2[], but you store it or assign it to a Vector4[], you get an implicit conversion error.
  • What changed? In some older TMP example scripts, uvs0 was treated as Vector4[], but now uvs0 is almost always a Vector2[]—hence the mismatch.
  • What if you truly need Vector4[]? Then you would need to convert those vectors manually (e.g., taking only the x and y components), but typically simply matching to Vector2[] throughout is what you want for standard UVs.

By updating the type to Vector2[] everywhere uvs0 is used, your script will compile and run correctly under modern TextMesh Pro versions.

Share this Q&A