Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Caching large amounts of text for an ebook

Discussion in 'UGUI & TextMesh Pro' started by sandworm, Apr 2, 2020.

  1. sandworm

    sandworm

    Joined:
    Aug 28, 2019
    Posts:
    13
    I'm building an ebook application in Unity, and since large files quickly overwhelm TMP, I'm trying to cache chunks of the book for TMP to display.

    The problem I'm running into is that I can't seem to get what text is actually being displayed vs what's being sent to the text box.

    I have tried using the page overflow mode (imagine an open book with two TMPs, one showing page 1 and one showing page 2) and grabbing the firstOverflowCharacterIndex, but it doesn't seem to work quite right. The index appears the same on both the page panels, so I cannot grab the true first character of the next page.

    My current concept is that I can populate the text box with a small part of the book, grab how many characters are actually on display, and create a substring from that count for "turning the page." Obviously I'd like it not to cut off in the middle of a word, but I'll deal with that once I've got this part working.

    Can someone point me in the right direction here?
     
  2. sandworm

    sandworm

    Joined:
    Aug 28, 2019
    Posts:
    13
    I really just need the exact amount of characters displayed (not overflowed) in a TMP field. Anyone?
     
  3. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    The text component has the following property

    public int firstOverflowCharacterIndex

    This property is the index of the first character that overflows. Using the TMP_Text.textInfo.characterCount which contains the total number of characters including the overflow, so TMP_Text.textInfo.characterCount - firstOverflowCharacterIndex should be the number of characters contained in the text container. You will need to check each character as some are not visible which is a property of the TMP_Text.textInfo.characterInfo[index].isVisible.
     
  4. sandworm

    sandworm

    Joined:
    Aug 28, 2019
    Posts:
    13
    Hey Stephan, thanks for getting back to me.

    I have tried
    Code (CSharp):
    1. Debug.Log("Characters displayed = " + (page1.textInfo.characterCount - page1.firstOverflowCharacterIndex));
    but although it is displaying a page full of text, it's returning a character count of 7... What am I missing?
    upload_2020-4-4_10-2-27.png

    The method I'm using here is as follows:

    Code (CSharp):
    1. page1.overflowMode = TextOverflowModes.Truncate;
    2.             page2.overflowMode = TextOverflowModes.Truncate;
    3.  
    4.             page1.ForceMeshUpdate();
    5.             page2.ForceMeshUpdate();
    6.  
    7.             cacheSize = page1.firstOverflowCharacterIndex  + page2.firstOverflowCharacterIndex;
    8.             Debug.Log("Cache Size is : " + cacheSize + " p1 foci " + page1.firstOverflowCharacterIndex + " p2 foci " + page2.firstOverflowCharacterIndex + " p1 linecount " + page1.textInfo.lineCount + " p1 maxvischars " + page1.maxVisibleCharacters);
    9.  
    10.             int charCount = (page1.textInfo.characterCount - page1.firstOverflowCharacterIndex);
    11.             Debug.Log("Characters displayed = " + charCount);
    12.  
    13.             page1.overflowMode = TextOverflowModes.Page;
    14.             page2.overflowMode = TextOverflowModes.Page;
     
  5. sandworm

    sandworm

    Joined:
    Aug 28, 2019
    Posts:
    13
    I have made a little progress here. I now have it grabbing a cache based on the character count initially displayed in the text field, but it appears this isn't always correct due to line breaks (hence it's not using the max count).

    For example if I determine that the first page displays 1000 chars in the text field, then when I page down I grab a substring from the full text from 1000 with a length of 1000. If there are a bunch of line breaks in that substring, it will truncate. The result is the pagination is off.

    It appears using firstOverflowCharacterIndex is returning a weird value if I subtract it from textInfo.characterCount. Perhaps if I pack the text field completely full of characters to get the max count, then populate the page with the real text, grab firstOverflowCharacterIndex and use it as the next page start pointer, I can intelligently grab the right amount of text each time.

    Thoughts?
     
  6. sandworm

    sandworm

    Joined:
    Aug 28, 2019
    Posts:
    13
    Update: Using this method and maintaining a list of string caches from previous pages got me there. It would be lovely if TMP could do this on its on on the back end, but I can understand why it doesn't, it's not a primary use case!
     
  7. junior330

    junior330

    Joined:
    Jan 15, 2020
    Posts:
    5
    Yeah, it would be if it would be on the back-end side.