Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

nospoone

12
Posts
2
Topics
1
Following
A member registered May 20, 2016

Creator of

Recent community posts

(1 edit)

Great find! That makes sense - it made me remember something about TextMeshPro's Rebuild() which is passing in a `UnityEngine.UI.CanvasUpdate` value. From that, I tried calling `Canvas.ForceUpdateCanvases();` just before setting the text (so before triggering a Rebuild()) and it worked. My script looks like this now:

using UnityEngine;
using I2.Loc;
    
[RequireComponent(typeof(SuperTextMesh))]
public class VSScreenTextHelper : MonoBehaviour {
    public string LocalizationString;
    private SuperTextMesh textMesh;
    
    void Start () {
        textMesh = GetComponent<SuperTextMesh>();
        Canvas.ForceUpdateCanvases();
        textMesh.Text = LocalizationManager.GetTermTranslation(LocalizationString);
    }
}

This makes me think that this is happening only because I'm calling it inside the Start/Awake function. As per docs (emphasis mine):

A canvas performs its layout and content generation calculations at the end of a frame, just before rendering, in order to ensure that it's based on all the latest changes that may have happened during that frame. This means that in the Start callback and the first Update callback, the layout and content under the canvas may not be up-to-date.

Code that relies on up-to-date layout or content can call this method to ensure it before executing code that relies on it.

I hope this can lead you to a potential implementable solution inside STM! Cheers!

Here's an example project, just add STM and it should reproduce correctly!

(1 edit)

Calling Rebuild() unfortunately doesn't do it, as well as putting the method under Start(). 馃

Thanks for taking the time to look into this 馃槉

(1 edit)

Hey!

Thanks again for STM, been a user for a wee bit (we even talked before!) and it has worked wonders for me. I unfortunately come to you today with a problem. 

Context
I have a simple screen with some text in it:


This looks great, however when I want to localize the text, things get hairy. Here is the code I use to localize my text:

using UnityEngine;
using I2.Loc;
[RequireComponent(typeof(SuperTextMesh))]
public class VSScreenTextHelper : MonoBehaviour {
    public string LocalizationString;
    private SuperTextMesh textMesh;
    
    void Awake () {
        textMesh = GetComponent<SuperTextMesh>();
        textMesh.Text = LocalizationManager.GetTermTranslation(LocalizationString);
    }
}

Pretty simple, yeah? This script is attached to the GameObject that has the STM component on it, which is a UI object (it has a RectTransform). The code puts in a new string inside STM's Text property and sends it on its way. Yet, as you might have already realized, problems arise.

Problem
When setting Text on an STM instance via code on a UI object, STM loses its alignment until any property is triggered in the inspector. Below is a gif of the process.


What I've tried
I tried a couple things before coming on these here forums to ask for help:

  • Messing with the parent's layout options
  • Using content size fitters
  • Triggering Rebuild() after changing the text
  • Toggling options via code, and then Rebuild()ing

I would love to dive into STM's codebase to figure it out but unfortunately with a big deadline looming above my head it's impossible for me to do so. I hope I provided enough information for you to be able to have at least a vague idea of what's going on.

Thanks for any help you can provide!

All good! Happy that I could solve my text worries :D

I've ended up implementing a bool to toggle the sizing:


As I needed another text to stay a certain size. That bool just replaces the one at line 2510 (that I commented out) and allows me to toggle the feature on or off.

Cheers!

Based on the information above, I was able to make this work by changing the AutoWrap property to this:

private float AutoWrap{ //get autowrap limit OR ui bounds
   get{
      if(uiMode && wrapText) return initialUIAutoWrap; //get wrap limit, within left and right bounds!
      return autoWrap;
   }
}
private float initialUIAutoWrap = 0;

and adding this to OnEnable():

if (uiMode && wrapText) {
   initialUIAutoWrap = ((RectTransform) t).rect.width;
}

which yields the correct sizes in my tests! Success!


