Search Unity

TextMesProUGUI loses material instance properties when saved to prefab

Discussion in 'UGUI & TextMesh Pro' started by Vedran_M, Jan 30, 2020.

  1. Vedran_M

    Vedran_M

    Joined:
    Dec 16, 2019
    Posts:
    14
    Hello,

    I'm having one slightly annoying problem. Instances of TextMeshProUGUI in the scene each have their own instance of default material, so I can change Face/Outline/Underlay/... for each text component separately - and that works nicely. In inspector I can see that it uses material "Font Name SDL Material (Instance)".

    But when I create prefab from those GameObjects from scene, TextMeshProUGUI components in the prefab lose instances of their material and use default material ("Font Name SDL Material"), meaning things like Face, Outline, Underlay etc. are lost.

    Is this a bug, perhaps even bug in Unity prefabs, or is this expected behavior?
    Or am I supposed to save instance of material as asset, and only then I can use it in prefab components?
    Workaround I'm using now is to leave one instance in the scene, and use it for instantiating new 'prefabs' from it.

    I'm using TextMeshPro 2.1.0 preview.3, and Unity 2019.2.12f1.

    Thanks for answering!
     
    Tymianek likes this.
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Since these instance materials are not persistent assets, they don't survive. The prefab and text object only contains a reference to these instances which don't survive.

    Is there a reason why you are creating instances of these materials instead of using persistent Material Presets?

    How many variations of these materials do you need?

    The suggested workflow is to create a set of material preset where these get assigned to the appropriate text objects.

    Often text objects will share some material preset. Swapping of material presets at runtime is common to allow objects to get different visual style but all these presets are typically created in advance.

    It is of course possible to use instance materials but those need to be re-created with the appropriate settings.
     
  3. Vedran_M

    Vedran_M

    Joined:
    Dec 16, 2019
    Posts:
    14
    Thank you for quick response Stephan! Your explanation makes sense.

    Reason why I have so many variations of materials is because I've made a script to import PSD layers directly to Unity scene, and it also imports text exactly as it is in PS, with shadow/outline/thickness/colors - I tried to use TextMeshPro to emulate Photoshop text effects as much as possible. And because artist don't often work very systematically, there are usually many minor variations of those, where outline color or thickness or something else can slightly differ from text to text.
    And honestly even before I automated this process, when I was manually entering text, I would often miss possibility to make some shadow a bit longer or slightly different color, to better fit what artist made. So I would usually fake it with what I have (I don't feel like creating 10 different materials, all with the same outline but slightly different color of it). And sometimes artist would not notice, and sometimes they would - if they had, that means I was too liberate. :)
    And it also happened several times to me and to other programmers that somebody would accidentally change a material, and then all the texts in the game with that material changed. Sometimes it takes a long time to track which of the buttons and texts should or shouldn't have shadow or outline and what was the source of the problem.

    Would it make sense to have option to save those settings saved in material also in TextMeshProUGUI class? Just so we could have many variations of text easily. I know that it would improve my workflow.

    And if I might be that bold, I have another question - do you think it's safe to keep TextMeshProUGUI instances and their instances of material in the scene, without needing to worry that it would be lost between reloading?

    Thanks again for all your help!
     
  4. Vedran_M

    Vedran_M

    Joined:
    Dec 16, 2019
    Posts:
    14
    If anyone wonders what I did in the end - I've created small handler which gets automatically called any time any prefab is being created/updated, and checks for all instances of TextMeshProUGUI inside the prefab, if any of them use instance of material instead of material itself.
    If it detects that - meaning, it detects that text being packed to prefab will lose its face/outline/... - it will display a warning like this to the user:



    If user clicks on Yes, it will search all material instances inside prefab, compare them to find duplicates, and create asset files of unique SDF Materials, and assign those new Asset Materials to game objects. Meaning, user style (outline, face, shadow, ...) will be saved in the prefab.

    This warning will be displayed ONLY if you're trying to pack TextMeshProUGUI components to prefab which use instances of materials instead of material itself. So if user is not doing anything 'wrong', he will never see this warning - and if he does see it, it probably stopped him from putting things to prefab and losing his work.

    Code is in the attachment. Just put it anywhere in the project and it should work automatically.
    Tested with Unity 2019.2.
     

    Attached Files:

    Unifikation likes this.
  5. Unifikation

    Unifikation

    Joined:
    Jan 4, 2023
    Posts:
    1,086
    @Vedran_M you still using Unity? If so, how much further you gotten with TMP?

    Thank you very much for this script, it's extremely helpful!!!