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

cnumber1

  • Newbie
  • *
  • Posts: 11
Re: Text along a curve
« Reply #105 on: July 15, 2016, 09:51:41 AM »
Thanks for the reply.
I am on version "Release 0.1.54 Beta 3c"
I downloaded the latest from the forum, beta 4 and installed it, it still says beta 3c in the comments inside TextMeshPro.cs

I tried it again with the same results

Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5687
Re: Text along a curve
« Reply #106 on: July 15, 2016, 12:10:09 PM »
Thanks for the reply.
I am on version "Release 0.1.54 Beta 3c"
I downloaded the latest from the forum, beta 4 and installed it, it still says beta 3c in the comments inside TextMeshPro.cs

I tried it again with the same results

I'll try to get you the updated script this afternoon which should help you get a feel for what needs to be modified.

cnumber1

  • Newbie
  • *
  • Posts: 11
Re: Text along a curve
« Reply #107 on: July 15, 2016, 01:05:47 PM »
Cool, thank you.

Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5687
Re: Text along a curve
« Reply #108 on: July 15, 2016, 01:40:26 PM »
Below is an updated script that I am using which works fine with the <font> and <sprite> tags as you can see from the image below.

Given this one a try and let me know if it works as expected. I may have updated some other stuff on my end which could affect this so we will find out.




