Search Unity

TextMesh Pro InheritedTextmeshPro class inspector

Discussion in 'UGUI & TextMesh Pro' started by BinaryCats, Jan 4, 2019.

  1. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    317
    Hi,

    I would like to add a
    OnValidate
    call to a
    TextMeshPro
    Component. If I inherit from
    TMPro.TextMeshPro
    , my component does not have the same (custom) inspector that a regular
    TextMeshPro
    would have.

    Is there any way to fix this?

    Thanks
     
  2. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    389
    I have the same problem.
    You can go around it by adding a custom inspector for your type:
    Code (CSharp):
    1. /// <summary>
    2. /// Custom inspector for the enhanced editor
    3. /// </summary>
    4. [CustomEditor(typeof(EnhancedText))]
    5. public class EnhancedText_Editor : TMP_EditorPanel
    6. {
    7.     /// <summary>
    8.     /// Draw the standard custom inspector
    9.     /// </summary>
    10.     override public void OnInspectorGUI()
    11.     {
    12.         base.OnInspectorGUI();
    13.     }
    14. }
    Don't forget to place that class in an editor-only assembly.
    Of course, you'll have to include your own inspector part for your own data.

    Unfortunately, you'll have to do it 100 times if you have 100 types which inherit from a TMP class...
    The 'good' way to fix it would be for Unity to make a very small change. Currently they have that:
    Code (CSharp):
    1. [CustomEditor(typeof(TextMeshPro)), CanEditMultipleObjects]
    2. public class TMP_EditorPanel : TMP_BaseEditorPanel
    That would fix the problem for any type inheriting from the text:
    Code (CSharp):
    1. [CustomEditor(typeof(TextMeshPro), true), CanEditMultipleObjects]
    2. public class TMP_EditorPanel : TMP_BaseEditorPanel
    Of course, it would have to be done for any type in TMP so that nobody will ever have the same problem anymore.
     
    Aligdev and BinaryCats like this.
  3. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    317

    Thank you very much for this I was looking everywhere for the
    TMP_EditorPanel
    .

    I'm not sure why unity don't mark the
    TMP_EditorPanel
    's CustomEditor Attribute with UseForChildren, if they didn't want us to inherit from it, they should have just made it
    sealed

    ¯\_(ツ)_/¯

    Do you (or anybody) know a place for the source code for
    TMP_EditorPanel
    ? it is not on the unity cs reference GitHub

    Thanks again :)
     
  4. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    389
    I guess that either 'UseForChildren' or 'sealed' have been forgotten, if the author sees this thread it probably won't take him more than a couple of hours to fix it in all TextMeshPro.

    As for the source code of 'TMP_EditorPanel', I access it using Unity. I have integrated it as a package using the package manager and in the Unity Editor after 'Assets' there is 'Packages'.
    In it you can find all the packages with their source code.
    I don't know where the sources are on the computer, but I think you can find it in that thread:
    https://forum.unity.com/threads/textmesh-pro-open-source-repository.517314/
     
    BinaryCats likes this.
  5. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    I made the change to both the TMP_EditorPanel and TMP_UiEditorPanel to enable "UseForChildren".
     
    Draco18s and BinaryCats like this.
  6. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    317
    Thanks for the info

    Thanks! :)
     
  7. Gladyon

    Gladyon

    Joined:
    Sep 10, 2015
    Posts:
    389
    Thanks, that will be most helpful.
    By the way, I'm now using TextMeshPro for a few weeks, and I can say that you did a very good job with it!
     
    Stephan_B and BinaryCats like this.
  8. Devs2020Armor

    Devs2020Armor

    Joined:
    May 29, 2019
    Posts:
    1
    So, I created an (for now) empty class that inherits TMP_Text, the associated editor.

    Code (CSharp):
    1. [CustomEditor(typeof(IconLabel))]
    2. public class IconLabelInspector : TMP_EditorPanel
    3. {
    4. }
    5.  
    6. public class IconLabel : TMP_Text
    7. {
    8. }
    The editor displays almost the same as the TMP_Text one, with the following differences:
    1. it doesn't pick up the default font set in the TMP Settings
    2. doesn't show the "Material Preset" property
    3. the "Extra Settings" only shows "Margins"


    When trying to associate a font in my custom inspector, it throws
    NullReferenceException: Object reference not set to an instance of an object

    When expanding "Extra Settings", it throws several
    Undo object may not be null.
    UnityEditor.Undo:RecordObject(Object, String)
    InvalidCastException: Specified cast is not valid.


    Does anyone have a clue whether this is an issue related to the UnityVersion (2019.1.4f1), MacOS or just me being stupid?
     

    Attached Files:

  9. GuoQPro

    GuoQPro

    Joined:
    Sep 9, 2019
    Posts:
    3
    Replacing TMP_EditorPanel with TMP_UiEditorPanel works for me.
     
  10. Frodger

    Frodger

    Joined:
    Oct 7, 2019
    Posts:
    1
    Can u show how to do this?
     
  11. Draco18s

    Draco18s

    Joined:
    Aug 15, 2011
    Posts:
    110
    As I just ran across this thread and the change Stephan made, here's a working example (his UGUI editor's class name was slightly incorrect). TMP_EditorPanel and TMP_EditorPanelUI (not TMP_UiEditorPanel).

    Code (CSharp):
    1.     [CustomEditor(typeof(LocalizedTextUGUI))]
    2.     public class LocalizedTextInspector : TMP_EditorPanelUI
    3.     {
    4.         protected override void OnEnable()
    5.         {
    6.             base.OnEnable(); //important
    7.             m_TextProp = serializedObject.FindProperty("unlocalizedText"); //point the existing text serialized property to my own
    8.         }
    9.     }
    Then an OnValidate method in my subclass does the localization step, which updates the TMP text field (and the cascading side effects, such as updating the render).

    Code (CSharp):
    1.     public class LocalizedTextUGUI : TextMeshProUGUI
    2.     {
    3.         [SerializeField]
    4.         private string unlocalizedText;
    5.  
    6.         protected override void OnValidate()
    7.         {
    8.             base.OnValidate();
    9.             text = Localization.ToLocal(unlocalizedText); //Localization class not shown
    10.         }
    11.     }
    There's some other hijinks to get Create -> Localized Text to show up in the hierarchy menu, but it's documented here. The only tricky thing was dealing with the "no canvas in scene" case and making sure to add all game objects you create (see: the "no canvas in scene" case) to the undo stack.

    Thanks Stephan for this change, I tore my hair out several years ago trying to do this very same thing and it was a breeze today as a result.

    Demo: