Author Topic: Text along a curve  (Read 63565 times)

Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5687
Re: Text along a curve
« Reply #45 on: November 10, 2015, 03:33:59 PM »
Make sure you get the revised version of the script located in this thread http://digitalnativestudios.com/forum/index.php?topic=712.msg5463#msg5463

Let me know if some of those functions works for you. This would be a better basis to start from.

In terms of the ForceMeshUpdate() here is perhaps a better explanation of the flow of this process.

(1) TextMesh Pro generate the text normally but we set the render flag to not render since we know we will modify it.
(2) We take the data from meshInfo and modify it and push it back.

We don't want to force TextMesh Pro to regenerate the text since that would essentially reset the whole thing.

P.S. I'll be driving back home tonight (18 hours of driving) I'll have full access to my dev environment and be able to provide much better assistance once there. I feel naked without Visual Studio. The Macbook Pro is nice but Monodevelop is simply not cutting it. Maybe Visual Studio Code once fully supported by Unity will be a nice option on the Mac.
« Last Edit: November 10, 2015, 03:37:49 PM by Stephan B. »

doktor3d

  • Beta User
  • Jr. Member
  • *
  • Posts: 54
Re: Text along a curve
« Reply #46 on: November 17, 2015, 05:56:01 AM »
It seems that the perspective filter code in the shader is causing issues with curved text that is orthogonal to a world space canvas. The result (if perspective filter is kept at default) is very blurry text when the text mesh verts are offset so the glyph quad is orthogonal to the canvas plane. My workaround is to set perspective filter to 0 in the Debug panel in the inspector. The 'proper' fix would presumably to calculate the filtering on a per-character mesh normal rather than overall TMP transform.
« Last Edit: November 18, 2015, 04:25:12 AM by doktor3d »

typeinwonderland

  • Newbie
  • *
  • Posts: 2
Re: Text along a curve
« Reply #47 on: January 01, 2016, 12:14:10 AM »
I've manipulated the Warp function to curve in Z axis, but couldn't figure out how to rotate each letter's angle based on the curve like this:


Can you please help?



Code: [Select]
IEnumerator AnimateVertexPositionsWarp(TextMeshPro textComponent)
{
VertexCurve.preWrapMode = WrapMode.Clamp;
VertexCurve.postWrapMode = WrapMode.Clamp;

Vector3[] vertexPositions;
Matrix4x4 matrix;

//int loopCount = 0;
int direction=1;
textComponent.havePropertiesChanged = true;
textComponent.ForceMeshUpdate();

float old_CurveScale = CurveScale;
AnimationCurve old_curve = CopyAnimationCurve(VertexCurve);

while (true)
{
if (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);
//Debug.Log("Updating object!");

textComponent.renderMode = TextRenderFlags.DontRender; // Instructing TextMesh Pro not to upload the mesh as we will be modifying it.
textComponent.ForceMeshUpdate(); // Generate the mesh and populate the textInfo with data we can use and manipulate.



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

//Debug.Log(characterCount);

if (characterCount == 0) continue;

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

float boundsMinX = textComponent.bounds.min.x;
float boundsMaxX = textComponent.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((vertexPositions[vertexIndex + 0].x + vertexPositions[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.
vertexPositions[vertexIndex + 0] += -offsetToMidBaseline;
vertexPositions[vertexIndex + 1] += -offsetToMidBaseline;
vertexPositions[vertexIndex + 2] += -offsetToMidBaseline;
vertexPositions[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 z0 = VertexCurve.Evaluate(x0) * CurveScale;
float z1 = 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, z1) - new Vector3(offsetToMidBaseline.x, z0);

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

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

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

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

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

yield return new WaitForSeconds(0.025f);
}
}

Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5687
Re: Text along a curve
« Reply #48 on: January 01, 2016, 02:59:04 PM »
Here is a revised script with updated Warp functions.

The warping is done on the Z-Axis (up / down). In order to have the text wrap on the Y-Axis, make the following changes at line 591 or 697 depending on which TMP component you are using.

Code: C#
  1. matrix = Matrix4x4.TRS(new Vector3(0, 0, y0), Quaternion.Euler(0, -angle, 0), Vector3.one);
  2.  


typeinwonderland

  • Newbie
  • *
  • Posts: 2
Re: Text along a curve
« Reply #49 on: January 01, 2016, 03:05:57 PM »
Awesome! it works well:)
Thank you so much!

Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5687
Re: Text along a curve
« Reply #50 on: January 01, 2016, 03:45:53 PM »
Awesome! it works well:)
Thank you so much!

You are most welcome and Happy New Year!

ARafay

  • Full Member
  • ***
  • Posts: 133
Re: Text along a curve
« Reply #51 on: January 06, 2016, 01:30:12 AM »
Hi Stephan,

Why VertexAttributeModifier is not part of TextMeshPro? This class along with other animation presets'd be great for new users.

Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5687
Re: Text along a curve
« Reply #52 on: January 06, 2016, 02:19:42 AM »
Hi Stephan,

Why VertexAttributeModifier is not part of TextMeshPro? This class along with other animation presets'd be great for new users.

I guess since it started out as just an example script, I never added it to the example scripts.

When I have some extra time, I'll clean it up and add it to the example scripts :)

ARafay

  • Full Member
  • ***
  • Posts: 133
Re: Text along a curve
« Reply #53 on: January 06, 2016, 07:51:31 AM »
Thanks :)