Code: C#
  1. // Copyright (C) 2014 - 2016 Stephan Bouchard - All Rights Reserved
  2. // This code can only be used under the standard Unity Asset Store End User License Agreement
  3. // A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms
  4.  
  5.  
  6. using UnityEngine;
  7. using System.Collections;
  8.  
  9.  
  10. namespace TMPro.Examples
  11. {
  12.  
  13.    public class WarpTextExample : MonoBehaviour
  14.    {
  15.  
  16.        private TMP_Text m_TextComponent;
  17.  
  18.        public AnimationCurve VertexCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.25f, 2.0f), new Keyframe(0.5f, 0), new Keyframe(0.75f, 2.0f), new Keyframe(1, 0f));
  19.        public float AngleMultiplier = 1.0f;
  20.        public float SpeedMultiplier = 1.0f;
  21.        public float CurveScale = 1.0f;
  22.  
  23.        void Awake()
  24.        {
  25.            m_TextComponent = gameObject.GetComponent<TMP_Text>();
  26.        }
  27.  
  28.  
  29.        void Start()
  30.        {
  31.            StartCoroutine(WarpText());
  32.        }
  33.  
  34.  
  35.        private AnimationCurve CopyAnimationCurve(AnimationCurve curve)
  36.        {
  37.            AnimationCurve newCurve = new AnimationCurve();
  38.  
  39.            newCurve.keys = curve.keys;
  40.  
  41.            return newCurve;
  42.        }
  43.  
  44.  
  45.        /// <summary>
  46.        ///  Method to curve text along a Unity animation curve.
  47.        /// </summary>
  48.        /// <param name="textComponent"></param>
  49.        /// <returns></returns>
  50.        IEnumerator WarpText()
  51.        {
  52.            VertexCurve.preWrapMode = WrapMode.Clamp;
  53.            VertexCurve.postWrapMode = WrapMode.Clamp;
  54.  
  55.            //Mesh mesh = m_TextComponent.textInfo.meshInfo[0].mesh;
  56.  
  57.            Vector3[] vertices;
  58.            Matrix4x4 matrix;
  59.  
  60.            m_TextComponent.havePropertiesChanged = true; // Need to force the TextMeshPro Object to be updated.
  61.            CurveScale *= 10;
  62.            float old_CurveScale = CurveScale;
  63.            AnimationCurve old_curve = CopyAnimationCurve(VertexCurve);
  64.  
  65.            while (true)
  66.            {
  67.                if (!m_TextComponent.havePropertiesChanged && old_CurveScale == CurveScale && old_curve.keys[1].value == VertexCurve.keys[1].value)
  68.                {
  69.                    yield return null;
  70.                    continue;
  71.                }
  72.  
  73.                old_CurveScale = CurveScale;
  74.                old_curve = CopyAnimationCurve(VertexCurve);
  75.  
  76.                m_TextComponent.ForceMeshUpdate(); // Generate the mesh and populate the textInfo with data we can use and manipulate.
  77.  
  78.                TMP_TextInfo textInfo = m_TextComponent.textInfo;
  79.                int characterCount = textInfo.characterCount;
  80.  
  81.  
  82.                if (characterCount == 0) continue;
  83.  
  84.                //vertices = textInfo.meshInfo[0].vertices;
  85.                //int lastVertexIndex = textInfo.characterInfo[characterCount - 1].vertexIndex;
  86.  
  87.                float boundsMinX = m_TextComponent.bounds.min.x;  //textInfo.meshInfo[0].mesh.bounds.min.x;
  88.                float boundsMaxX = m_TextComponent.bounds.max.x;  //textInfo.meshInfo[0].mesh.bounds.max.x;
  89.  
  90.  
  91.  
  92.                for (int i = 0; i < characterCount; i++)
  93.                {
  94.                    if (!textInfo.characterInfo[i].isVisible)
  95.                        continue;
  96.  
  97.                    int vertexIndex = textInfo.characterInfo[i].vertexIndex;
  98.  
  99.                    // Get the index of the mesh used by this character.
  100.                    int materialIndex = textInfo.characterInfo[i].materialReferenceIndex;
  101.  
  102.                    vertices = textInfo.meshInfo[materialIndex].vertices;
  103.  
  104.                    // Compute the baseline mid point for each character
  105.                    Vector3 offsetToMidBaseline = new Vector2((vertices[vertexIndex + 0].x + vertices[vertexIndex + 2].x) / 2, textInfo.characterInfo[i].baseLine);
  106.                    //float offsetY = VertexCurve.Evaluate((float)i / characterCount + loopCount / 50f); // Random.Range(-0.25f, 0.25f);
  107.  
  108.                    // Apply offset to adjust our pivot point.
  109.                    vertices[vertexIndex + 0] += -offsetToMidBaseline;
  110.                    vertices[vertexIndex + 1] += -offsetToMidBaseline;
  111.                    vertices[vertexIndex + 2] += -offsetToMidBaseline;
  112.                    vertices[vertexIndex + 3] += -offsetToMidBaseline;
  113.  
  114.                    // Compute the angle of rotation for each character based on the animation curve
  115.                    float x0 = (offsetToMidBaseline.x - boundsMinX) / (boundsMaxX - boundsMinX); // Character's position relative to the bounds of the mesh.
  116.                    float x1 = x0 + 0.0001f;
  117.                    float y0 = VertexCurve.Evaluate(x0) * CurveScale;
  118.                    float y1 = VertexCurve.Evaluate(x1) * CurveScale;
  119.  
  120.                    Vector3 horizontal = new Vector3(1, 0, 0);
  121.                    //Vector3 normal = new Vector3(-(y1 - y0), (x1 * (boundsMaxX - boundsMinX) + boundsMinX) - offsetToMidBaseline.x, 0);
  122.                    Vector3 tangent = new Vector3(x1 * (boundsMaxX - boundsMinX) + boundsMinX, y1) - new Vector3(offsetToMidBaseline.x, y0);
  123.  
  124.                    float dot = Mathf.Acos(Vector3.Dot(horizontal, tangent.normalized)) * 57.2957795f;
  125.                    Vector3 cross = Vector3.Cross(horizontal, tangent);
  126.                    float angle = cross.z > 0 ? dot : 360 - dot;
  127.  
  128.                    matrix = Matrix4x4.TRS(new Vector3(0, y0, 0), Quaternion.Euler(0, 0, angle), Vector3.one);
  129.  
  130.                    vertices[vertexIndex + 0] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 0]);
  131.                    vertices[vertexIndex + 1] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 1]);
  132.                    vertices[vertexIndex + 2] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 2]);
  133.                    vertices[vertexIndex + 3] = matrix.MultiplyPoint3x4(vertices[vertexIndex + 3]);
  134.  
  135.                    vertices[vertexIndex + 0] += offsetToMidBaseline;
  136.                    vertices[vertexIndex + 1] += offsetToMidBaseline;
  137.                    vertices[vertexIndex + 2] += offsetToMidBaseline;
  138.                    vertices[vertexIndex + 3] += offsetToMidBaseline;
  139.                }
  140.  
  141.  
  142.                // Upload the mesh with the revised information
  143.                m_TextComponent.UpdateVertexData();
  144.  
  145.                yield return new WaitForSeconds(0.025f);
  146.            }
  147.        }
  148.    }
  149. }
  150.  

cnumber1

  • Newbie
  • *
  • Posts: 11
Re: Text along a curve
« Reply #109 on: July 15, 2016, 04:48:14 PM »
thanks for the help, that solved my issue :)

Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5687
Re: Text along a curve
« Reply #110 on: July 15, 2016, 07:31:16 PM »
thanks for the help, that solved my issue :)

You are welcome :)

Now in terms of the addition of a <material> tag please see the following post. http://digitalnativestudios.com/forum/index.php?topic=1150.0

MV10

  • Newbie
  • *
  • Posts: 38
Re: Text along a curve
« Reply #111 on: October 15, 2016, 07:48:53 AM »
Before I start messing around with VertexAttributeModifier, I want to ask if it will help with my specific requirement.

