Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

TextMesh Pro Colour Outline, Not Changing via Script, Issue

Discussion in 'Unity UI (uGUI) & TextMesh Pro' started by renman3000, Dec 22, 2017.

  1. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,432
    Hi there,
    Ive been using TMP in my project and I love it, for the most part.

    In regards to changing colours, of a TMP unit, material, outline or face, I am aware this will effect all other instances that share this material. This is fine, however, in code, when I run the program, the color seems to not change as it should.


    Can there be any reason for a material color (outline) for example, not change to the color I set it to, in script, if I have altered it, but hand, in the editor, before run?

    Thanks.
     
  2. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    2,649
    The outlineColor property is of type <Color32> so make sure that you setting and using Color32.

    Also be mindful that properties like outlineColor create an instance of the material. Internally, this colorOutline is simply accessing one of the material properties.
     
  3. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,432

    Thanks for the quick response.

    - I changed the variable from Color to Color32 but the same issue occurs.
    - I deleted and regenerated the object but the same issue occurs (that has worked in the past)
    - this project has been fine for weeks, and this issue just popped up today.

    Please let me know of anything we can do to sort this out.


    Thank you!
     
  4. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    2,649
    This should all be working. What values are you using to set this Color32?

    Also be mindful that the outline itself like underlay uses a shaderkeyword. So perhaps the material that you are using doesn't have those shaderkeywords enabled to begin with.

    While on this topic. Any reason why you are setting the outline color via script instead of using a pre-defined Material Preset? Do you have several text objects all with different outline colors?
     
  5. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,432

    Hi thanks,
    Ive included screenshots of the material setting.


    I am using script for the following reasons.

    - I have 6 worlds, each has their own font color arrangement (face and outline).
    - I use the same scene, gameplay, levels selection, world selection, regardless of which world is open. The objects within, including TMP entities, are instructed to adjust their face and outline colours accordingly.





     
  6. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    2,649
    I can't see from the image where the issue might be. I suspect it is related to how this outline color is being set via scripting.

    Any chance you could share with me a simple repro which you can provide via private link in a PM or simply by submitting a bug report with Unity and providing me with the case #.

    While we figure out the issue together. Here is another suggestion: If you are only using an Outline with or without Underlay, I would switch the shader to use the Mobile Distance Field version which is a bit more efficient than the full distance field that you are using right now.

    In terms of handling of the materials, I would still learn towards using Material Presets which are pre-define for each of those worlds and then assign those material instead of modifying the materials via scripting.

    If modifying those outline via scripting ends up being the best option, I would make sure that I only create one material instance with a given outline and color for each group of text objects. Ie. modifying the outline over several objects results in several instance of essentially the same material which results in several extra draw calls. Whereas at least re-using the same material instance on several text object would be more efficient in terms of draw calls.

    Just for testing...

    Create a new text object of type <TextMeshPro> and add the following script to it. Make sure the text object has a material that is using the normal Distance Field shader and not the Mobile Distance Field since this script doesn't enable the outline keyword.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using TMPro;
    4.  
    5. public class SandBox_08 : MonoBehaviour
    6. {
    7.     private TMP_Text m_TextComponent;
    8.  
    9.     void Awake()
    10.     {
    11.         m_TextComponent = GetComponent<TMP_Text>();
    12.         m_TextComponent.text = "A line of text.";
    13.         m_TextComponent.color = Color.yellow;
    14.         m_TextComponent.outlineWidth = 0.15f;
    15.         m_TextComponent.outlineColor = Color.red;
    16.     }
    17. }
     
    Last edited: Dec 22, 2017
    Hanh likes this.
  7. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,432
    @Stephan-B
    This is how I am setting the colours...


    Font_Color_Holder.ins is an object that exists in each level. This script, function exists on each font object. It manages 2 objects (each has a Text Mesh Pro (Script)). It gathers the colours, from the Font Color Holder and sets them as such....
    Code (csharp):
    1.  
    2.     void set_colors(){
    3.         Color c_face = Font_Color_Holder.ins.c_face [LoadingMng.int_world];
    4.         Color32 c_outline = Font_Color_Holder.ins.c_outline32 [LoadingMng.int_world];
    5.         units [0].faceColor = c_face;
    6.         units [0].outlineColor = c_outline;
    7.         units [1].faceColor = c_outline;
    8.         units [1].outlineColor = c_outline;
    9.  
    10.         print ("OUTLINE COLOR " + c_outline);
    11.  
    12.     }

    -.... again this has been working fine for months, until this afternoon. (Of course the day before release! So yes, it is urgent, so I thank you for the support.).




    * Mobile Distance Field did not work.


    * as for only creating one material per color arrangement, I had chosen this method (shared) to save memory. To create one per arrangement, means at least 12 objects, not too bad on memory I guess.

    So odd as this had been working, like I say.

    * I ran your test, seems to work just fine!
     
  8. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    2,649
    What is the value of that c_outline color?

    Given it is a Color32, each color component should be a byte of value 0 to 255.

    Do you assign a new material to these text objects? Do you assign these new colors just after changing the material?

    What might have changed since the last time you tested this? Did you upgrade Unity? Did you change materials? Any change to those scripts?
     
    Last edited: Dec 22, 2017
  9. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,432
    Not between 0 and 1?

    The print shows (0, 73, 246, 255). This should be a strong blue, I believe.
     
  10. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    2,649
    Is the faceColor changing?

    Do you get the same behavior if you use a different material like any of the materials included with TMP?

    Edit - When you ran the test above, did you try using your materials to see if the behavior is the same?
     
    Last edited: Dec 22, 2017
  11. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,432
    Y

    Yes. The face seems to change fine.
     
  12. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,432
    If you look, you see here two tone manipulation....

    The background colour is purple....
    then there are two text Mesh Pro units in front. One is slightly below and behind in position, to give to two objects (with the same string) a visual depth.


    As you can see the outline is not in effect.


    ??
     
  13. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    2,649
    Do you get the same behavior using any of the font assets included with TextMesh Pro? Make sure you enable Outline (in the material inspector) or switch the shader to the full Distance Field version.
     
    renman3000 likes this.
  14. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,432


    Hi...
    I think I was mistaken.... same effect no matter the material.

    What I see is, in the scene window, is the font turn yellow, with a red outline, however the outline is a rough shape or the character. It is not tight fitting to the font.

    This same outline can't be seen in the Game View.
     
  15. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,432
    ... I think at this point, it may be best to jay create a separate material for each color.

    Unfortunate tho, as it was working!!!

    Anyhow, thank you for your help and the asset!!!
     
  16. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    2,649
    If this was working, it must be something trivial that is being overlooked. You can always quickly submit a Unity bug report and include the project. This way I can take a look at it and hopefully quickly spot what is causing this behavior.
     
    renman3000 likes this.
  17. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,432
    If I had to bet, it will be gone in the morning.
    Cheers!
     
  18. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    2,649
    You know where to find me if you need further assistance.
     
    renman3000 likes this.
  19. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,432
    So I found it!!!!!
    The Material, Outline, was not enabled.
    Done.
     
    Stephan_B likes this.
  20. peterahou

    peterahou

    Joined:
    May 19, 2015
    Posts:
    46
    Sorry about the necropost, but this is definitely still an issue in TextMesh Pro version 1.3.0
    Trying to change outline colour only works the first time in my project, but I figured out that I could work around this limitation by directly accessing the shared font material and toggling the gameobject on/off to force it to update:

    Code (CSharp):
    1. _text.gameObject.SetActive(false);
    2. _text.fontSharedMaterial.SetColor("_OutlineColor", outline);
    3. _text.gameObject.SetActive(true);
     
  21. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    2,649
    In order to force an update of the text object, you should be using the TMP_Text.ForceMeshUpdate() function.

    This should be done whenever you change a property of the text object where you need the object to be updated right away as opposed to waiting until the frame is drawn.

    As to the behavior reported, when accessing the OutlineColor or Width, or any properties of the Material instead of the SharedMaterial, you end up with an instance of that material. So make sure that you are changing the Outline color on the correct material.
     
  22. peterahou

    peterahou

    Joined:
    May 19, 2015
    Posts:
    46
    In this case, ForceMeshUpdate() has no effect. I can only get the outline to change colour by toggling the gameobject on/off.
     
  23. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    2,649
    Are you trying to change the Outline color of a specific text object or for all text objects that share the same material?
     
  24. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    80
    Stephan_B, I'm seeing the same behavior in 2018.3.1f1. While .color may be changed as needed, .outlineColor only changes once. I imagine this is related to the creation of material instances?

    Code (CSharp):
    1. // fails
    2. _UIFixedTooltip.outlineColor = lightTextColor;
    3. _UIFixedTooltip.ForceMeshUpdate();
     
  25. Tony707

    Tony707

    Joined:
    Jun 15, 2015
    Posts:
    37
    Having the same issue on 2018.3.6f1.
     
  26. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    2,649
    Make sure your color is defined as Color32.

    The outlineColor property changes the _OutlineColor property on the material. So make sure you have a valid / correct reference to the material and not an instance.

    Instead of changing the color of the outline via this text object property, you can also use the following.

    Code (csharp):
    1. m_sharedMaterial.SetColor(ShaderUtilities.ID_OutlineColor, new Color(1.0f, 0.8f, 0.0f));
     
    Last edited: Mar 20, 2019
  27. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    80
    Confirmed.
     
  28. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    2,649
    Are you still having the issue?

    Please share the script you are using to change the outline if you still have an issue.
     
  29. stonstad

    stonstad

    Joined:
    Jan 19, 2018
    Posts:
    80
    The Unity color object has implicit conversion to Color32, right?

    Code (CSharp):
    1. public static implicit operator Color32(Color c);
    Assuming this implicit conversion is implemented correctly specifying Color vs Color32 shouldn't make a difference, right? FWIW, I did try using Color32 directly.

    Here's the code that does not work:
    Code (CSharp):
    1. tmpText.outlineColor = new Color(1.0f, 0.0f, 0.0f);
    2. tmpText.ForceMeshUpdate();
    Strangely, this code does work:
    Code (CSharp):
    1. tmpText.color= new Color(1.0f, 0.0f, 0.0f);
    2. tmpText.ForceMeshUpdate();
    This setup occurs before an initial frame is rendered. In some scenarios the text game object is inactive.

    I do have a work around in place by using predefined materials that I switch around based on scene background color.
     
  30. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    2,649
    Can you verify if the active state of the object does affect this in your implementation?
     
  31. tabulatouch

    tabulatouch

    Joined:
    Mar 12, 2015
    Posts:
    8
    Hello,
    I am using 2019.1.2 and have the same issues, cannot change font outline or face colors by code.
     
  32. Milanovicc

    Milanovicc

    Joined:
    Aug 30, 2017
    Posts:
    1
    I had the same problem , this worked for me:

    Code (CSharp):
    1. TextField.gameObject.SetActive(false);
    2. TextField.outlineColor = new Color32(1, 100, 248, 255);
    3. TextField.gameObject.SetActive(true);
    ForceMeshUpdate() didn't work for some reason , so i made it update by setting the gameobject on and off.