I have to figure out the correct padding values, but other than that, it is working! Thanks so much for the help!

(3 edits)
<img src="<a href="https://img.itch.zone/aW1nLzc0MzI5Ny5wbmc=/original/sodrsd.png">https://img.itch.zone/aW1nLzc0MzI5Ny5wbmc=/original/sodrsd.png</a>">RebuildTextInfo

Whoa! Removing that, combined with changing my setting code to:

private void OnDialoguerTextPhase(DialoguerTextData data) {
   RectTransform dialogBoxTextTransform = (RectTransform) DialogBoxText.gameObject.transform;
   DialogBox.SetActive(true);
   DialogBoxText.text = LocalizationManager.GetTermTranslation(data.text);
   DialogBoxText.Rebuild();
   DialogFrame.sizeDelta = dialogBoxTextTransform.sizeDelta;
}

Makes it fit the text. However, how do I define how far it can go before it wraps?

 

Upon further inspection it seems like it makes it fit the longest word? 馃

---

Edit 1

Looking at SuperTextMesh.cs:

if(uiMode && wrapText) return (float)((RectTransform)t).rect.width; //get wrap limit, within left and right bounds!

Seems like it's not respecting it in some way? Looking further...

---

Edit 2

Seems like AutoWrap gets reset somehow? Calling the code above calls RebuildTextInfo() three times with different AutoSize values:

---

Edit 3

Well, since SetMesh() overwrites the sizeDelta of the RectTransform, it changes the value to the new one (shrunk text), making it impossible to expand it to what it was set initially.

rect.sizeDelta = new Vector2(textMesh.bounds.size.x, textMesh.bounds.size.y);

(1 edit)

Hmm. Using bounds like so:

Vector3 size = DialogBoxText.topLeftBounds - DialogBoxText.bottomRightBounds;

yields correct height, but incorrect width:

I'll try using a VertexMod to get the correct bounds, to see if that works out...

I've been away from updates for so long, forgive me if I've forgotten stuff about my own asset!

No problem whatsoever!

Is it possible to just use the size of the recttransform, itself?

Yes! The problem I had with this, however, is that it stops being updated if/when wrapping is enabled.

Thanks for the tip. I'll try 'em out, I didn't think of them because they said

for non-UI text

However the changelog said they did - I'll try and report back!

To clarify, here's a small and big one side to side:

Ideally, I feed text in and the frame adjusts itself to the size.

(1 edit)

Hi! First of all, thanks for STM - it saved me hours. :D

I am using the uGUI flavor of STM. I am trying to do dialog textboxes where my frame shrinks if the text is small enough (in length), or grows in height once it reaches a maximum width and makes the text wrap. I hope that makes sense.


I can achieve this relatively easily with uGUI by having this setup (which consists of Horizontal Layouts and Content Size Fitters) but I noticed that STM wasn't actually getting its values driven by these components.

That's fine, I thought, I'll just implement the wrapping myself. I have it working, except for one last detail. Here's how I am changing my text:

private void OnDialoguerTextPhase(DialoguerTextData data) {
    RectTransform dialogBoxTexTransform = (RectTransform) DialogBoxText.gameObject.transform;
    DialogBox.SetActive(true);
    DialogBoxText.wrapText = false;
    DialogBoxText.Text = LocalizationManager.GetTermTranslation(data.text);
    if (dialogBoxTexTransform.sizeDelta.x > 500) {
        DialogBoxText.wrapText = true;
        DialogBoxText.Rebuild();
        dialogBoxTexTransform.sizeDelta = new Vector2(500, DialogBoxText.textMesh.bounds.size.y);
    }
}

The problem here is that DialogBoxText.textMesh.bounds  seems to be set to the old bounds, even if I call Rebuild(). It gets updated after two calls to that method.

I've looked through the docs and couldn't find anything of help there... Maybe looping through the characters and identifying the actual mesh size? Do you have any advice on how to make this work?

Thanks again for an awesome asset! :D