hadesfury

  • Beta User
  • Full Member
  • *
  • Posts: 133
Re: Text along a curve
« Reply #54 on: January 18, 2016, 08:35:34 AM »
It seems some
Code: [Select]
textComponent.renderMode = TextRenderFlags.Render; are missing

At the end of 
Code: [Select]
IEnumerator AnimateVertexColors(TextMeshProUGUI textComponent) for example
At the end of 
Code: [Select]
IEnumerator AnimateVertexPositions(TextMeshProUGUI textComponent) for example

Here's the version I modified

mihakinova

  • Newbie
  • *
  • Posts: 1
Re: Text along a curve
« Reply #55 on: January 25, 2016, 05:56:03 AM »
I'm trying to wrap my head around the math here, with little luck. Does anyone know how I would get the curve to use the bounds of the entire text field instead of just the text? So no matter what text I would put in, it would always curve the same way (e.g. now, the text curves "more" if there is only 5 characters compared to 30 characters).

hadesfury

  • Beta User
  • Full Member
  • *
  • Posts: 133
Re: Text along a curve
« Reply #56 on: January 25, 2016, 08:17:36 AM »
I really need that too ... but I does not have the time for now ...

dcrosby

  • Newbie
  • *
  • Posts: 12
Re: Text along a curve
« Reply #57 on: January 26, 2016, 01:04:20 PM »
I've been playing with Text on a spline, after I found some open implementation of splines on catlikecoding.com http://catlikecoding.com/unity/tutorials/curves-and-splines/ and it works, but doesn't adhere to the spline, am I doing something wrong ? I sent StephanB the source, so maybe he can shed some light, otherwise I will post the code here, so someone else may be able to pickup that torch.

-Derek

Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5687
Re: Text along a curve
« Reply #58 on: January 26, 2016, 01:08:58 PM »
I've been playing with Text on a spline, after I found some open implementation of splines on catlikecoding.com http://catlikecoding.com/unity/tutorials/curves-and-splines/ and it works, but doesn't adhere to the spline, am I doing something wrong ? I sent StephanB the source, so maybe he can shed some light, otherwise I will post the code here, so someone else may be able to pickup that torch.

-Derek

I'll take a look as soon as I have some extra time. Right now I am focusing on trying to get the beta release out with Multi Fonts & Sprites.

Since Jasper Flicks of Catlikecoding is a member of this forum I would suggest sending him a PM on this as he should be able to provide assistance.

Jasper Flick

  • Global Moderator
  • Jr. Member
  • *****
  • Posts: 85
Re: Text along a curve
« Reply #59 on: January 27, 2016, 07:58:16 AM »
Here is my reply to Miha's question, concerning the bounds problem, so others can see it too.
Quote
That script determines the curve sample point from the character’s local position. This position is converted into a 0-1 range inside the X-dimensional bounds of the mesh. These bounds are set using textComponent.bounds. Instead, you can use any value range here. Like the text field’s width or a manually configurable range. You might have to offset the bounds you’re using depending on how the mesh is positioned locally.

dcrosby, what do you mean with working but not adhering to the spline?
« Last Edit: January 27, 2016, 08:03:05 AM by Jasper Flick »