Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

Multiline TMP_InputField, auto-resize height while editing.

Discussion in 'UGUI & TextMesh Pro' started by Peeling, Mar 8, 2019.

  1. Peeling

    Peeling

    Joined:
    Nov 10, 2013
    Posts:
    29
    I have been trying to get this to work all day with no success. I have searched for answers, found many, tried them all, had no success. I have tried every combination of layout elements, vertical layouts, content size fitters on every combination of the various elements to no avail.

    I tried hooking into value-changed and manually asking the text component for its preferred size. This did not work because the text component's preferred size ignores its wrapping setting (so hitting return makes the box taller, but wrapping lines does not).

    If I disable the Rect Mask I can see the text overflowing the input field area, but there seems to be no way at all to get 'how big it is' and position the input field around it.

    This seems like such a basic, simple, fundamental thing to want to do; I don't understand why it's... impossible.
     
  2. Peeling

    Peeling

    Joined:
    Nov 10, 2013
    Posts:
    29
    So, forty more minutes of plugging away and a variant on one of the suggested solutions seems to be working - though it's very ugly:

    1. Make the input field object a child of a TMP_Text object. Make sure the parent text object has the same settings as the input field's text object. NOTE: Be sure to open up and set the 'extra settings' margins to match the InputField's TextArea child's left/top/right/bottom values.

    2. Add a Context Size Fitter to the parent Text object, and a Layout Element with an appropriate minimum height (otherwise it'll shrink to nothing). Set the Context Size Fitter's vertical fit to 'Preferred Size'.

    3. Make sure the InputField's rect transform is set to 'stretch', with zero L/T/R/B.

    4. Now write a script that copies the InputField's text to the parent Text, and make sure that gets called On Value Changed.

    Here's the trick that made it work for me: When copying up the text, check to see if the last character is a carriage return ("\n"). If it is, stick another character on the end. This is because the parent text object will silently ignore empty lines at the bottom, but the input field WON'T, which means the two get out of sync and you get text wandering off the top of the field area.

    If you've done everything right (DON'T forget the extra settings margins, otherwise the two text areas will be different sizes and get out of sync), this seems to be a fairly robust (if bloody ugly and inefficient) way of getting an auto-resizing multi-line text input field.

    It even worked when I manually resized the width of the parent text box when it was full of text at runtime, so for now at least I can make some progress.
     
  3. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    4,277
    The TMP Input Field does not currently implement the ILayoutElement interface which is why Layout Components are not working with it.

    I am currently looking into this. I'll reply to this post as soon as I have more information to share.

    P.S. Support for Layout Components should have been added a while back which is why I am looking into this as we speak.
     
  4. Peeling

    Peeling

    Joined:
    Nov 10, 2013
    Posts:
    29
    That's great, thank you!
     
  5. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    4,277
    Here are the changes to the TMP_InputField.cs file required to add support for Layout Components.

    upload_2019-3-9_16-42-4.png

    In order for the Input Field to behave correctly (as far as I can tell based on my limited testing) the following changes to the structure of the parent and child objects is required.



    Give this a try and let me know if it behaves as expected.
     
  6. Peeling

    Peeling

    Joined:
    Nov 10, 2013
    Posts:
    29
    Sorry, I'm only just getting back to this now - trying it ASAP. Thanks!
     
  7. Peeling

    Peeling

    Joined:
    Nov 10, 2013
    Posts:
    29
    My TMP_Inputfield.cs file is MUCH shorter than yours! Am I out of date?
     
  8. Peeling

    Peeling

    Joined:
    Nov 10, 2013
    Posts:
    29
    I made all those changes, and I get this error while typing into the box:

    Trying to add TextMeshPro - InputField Input Caret (TMPro.TMP_SelectionCaret) for graphic rebuild while we are already inside a graphic rebuild loop. This is not supported.
    UnityEngine.RectTransform:set_anchorMin(Vector2)
    TMPro.TMP_InputField:AssignPositioningIfNeeded() (at Library/PackageCache/com.unity.textmeshpro@1.3.0/Scripts/Runtime/TMP_InputField.cs:2743)
    TMPro.TMP_InputField:AdjustRectTransformRelativeToViewport(Vector2, Single, Boolean) (at Library/PackageCache/com.unity.textmeshpro@1.3.0/Scripts/Runtime/TMP_InputField.cs:2999)
    TMPro.TMP_InputField:GenerateCaret(VertexHelper, Vector2) (at Library/PackageCache/com.unity.textmeshpro@1.3.0/Scripts/Runtime/TMP_InputField.cs:2835)
    TMPro.TMP_InputField:OnFillVBO(Mesh) (at Library/PackageCache/com.unity.textmeshpro@1.3.0/Scripts/Runtime/TMP_InputField.cs:2774)
    TMPro.TMP_InputField:UpdateGeometry() (at Library/PackageCache/com.unity.textmeshpro@1.3.0/Scripts/Runtime/TMP_InputField.cs:2719)
    TMPro.TMP_InputField:Rebuild(CanvasUpdate) (at Library/PackageCache/com.unity.textmeshpro@1.3.0/Scripts/Runtime/TMP_InputField.cs:2673)
    UnityEngine.Canvas:SendWillRenderCanvases()
     
  9. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    4,277
    Most likely you forgot to add the Layout Element to the Placeholder and set it to ignore.

    Also these changes most likely will require you use version 1.4.0-preview.3a.
     
  10. Peeling

    Peeling

    Joined:
    Nov 10, 2013
    Posts:
    29
    Thanks :) I'll return to this when I've updated.
     
  11. Peeling

    Peeling

    Joined:
    Nov 10, 2013
    Posts:
    29
    Okay, I've tried with the settings you suggested and the 1.4.0 release. I definitely have all the right components and settings, but as soon as what I'm typing into the box reaches the right hand side I start getting error spam about trying to add the caret for a graphic rebuild while in a rebuild loop.

    Apart from that it almost works - but there's a problem. I want the box to auto-expand horizontally too, but setting the content size fitter to 'preferred' horizontally makes the box zero width and impossible to click on when empty. If I add a layout element to the text to force a minimum width, it seems to interact badly; the text and caret jump around all over the place while I'm typing.
     
  12. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    4,277
    Can you export / provide me a Repro project / scene to take a look at?
     
  13. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    4,277
    The following additional changes should get you the functionality you seek,

    upload_2019-4-2_15-41-26.png

    In terms of the zero width, add a Layout Element to the Input Field parent as seen below. This will enable you to set a minimum size for it.

    upload_2019-4-2_15-42-55.png

     
    Last edited: Apr 2, 2019
  14. ConorArup

    ConorArup

    Joined:
    Feb 15, 2018
    Posts:
    16
    Hi Stephan,

    I've updated to both 1.40 preview 3a and 1.40 and I don't seem any of the code that is shown in the last addition screenshot (lines 4041).

    I also seem to be experiencing a separate issue. I'm trying to contain mine within a ScrollView. I've got it working with the various setups suggested above, however, I have two issues:
    • Firstly, when the input reaches the end of the content area and thus increments past the mask, the scrollbar doesn't update which means you have to keep dragging the scrollbar down to view the latest text. This could be solved by setting the scrollbar value to 0 or 1 onValueChanged but then if you start editing the text in the middle of the content area it would just snap it back down. Do you have any suggestions for fixing this?
      • I'm aware the TextMeshPro InputField has a scrollbar property but I can't seem to get this to work at all? If I put the InputField outside of the ScrollView then there is no mask? I think I'm missing something pretty obvious.
    • Secondly, if I use the mouse scroll wheel while hovering over the input field the content just disappears until I start typing again. Any idea?
     
    Last edited: Apr 18, 2019
  15. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    4,277
    These changes haven't been released yet. They will be included in version 1.4.2 for Unity 2018.3 and 2.0.2 for Unity 2019.2.

    Until the required changes, the input field will be misbehaving with layout components.
     
  16. nikix22

    nikix22

    Joined:
    Jan 16, 2015
    Posts:
    23
    Hi :) I was getting the same error like you described, and I FIXED IT! :)
    My InputField was inside Canvas which had PixelPerfect option checked on.
    When I unchecked PixelPerfect, error disapeared :)
    Greets!
     
unityunity