I need to align text to arcs -- a specific segment of the circumference of a circle. I have the starting and ending angle (for example, a radius R, a Vector3 centerpoint, from 75 degrees to 95 degrees), and I can easily calculate Vector3s anywhere along that arc. The arcs aren't animated but they're generated at runtime from code.

I ask because it sounds like this script relies on splines or Bezier curves, which won't work for me. (A single spline segment can't represent more than one quarter of a circle, plus calculating the needed control points is quite a bit more work -- and of course, I already have the other data available and working.)

Additionally, I'd like the text to be vertically aligned through the center, as requested in this thread, but I'll try the voffset thing he mentions, and the other stuff you did in response to this one may work, too -- new to me since I last updated TMP.

Is the VertexAttributeModifier script the right place to start or is my scenario too different?

Edit: Since I can calculate arbitrary vectors on my desired path it looks like I can easily adapt dshook's script (plug in my arc functions instead of the Bezier function)... not quite sure what a curve "velocity" is yet but it looks promising.
« Last Edit: October 15, 2016, 08:31:24 AM by MV10 »

MV10

  • Newbie
  • *
  • Posts: 38
Re: Text along a curve
« Reply #112 on: October 15, 2016, 12:44:33 PM »
Got it! Thanks dshook, if you're out there! :D

[ Guests cannot view attachments ]

MV10

  • Newbie
  • *
  • Posts: 38
Re: Text along a curve
« Reply #113 on: October 15, 2016, 01:00:46 PM »
Hmm, or maybe not quite... ah, bet I have to subtract X from the mesh vertex corners when it passes 180 degrees instead of adding. Weird. Feels like something that ought to have a better solution than brute force but it isn't coming to me right now.

[ Guests cannot view attachments ]

Edit: Ah, of course ... rotation is counterclockwise, but text is always left-to-right so at 180 I have to work backwards through the angles. Uh, it gets "interesting" when the text overlaps that boundary.

[ Guests cannot view attachments ]
« Last Edit: October 15, 2016, 01:27:38 PM by MV10 »

MV10

  • Newbie
  • *
  • Posts: 38
Re: Text along a curve
« Reply #114 on: October 16, 2016, 03:39:06 PM »
Well I finally put together a somewhat-generalized solution. It's difficult to programmatically decide on the right parameters based on text length, radius, and the available space -- which must then be expressed as start/end angles. But good enough for now, I suppose.

[ Guests cannot view attachments ]

Jasper Flick

  • Global Moderator
  • Jr. Member
  • *****
  • Posts: 85
Re: Text along a curve
« Reply #115 on: October 17, 2016, 11:53:52 AM »
Looking good, MV10!

Trigan

  • Newbie
  • *
  • Posts: 3
Re: Text along a curve
« Reply #116 on: November 26, 2016, 10:42:06 AM »
Hello all.

Just getting up to speed on whats available. I need the text to be curved as so the face of the the text is all pointing towards a central  point. ( A viewer in VR who would see all text equidistant around them).  Is there any code existing already doing that. Is this easily achievable?  Thanks.

Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5687
Re: Text along a curve
« Reply #117 on: November 26, 2016, 12:24:06 PM »
Hello all.

Just getting up to speed on whats available. I need the text to be curved as so the face of the the text is all pointing towards a central  point. ( A viewer in VR who would see all text equidistant around them).  Is there any code existing already doing that. Is this easily achievable?  Thanks.

The following post / reply on page 4 should provide enough information for you to achieve this. In that example the text is curved in the opposite direction you want but that is simple to change.

here is the link http://digitalnativestudios.com/forum/index.php?topic=31.msg6390#msg6390

Trigan

  • Newbie
  • *
  • Posts: 3
Re: Text along a curve
« Reply #118 on: November 26, 2016, 01:44:04 PM »
Doh!  I thought I had looked through this entire thread before I asked. Thanks.

With referenced files like VertexAttributeModifier.cs do you keep the latest one in a central spot or do we have to go through a thread looking for it?

I noticed that there are no version #'s or dates in the comments.  I am having trouble discerning what version(s) exist and which is the latest.

Is there any sort of version control going on I am unaware of? 


Stephan B.

  • Administrator
  • Hero Member
  • *****
  • Posts: 5687
Re: Text along a curve
« Reply #119 on: November 26, 2016, 01:53:14 PM »
Doh!  I thought I had looked through this entire thread before I asked. Thanks.

With referenced files like VertexAttributeModifier.cs do you keep the latest one in a central spot or do we have to go through a thread looking for it?

I noticed that there are no version #'s or dates in the comments.  I am having trouble discerning what version(s) exist and which is the latest.

Is there any sort of version control going on I am unaware of?

The latest versions of those example scripts or revised implementations of them are included in the Examples/Scripts folder. The newer implementation of the text curving is the "WarpTextExample.cs"