Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

TMP_InputField /_Text not rebuilding initially

Discussion in 'Unity UI (uGUI) & TextMesh Pro' started by Julien_at_work, Aug 5, 2019.

  1. Julien_at_work

    Julien_at_work

    Joined:
    Aug 9, 2018
    Posts:
    21
    Hi,
    When updating TMP_InputField.text right after instantiation of a containing prefab, the display of the underlying TMP_Text is not built or updated properly (empty/invisible).
    The editor-inspector shows the correct value in the input field, meaning the value passed through script arrives there, only the scene part is faulty.
    I can trigger a rebuild manually, by toggling for example boldness on and off. After that the value displays; so it must be something related to setting the value right after instantiation.
    Here are the relevant parts of the script that access the TMP_Input, Setup is called right after instantiation, 'input' is the TMP_InputField reference:

    Code (CSharp):
    1.  
    2. ...
    3. public override void Setup(string labelText, RangeFloat? limits, float? initialValue)
    4. {
    5.    SetLabelText(labelText);
    6.    input.characterValidation = TMP_InputField.CharacterValidation.Decimal;
    7.    input.onValueChanged.RemoveListener(OnValueChanged);
    8.    if (limits.HasValue)
    9.    {
    10.        this.limits = limits.Value;
    11.    }
    12.    if (initialValue.HasValue) SetValue(initialValue.Value);
    13.    input.onValueChanged.AddListener(OnValueChanged);
    14. }
    15.  
    16. float GetValue()
    17. {
    18.    float.TryParse(input.text, NumberStyles.Float, CultureInfo.InvariantCulture, out var val);
    19.    return val;
    20. }
    21.  
    22. public override void SetValue(float value)
    23. {
    24.    if (useLimits) limits.ClampValue(ref value);
    25.    var val = value.ToString("0.0", CultureInfo.InvariantCulture);
    26.    input.text = val;
    27. }
    28. ...
    29.  
    Is there something i'm missing?
     
  2. Julien_at_work

    Julien_at_work

    Joined:
    Aug 9, 2018
    Posts:
    21
    Unfortunately this ugly modification makes it work:
    Code (csharp):
    1.  
    2. public override void Setup(string labelText, RangeFloat? limits, float? initialValue)
    3. {
    4.    SetLabelText(labelText);
    5.    input.characterValidation = TMP_InputField.CharacterValidation.Decimal;
    6.    input.onValueChanged.RemoveListener(OnValueChanged);
    7.    if (limits.HasValue)
    8.    {
    9.        this.limits = limits.Value;
    10.    }
    11.    valueToSet = initialValue;
    12.    Invoke(nameof(DelayedSet), Time.deltaTime);
    13. }
    14.  
    15. float? valueToSet;
    16. void DelayedSet()
    17. {
    18.    if (valueToSet.HasValue) SetValue(valueToSet.Value);
    19.    input.onValueChanged.AddListener(OnValueChanged);
    20. }
    21.  
    And more robust if replaced with a delay value that guarantees to skip atleast that one apparrently needed frame
     
  3. Julien_at_work

    Julien_at_work

    Joined:
    Aug 9, 2018
    Posts:
    21