Search Unity

html to Text mesh pro?

Discussion in 'UGUI & TextMesh Pro' started by Shadowing, Oct 6, 2018.

  1. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    Has anyone made a thing that converts html to text mesh pro?
    Figure id ask before building one. Can save me some time if one already exists some where.
     
  2. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    bump

    if not how would I do a paragraph tag <p></p> for text mesh rich text?
     
  3. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    A paragraph is typically two consecutive linefeed / char(10) or "\n\n" in the text.
     
  4. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    when i use the page tags <page>fafdafdaf</page>
    TMPro isn't removing the </page>
    <page> tag gets removed just fine


     
  5. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    There is no </page> tag. The <page> tag increases the virtual page to force a page break when the text could still fit in the current page / vertical space.
     
  6. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    Thanks @Stephan_B I appreciate the help man.
    How can I handle embed html images with links. Does text Mesh pro have anything for that?
    I read about sprite but that seems just for emoji stuff.

    I'm using this other Text asset that lets me do clickable links like this
    <a class="external_link" name="https://google.com">This is my link to google</a>
    Then I can have a function that controls what happens when a <a> tag with that class name is clicked on.

    Does text mesh pro have anything like that?
    I looked at link for the rich text but that isn't quite the same. Really needs another data field.

    This is a example what i can do with this asset called Candlelight thats now depreciated sadly.
    Code (csharp):
    1.  
    2. <a class="external_link" name="https://google.com"></a>
    3. <a class="guide" name="Tutorials for newbies"></a>
    4.  
    5.  
    6.    public void Link(Candlelight.UI.HyperText hyperText, Candlelight.UI.HyperText.LinkInfo info) {
    7.      
    8.         switch(info.ClassName) {
    9.             case "guide":
    10.                  GuideButton.onClick.Invoke();
    11.         break;
    12.                 case "external_link":
    13.                 ExternalLink(info.Name);
    14.         break;
    15. }
    16. }
    17.  
     
    Last edited: Oct 10, 2018
  7. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The <link="ID"> tag is what you want to use. Unlike the <a href..> type tags, the link tag allows you to define any behavior you want when hovering over the section of the text enclosed in the link tag.

    See example 12 and 12a included in the TMP Examples and Extras.
     
  8. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    Thanks man im seeing all the examples now.
    Seems to be the same as what it says in the guide.

    See the <link="ID_01">online documentation</link>

    so its just an id tag with content.
    so the only way I can think to do this is to create my own string and parse it?

    See the <link="external_link">This is a link to google#https://google.com</link>
    Probably won't use that as the separator but just an example.
     
  9. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Something like <link="ExternalLink_01">This is the text users interact with aka link</link>

    Since you might have several external links, you give each of the unique ones their own ID. Then you can implement any logic you want in terms of what happens when a link is clicked or selected.
     
  10. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    Thanks for all the help man.
    I guess what I was saying is there should be a way to send data with your link. <link="ExternalLink_01" data="My data">
    This way you can create dynamic links/code.

    Code (csharp):
    1.  
    2. <link="external_link" data="https://google.com">This is a link to google</link>
    3.  
    If you have a link that looks like this below. You don't want people to see that huge long ugly link.
    Code (csharp):
    1.  
    2. https://www.google.com/search?q=how+to+fly+kites&rlz=1C1CHBF_enUS817US817&oq=how+to+fly+kites&aqs=chrome..69i57j0l5.2784j0j8&sourceid=chrome&ie=UTF-8
    3.  
    Creating your own separate dictionary for a few links is fine I guess. If you have say 1000 links that wouldn't work with out a data field.
     
    Last edited: Oct 12, 2018
  11. John-B

    John-B

    Joined:
    Nov 14, 2009
    Posts:
    1,262
    Following up on the OP, is there such a utility? I have a LOT of old HTML files that were previously used in a WebView, that I'm converting to UGUI and TMP. The formatting is pretty simple, just bold and italic tags, and the occasional super- or subscript. There's no way to find formatted text in Pages, and if it can be done in Word with wildcards, I can't figure it out.
     
  12. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    doesn't exist man. Gonna have to rewrite it.
     
  13. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    @Stephan_B
    idk im trying out demo scene 12 and 12a
    Doesn't show how to do a clickable link?
    It seems TMP_text Event Handler is only for hover over?
     
  14. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Review the code in the TMP_TextSelector_B.cs script in the "Example of Link Handling" section. In this case, it shows how some action in this case some instantiated object (in the Awake() function) can be positioned / shown on hover. However, this action could be implemented to do anything such as opening some browser to a specific link.

    The Link tag isn't related to a "link" in a browser sense but used to define a section of text (with some unique ID) that would want to track so that you can implement whatever logic you want whether it be OnClick, OnHover, etc. Again the link tag allows you to simply define a section of text so you can track / interact with it.
     
  15. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    I got it figured out finally using your response on this thread
    https://forum.unity.com/threads/clickable-text-link-example-doesnt-work.654472/
    I really frown on editing a TMP script though. I see i could make my own event on a custom script.

    I added get mouse down on TextEventhandler
    Code (csharp):
    1. Input.GetMouseButtonDown(0)

    Code (csharp):
    1.  
    2.  
    3.         void LateUpdate()
    4.         {
    5.             if (Input.GetMouseButtonDown(0) && TMP_TextUtilities.IsIntersectingRectTransform(m_TextComponent.rectTransform, Input.mousePosition, m_Camera))
    6.             {
    7.  
     
  16. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    Actually I just notice this isn't working.
    It only works on one click. After that clicking it again doesn't work.
     
  17. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    Alright I decided to do this instead

    Code (csharp):
    1.  
    2.  
    3. using TMPro;
    4. using UnityEngine;
    5. using UnityEngine.EventSystems;
    6. public class GameLink : MonoBehaviour, IPointerClickHandler
    7. {
    8.     public GameObject LinkGameObject;
    9.     [Tooltip("Only include a camera if canvas uses a camera")]
    10.     public Camera m_Camera;
    11.     TMP_Text m_TextMeshPro;
    12.     Camera Camera;
    13.  
    14.  
    15.     void Awake() {
    16.         m_TextMeshPro = gameObject.GetComponent<TextMeshProUGUI>();
    17.         Camera = m_Camera ? m_Camera : null;
    18.     }
    19.     public void OnPointerClick(PointerEventData eventData){
    20.             int linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextMeshPro, Input.mousePosition, Camera);
    21.             if (linkIndex != -1)
    22.             {
    23.                 TMP_LinkInfo linkInfo = m_TextMeshPro.textInfo.linkInfo[linkIndex];
    24.                 string LinkData = linkInfo.GetLinkID();
    25.                 LinkGameObject.SendMessage("Link",LinkData);
    26.         }
    27.     }
    28. }
    29.  
    30.  
     
  18. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    I'm having problems getting the whole link to change color when hover over it. Where it changes color of every word in the link and not just the word thats currently being hovered over.
    It seems your example should do this? I can't imagine any reason why someone would want a single word in a link to change color only.

    anyways on this example I grabed a example you had for Onclick to change color but I think it has depreciated code maybe.

    meshInfo.uiVertices and linkInfo.characterCount don't exist in your api.


    Code (csharp):
    1.  
    2.  
    3. void LateUpdate()
    4.         {
    5.             if (isHoveringObject)
    6.             {
    7.                         // Check if Mouse intersects any words and if so assign a random color to that word.
    8.             int linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextMeshPro, Input.mousePosition, Camera);
    9.             if (linkIndex != -1)
    10.             {
    11.                 TMP_LinkInfo linkInfo = m_TextMeshPro.textInfo.linkInfo[linkIndex];
    12.                 UIVertex[] uiVertices = m_TextMeshPro.textInfo.meshInfo.uiVertices;
    13.                 Color32 c = new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255), (byte)Random.Range(0, 255), 255);
    14.                 for (int i = 0; i < linkInfo.characterCount; i++)
    15.                 {
    16.                     TMP_CharacterInfo cInfo = m_TextMeshPro.textInfo.characterInfo[linkInfo.firstCharacterIndex + i];
    17.                     if (!cInfo.isVisible) continue; // Skip invisible characters.
    18.                     int vertexIndex = cInfo.vertexIndex;
    19.                     uiVertices[vertexIndex + 0].color = c;
    20.                     uiVertices[vertexIndex + 1].color = c;
    21.                     uiVertices[vertexIndex + 2].color = c;
    22.                     uiVertices[vertexIndex + 3].color = c;
    23.                 }
    24.                 m_TextMeshPro.canvasRenderer.SetVertices(uiVertices, uiVertices.Length);
    25.             }
    26.             else
    27.             {
    28.                 // Restore any character that may have been modified
    29.                 if (m_lastIndex != -1)
    30.                 {
    31.                     RestoreCachedVertexAttributes(m_lastIndex);
    32.                     m_lastIndex = -1;
    33.                 }
    34.             }
    35.            
    36.         }
    37.  
     
  19. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Make sure you are looking at examples scripts contained in the TMP Examples & Extras contained in whatever version of the TMP package you are using as the code from above appears to be from some older source as indeed TMP_LinkInfo does not contain properties like characterCount.

    Using whatever code editor you are using, you should be able to see the properties contained in the TMP_TextInfo where the relevant ones are:

    public int linkTextfirstCharacterIndex;
    public int linkTextLength;

    This linkTextfirstCharacterIndex is the index of the character in the TMP_Text.textInfo.characterInfo[index] whose vertex color you would want to change. To do that, you then have to look at what material index and ultimately what vertices index this character is using the meshInfo.

    See example 23 - Animating Vertex Attributes which contains another example script showing how to changes these vertex colors.
     
  20. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    Alright I removed text mesh pro and updated to 15.0
    re-imported essentials and demos and that depreciated code still exists.
    You probably didn't realize it cause its commented out in the demo.
     
  21. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    Why is it that it takes like 6 frames before FindingIntersectingLink returns a link being hovered over?
    I'm using ScreenSpaceOverlay

    After I realized this no wonder my code is being wacky.
    The example code is inefficient. Trying to change the color every so many frames while being hovered over. Well I think maybe the logic does prevent that.


    Code (csharp):
    1.  
    2.    public void LateUpdate(){
    3.           if (CurrentHoverLinkStatus == SwitchStatus.On) {
    4.              
    5.                // Check if mouse intersects with any links.
    6.                linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextMeshPro, Input.mousePosition, m_Camera);
    7.             Debug.Log(linkIndex);
    8.                // Handle new Link selection.
    9.                if (linkIndex != -1){
    10.  
    11.  
     
    Last edited: Mar 27, 2020
  22. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    I ran into a problem. I got my script all finished.
    but hover on and off detection isn't right. It detects rather I hover over the entire text area instead of just the link.
    So the link changes colors just by the cursor entering the text area instead of just the link only.

    Code (csharp):
    1.  
    2.  
    3. using TMPro;
    4. using UnityEngine;
    5. using UnityEngine.EventSystems;
    6. public class GameLink : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler, IPointerExitHandler
    7. {
    8.     [Header("References")]
    9.     public GameObject LinkGameObject;
    10.     [Tooltip("Only include a camera if canvas uses a camera")]
    11.     public Camera m_Camera = null;
    12.     [Space(8)]
    13.     [Header("Link Colors")]
    14.     public bool OverrideDefaultColors = false;
    15.     public Color32 DefaultColor = Color.white;
    16.     public Color32 HoverColor = Color.cyan;
    17.     public Color32 ClickColor = Color.gray;
    18.     private TMP_Text m_TextMeshPro;
    19.     private bool isHoveringObject;
    20.     private int linkIndex = -1;
    21.     private TMP_LinkInfo linkInfo;
    22.     private bool CurrentHoverLinkStatus = false;
    23.     private Color32 defaultColor = Color.white;
    24.     private Color32 hoverColor = Color.cyan;
    25.     private Color32 clickColor = Color.gray;
    26.  
    27.     void Awake() {
    28.         m_TextMeshPro = gameObject.GetComponent<TextMeshProUGUI>();
    29.     }
    30.  
    31.     void Start() {
    32.             defaultColor = OverrideDefaultColors ? DefaultColor : GameSettings.defaultColor;
    33.             hoverColor = OverrideDefaultColors ? HoverColor : GameSettings.hoverColor;
    34.             clickColor = OverrideDefaultColors ? ClickColor : GameSettings.clickColor;
    35.     }
    36.  
    37.     void OnEnable(){
    38.             // Subscribe to event fired when text object has been regenerated.
    39.             TMPro_EventManager.TEXT_CHANGED_EVENT.Add(ON_TEXT_CHANGED);
    40.     }
    41.  
    42.     void OnDisable(){
    43.             // UnSubscribe to event fired when text object has been regenerated.
    44.             TMPro_EventManager.TEXT_CHANGED_EVENT.Remove(ON_TEXT_CHANGED);
    45.     }
    46.  
    47.     void ON_TEXT_CHANGED(Object obj){
    48.             if (obj == m_TextMeshPro){
    49.                TMP_LinkInfo[]  AllLinks = m_TextMeshPro.textInfo.linkInfo;
    50.                 foreach (TMP_LinkInfo Link in AllLinks) {
    51.                     linkInfo = Link;
    52.                     ChangeLinkColor(defaultColor);
    53.                 }
    54.             }
    55.     }
    56.  
    57.     public void OnPointerDown(PointerEventData eventData){
    58.        linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextMeshPro, Input.mousePosition, m_Camera);
    59.        if (linkIndex != -1){
    60.                 ChangeLinkColor(clickColor);
    61.                 linkInfo = m_TextMeshPro.textInfo.linkInfo[linkIndex];
    62.                 string LinkData = linkInfo.GetLinkID();
    63.                 LinkGameObject.SendMessage("Link",LinkData);
    64.         }
    65.     }
    66.  
    67.     public void OnPointerUp(PointerEventData eventData){
    68.         if (linkIndex != -1){
    69.             ChangeLinkColor(isHoveringObject && !CurrentHoverLinkStatus ? hoverColor: defaultColor);
    70.             linkIndex = -1;
    71.         }
    72.     }
    73.  
    74.     public void OnPointerEnter(PointerEventData eventData){
    75.         isHoveringObject = true;
    76.     }
    77.  
    78.     public void OnPointerExit(PointerEventData eventData){
    79.         isHoveringObject = false;
    80.     }
    81.  
    82.    public void LateUpdate(){
    83.         if (isHoveringObject && linkIndex == -1) {
    84.                // Check if mouse intersects with any links.
    85.                linkIndex = TMP_TextUtilities.FindIntersectingLink(m_TextMeshPro, Input.mousePosition, m_Camera);
    86.         }
    87.         if (linkIndex == -1) {
    88.             return;
    89.         }
    90.         if (isHoveringObject && !CurrentHoverLinkStatus) {
    91.             linkInfo = m_TextMeshPro.textInfo.linkInfo[linkIndex];
    92.             ChangeLinkColor(hoverColor);
    93.             CurrentHoverLinkStatus = true;
    94.         }
    95.         if (!isHoveringObject && CurrentHoverLinkStatus){
    96.             ChangeLinkColor(defaultColor);
    97.             CurrentHoverLinkStatus = false;
    98.             linkIndex = -1;
    99.         }
    100.  }
    101.  
    102.     void ChangeLinkColor(Color32 color) {
    103.             // Iterate through each of the characters of the link.
    104.             for (int i = 0; i < linkInfo.linkTextLength; i++){
    105.                     int characterIndex = linkInfo.linkTextfirstCharacterIndex + i;
    106.                     // Get the index of the material / sub text object used by this character.
    107.                     int meshIndex = m_TextMeshPro.textInfo.characterInfo[characterIndex].materialReferenceIndex;
    108.                     int vertexIndex = m_TextMeshPro.textInfo.characterInfo[characterIndex].vertexIndex;
    109.                     // Get a reference to the vertex color
    110.                     Color32[] vertexColors = m_TextMeshPro.textInfo.meshInfo[meshIndex].colors32;
    111.                     vertexColors[vertexIndex + 0] = color;
    112.                     vertexColors[vertexIndex + 1] = color;
    113.                     vertexColors[vertexIndex + 2] = color;
    114.                     vertexColors[vertexIndex + 3] = color;
    115.             }
    116.             // Update Geometry
    117.             m_TextMeshPro.UpdateVertexData(TMP_VertexDataUpdateFlags.All);
    118.     }
    119. }
    120.  
    121.  


    Edit: oh wait it only does that when hovering off so its a logic mistake in my code then.
     
    marius_87 likes this.
  23. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    Ahh I see what my issue is I'm not detecting if IntersectingLink is -1 when hovering off lol.

    I noticed that FindIntersectingLink works on the current frame when inside OnPointerDown but not when inside OnPointerEnter? How can that be. Why is OnPointerEnter a 6 or 8 frame detection wait?
     
  24. Shadowing

    Shadowing

    Joined:
    Jan 29, 2015
    Posts:
    1,648
    Oh i see whats going on now lmao. It was never skipping frame. When i was moving my cursor over the text area to the link it was returning negative until my cursor was over the link lol.

    My bad I understand all that now :)
     
  25. crafTDev

    crafTDev

    Joined:
    Nov 5, 2008
    Posts:
    1,820
    Hello,

    I’ve developed a simple asset that handles this issue. It will be put up on the asset store soon!

    Thanks,
    crafTDev
     
    jGate99 likes this.
  26. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,945
    did u wrote an html parser? if so im in
     
  27. crafTDev

    crafTDev

    Joined:
    Nov 5, 2008
    Posts:
    1,820
    Yes.

    Thanks,
    crafTDev
     
    jGate99 likes this.
  28. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    1,945
    Finally, cant wait :D
     
  29. Taggler

    Taggler

    Joined:
    Apr 13, 2018
    Posts:
    6
    Have you release it on asset store