Search Unity

TextMesh Pro TMP alignment messed up after upgrade to Unity 2018.4 LTS

Discussion in 'UGUI & TextMesh Pro' started by mh114, Aug 27, 2019.

  1. mh114

    mh114

    Joined:
    Nov 17, 2013
    Posts:
    295
    Hi Stephan, I've been upgrading our projects from 2017.4 LTS to 2018.1, then to 2018.2, and now finally to 2018.4. Originally we were using the source version of TMP, so I went with the GUID conversion process and everything seemed to work fine in 2018.2. After upgrading to 2018.4, it seems many of our TMP texts are aligned wrong. It may be related to prefabs, but may be not (I only checked a few misaligned texts so far, those all happened to be prefabs, but there are probably lots of misaligned cases).

    It seems I can fix the alignment by modifying the settings, but as we have a large game with TMP texts everywhere, going through them all is going to be painful. So I was thinking of trying to find the problematic instances and fixing patching them with some kind of processing outside Unity, perhaps.

    Have you seen any issues with alignment, any ideas? I noticed in one prefab text was supposed to be centered both horizontally and vertically, the relevant data before touching it is:
    m_textAlignment: 5
    m_isAlignmentEnumConverted: 0


    After I fix the alignment in the prefab, the asset reserializes, removing those two lines and adding:
    m_textAlignment: 514

    I was thinking maybe searching for those old m_textAlignment: lines, and replacing them with the correct bitmask of the new alignment, but I'm not sure if all the misaligned cases are similar (yet, as I haven't looked at it too much).

    EDIT: I can still go back to 2018.2 if it helps to do some processing back there, with TMP 1.3.0. In 2018.4 I have TMP 1.4.1.
     
  2. mh114

    mh114

    Joined:
    Nov 17, 2013
    Posts:
    295
    Seems indeed that the broken TMP prefabs are older stuff in our project, newer prefabs appear with correct alignment. It is likely related to the old alignment properties, perhaps they were automatically converted up-to TMP version 1.3.0 but no longer are?

    Any ideas, @Stephan_B ? My current plan is to identify the old serialized lines and search & replace them with new line where the alignment is a bitmask, but that may be also problematic because the intended alignments are different depending on the case..
     
  3. mh114

    mh114

    Joined:
    Nov 17, 2013
    Posts:
    295
    Progress! I went back to 2018.2 and TMP 1.3.0, wrote a script to inspect all our assets, find their TMP components and detect if they are using the old alignment values (numbers 0-23 I believe). Using TMP_Compatibility I can convert them, so hopefully when I change the alignment, save the asset and then later import into 2018.4 / TMP 1.4.1 it should work. :)
     
  4. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The removal of the TMP_Compatibility.cs and conversion of the old style going back to 5.x, was an oversight on my part. This conversion will be back in the next release and properly convert to the new format and avoid these issues. Sorry about that.
     
    mh114 likes this.
  5. mh114

    mh114

    Joined:
    Nov 17, 2013
    Posts:
    295
    No problem, glad to know it will be sorted out. Can you guesstimate when the new release drops?

    I think I'll go ahead with my ad-hoc conversion for the time being, though, unless the fixed release is imminent.
     
  6. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Trying to get the next release out within the next 10 - 14 days. Hopefully, I don't run / get reports of anything major and I can stick to this.
     
    mh114 likes this.
  7. pdafedar

    pdafedar

    Joined:
    Apr 17, 2018
    Posts:
    9
    Hey @Stephan_B , We are also facing similar TMP alignment issues after upgrading our Unity from 2018.2.x to 2018.4.8f1. It's kind of unexpected to see things are messed up after doing the upgrade.
    Can you tell us at least in which version we can expect this fix? or is it already fixed in newer version 2018.4.9f1? I would appreciate your confirmation on this fix.
     
  8. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    This will be fixed in the next release which should be available later this week.
     
  9. anp

    anp

    Joined:
    Jul 1, 2015
    Posts:
    7
  10. ortin

    ortin

    Joined:
    Jan 13, 2013
    Posts:
    221
  11. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Ran into some issues with the new package release automation / publishing process which I now (as of this post) appear to have resolved.

    If this wasn't the first time going through the new publishing process, I would have released the package over the weekend but I think it is best I do some additional testing and get this out on Monday.

    I'll provide an update if I run into any new unforeseen issue. Otherwise, I'll update / create a new sticky post announcing the new release.
     
  12. pdafedar

    pdafedar

    Joined:
    Apr 17, 2018
    Posts:
    9
    Hey @Stephan_B , Any update available on the new TMPro package release?
    We are not able to see the new version yet. This is something critical and directly impacting our production timeline. We thought LTS will be the stable version among all Unity versions out there. But with this new TMPro package most of our \ texts pushed to right alignment or more precisely, they pushed to right extreme rect bound.

    Please keep us updated here as soon as the new release is public.
     
  13. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Ran into an overseen issue with the new package release automation system. Should be able to resolve that with the Package Manager Team tomorrow and then get the new release out shortly thereafter.

    In terms of the alignment issue, it is something that affects older projects coming from much older versions of Unity. At least that should be the only case.
     
  14. pdafedar

    pdafedar

    Joined:
    Apr 17, 2018
    Posts:
    9
    @Stephan_B Yes, you are right. It is mostly happening for some of the legacy contents created in Unity 5.6 or lesser.
    Do you think your new package update will fix that problem completely? or do we need to make any manual changes on top of it?
     
  15. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The new package (version 1.5.x & 2.1.x) should handle loading / converting from an old project correctly.

    I'll do additional testing with an old project incorrectly converted in 1.4.1 into the new version which if necessary I think could be handled as well but not sure yet.
     
  16. pdafedar

    pdafedar

    Joined:
    Apr 17, 2018
    Posts:
    9
    @Stephan_B , New TMPro Package is still not available in the package manager of Unity 2018.4.8 LTS! Can you please give us the update soon. It's more than a week now waiting for the fix and still, we are not sure when we can expect it further.
     
  17. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    In final testing / including verifying alignment handling from Unity 4.x to early 5.x cycle to newer handling introduced when the TMP_Text class was added in later 5.x cycle through 1.4.0 to 1.4.1 which resulted in the alignment issue on projects from the Legacy cycle from 4.x to early 5.x.

    I expect to release the package tomorrow unless I run into something major.

    I will provide a separate update on the alignment handling later tonight.

    Update
    Tested the old alignment going back to 5.4 which used enum values between 0 - 23 and loading those scenes / objects in the latest release worked as expected.|

    Also tested an old scene with 5.4 alignment and saved it in 1.4.1 where alignment was broken. Upgraded the package to version 1.5.0 and the alignment was then correct.

    So this looks fine for the next release.
     
    Last edited: Sep 27, 2019
    anp likes this.
  18. pdafedar

    pdafedar

    Joined:
    Apr 17, 2018
    Posts:
    9
    Excellent! Can't wait to try out the new release. Thank you @Stephan_B . Kindly update here once it's live.
     
    anp likes this.
  19. anp

    anp

    Joined:
    Jul 1, 2015
    Posts:
    7
    +1 Really need that new release ASAP. Thank you @Stephan_B for all the updates here!
     
  20. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    See top sticky post ;)

    Let me know how this behaves in the new release.
     
  21. anp

    anp

    Joined:
    Jul 1, 2015
    Posts:
    7
    @Stephan_B the text alignment issue is fixed with the new 1.5.0 TMPro package version in 2018.4! Thank you so much :)
     
    Stephan_B likes this.
  22. pdafedar

    pdafedar

    Joined:
    Apr 17, 2018
    Posts:
    9
    @Stephan_B ; Yes, 1.5.0 has brought back old alignment. Thanks for the update.

    Apparently, we did create one in-house tool, which did the same fix a week back your 1.5.0 release.


    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System;
    4. using System.IO;
    5. using System.Text;
    6. using System.Linq;
    7. using System.Collections;
    8. using System.Collections.Generic;
    9. using TMPro.EditorUtilities;
    10.  
    11. namespace TMPro.Experimental
    12. {
    13.     /// <summary>
    14.     /// Data structure containing the target and replacement fileIDs and GUIDs which will require remapping from previous version of TextMesh Pro to the new TextMesh Pro UPM package.
    15.     /// </summary>
    16.     [System.Serializable]
    17.     struct AssetConversionRecord
    18.     {
    19.         public string referencedResource;
    20.         public string target;
    21.         public string replacement;
    22.     }
    23.  
    24.  
    25.     /// <summary>
    26.     /// Data structure containing a list of target and replacement fileID and GUID requiring remapping from previous versions of TextMesh Pro to the new TextMesh Pro UPM package.
    27.     /// This data structure is populated with the data contained in the PackageConversionData.json file included in the package.
    28.     /// </summary>
    29.     [System.Serializable]
    30.     class AssetConversionData
    31.     {
    32.         public List<AssetConversionRecord> assetRecords;
    33.     }
    34.  
    35.  
    36.     public class TMPro_AlignementFixer : EditorWindow
    37.     {
    38.         // Create Sprite Asset Editor Window
    39.         [MenuItem("Window/TextMeshPro/Alignment Fixer", false, 2100)]
    40.         static void ShowConverterWindow()
    41.         {
    42.             var window = GetWindow<TMPro_AlignementFixer>();
    43.             window.titleContent = new GUIContent("Alignment Fixer");
    44.             window.Focus();
    45.         }
    46.  
    47.         private static HashSet<Type> m_IgnoreAssetTypes = new HashSet<Type>()
    48.         {
    49.             typeof(AnimatorOverrideController),
    50.             typeof(AudioClip),
    51.             typeof(AvatarMask),
    52.             typeof(ComputeShader),
    53.             typeof(Cubemap),
    54.             typeof(DefaultAsset),
    55.             typeof(Flare),
    56.             typeof(Font),
    57.             typeof(GUISkin),
    58.             typeof(HumanTemplate),
    59.             typeof(LightingDataAsset),
    60.             typeof(Mesh),
    61.             typeof(MonoScript),
    62.             typeof(PhysicMaterial),
    63.             typeof(PhysicsMaterial2D),
    64.             typeof(RenderTexture),
    65.             typeof(Shader),
    66.             typeof(TerrainData),
    67.             typeof(TextAsset),
    68.             typeof(Texture2D),
    69.             typeof(Texture2DArray),
    70.             typeof(Texture3D),
    71.             typeof(UnityEditor.Animations.AnimatorController),
    72.             typeof(UnityEditorInternal.AssemblyDefinitionAsset),
    73.             typeof(UnityEngine.AI.NavMeshData),
    74.             typeof(UnityEngine.Tilemaps.Tile),
    75.             typeof(UnityEngine.U2D.SpriteAtlas),
    76.             typeof(UnityEngine.Video.VideoClip),
    77.         };
    78.  
    79.         struct AssetFileRecord
    80.         {
    81.             public string assetFilePath;
    82.             public string assetMetaFilePath;
    83.  
    84.             public AssetFileRecord(string filePath, string metaFilePath)
    85.             {
    86.                 this.assetFilePath = filePath;
    87.                 this.assetMetaFilePath = metaFilePath;
    88.             }
    89.         }
    90.  
    91.         private static string m_ProjectPath;
    92.         private static bool m_IsAlreadyScanningProject;
    93.         private static bool m_CancelScanProcess;
    94.         private static string k_ProjectScanReportDefaultText = "<color=#FFFF80><b>Project Scan Results</b></color>\n";
    95.         private static string k_ProjectScanLabelPrefix = "Scanning: ";
    96.         private static string m_ProjectScanResults = string.Empty;
    97.         private static Vector2 m_ProjectScanResultScrollPosition;
    98.         private static float m_ProgressPercentage = 0;
    99.  
    100.         private static int m_ScanningTotalFiles;
    101.         private static int m_RemainingFilesToScan;
    102.         private static int m_ScanningCurrentFileIndex;
    103.         private static string m_ScanningCurrentFileName;
    104.  
    105.         private static AssetConversionData m_ConversionData;
    106.  
    107.         private static List<AssetFileRecord> assetFileRecord = new List<AssetFileRecord>();
    108.  
    109.  
    110.         void OnEnable()
    111.         {
    112.             // Set Editor Window Size
    113.             SetEditorWindowSize();
    114.  
    115.             m_ProjectScanResults = k_ProjectScanReportDefaultText;
    116.         }
    117.  
    118.  
    119.         void OnGUI()
    120.         {
    121.             GUILayout.BeginVertical();
    122.             {
    123.                 // Scan project files and resources
    124.                 GUILayout.BeginVertical(EditorStyles.helpBox);
    125.                 {
    126.                     GUILayout.Label("Scan Project Files", EditorStyles.boldLabel);
    127.                     GUILayout.Space(5f);
    128.  
    129.                     GUI.enabled = m_IsAlreadyScanningProject == false ? true : false;
    130.                     if (GUILayout.Button("Scan Project Files"))
    131.                     {
    132.                         m_CancelScanProcess = false;
    133.  
    134.                         // Make sure Asset Serialization mode is set to ForceText and Version Control mode to Visible Meta Files.
    135.                         if (CheckProjectSerializationAndSourceControlModes() == true)
    136.                         {
    137.                             m_ProjectPath = Path.GetFullPath("Assets/..");
    138.                             TMP_EditorCoroutine.StartCoroutine(ScanProjectFiles());
    139.                         }
    140.                         else
    141.                         {
    142.                             EditorUtility.DisplayDialog("Project Settings Change Required", "In menu options \"Edit - Project Settings - Editor\", please change Asset Serialization Mode to ForceText and Source Control Mode to Visible Meta Files.", "OK", string.Empty);
    143.                         }
    144.                     }
    145.                     GUI.enabled = true;
    146.  
    147.                     // Display progress bar
    148.                     Rect rect = GUILayoutUtility.GetRect(0f, 20f, GUILayout.ExpandWidth(true));
    149.                     EditorGUI.ProgressBar(rect, m_ProgressPercentage, "Scan Progress (" + m_ScanningCurrentFileIndex + "/" + m_ScanningTotalFiles + ")");
    150.  
    151.                     // Display cancel button and name of file currently being scanned.
    152.                     if (m_IsAlreadyScanningProject)
    153.                     {
    154.                         Rect cancelRect = new Rect(rect.width - 20, rect.y + 2, 20, 16);
    155.                         if (GUI.Button(cancelRect, "X"))
    156.                         {
    157.                             m_CancelScanProcess = true;
    158.                         }
    159.                         GUILayout.Label(k_ProjectScanLabelPrefix + m_ScanningCurrentFileName, TMP_UIStyleManager.label);
    160.                     }
    161.                     else
    162.                         GUILayout.Label(string.Empty);
    163.  
    164.                     GUILayout.Space(5);
    165.  
    166.                     // Creation Feedback
    167.                     GUILayout.BeginVertical(TMP_UIStyleManager.textAreaBoxWindow, GUILayout.ExpandHeight(true));
    168.                     {
    169.                         m_ProjectScanResultScrollPosition = EditorGUILayout.BeginScrollView(m_ProjectScanResultScrollPosition, GUILayout.ExpandHeight(true));
    170.                         EditorGUILayout.LabelField(m_ProjectScanResults, TMP_UIStyleManager.label);
    171.                         EditorGUILayout.EndScrollView();
    172.                     }
    173.                     GUILayout.EndVertical();
    174.                     GUILayout.Space(5f);
    175.                 }
    176.                 GUILayout.EndVertical();
    177.  
    178.                 // Scan project files and resources
    179.                 GUILayout.BeginVertical(EditorStyles.helpBox);
    180.                 {
    181.                     GUILayout.Label("Save Modified Project Files", EditorStyles.boldLabel);
    182.                     GUILayout.Label("Pressing the <i>Save Modified Project Files</i> button will update the files in the <i>Project Scan Results</i> listed above. <color=#FFFF80>Please make sure that you have created a backup of your project first</color> as these file modifications are permanent and cannot be undone.", TMP_UIStyleManager.label);
    183.                     GUILayout.Space(5f);
    184.  
    185.                     GUI.enabled = m_IsAlreadyScanningProject == false && assetFileRecord.Count > 0 ? true : false;
    186.                     if (GUILayout.Button("Save Modified Project Files"))
    187.                     {
    188.                         TMP_EditorCoroutine.StartCoroutine(UpdateProjectFiles());
    189.                     }
    190.                     GUILayout.Space(10f);
    191.                 }
    192.                 GUILayout.EndVertical();
    193.  
    194.             }
    195.             GUILayout.EndVertical();
    196.             GUILayout.Space(5f);
    197.         }
    198.  
    199.         void OnInspectorUpdate()
    200.         {
    201.             Repaint();
    202.         }
    203.  
    204.  
    205.         /// <summary>
    206.         /// Limits the minimum size of the editor window.
    207.         /// </summary>
    208.         void SetEditorWindowSize()
    209.         {
    210.             EditorWindow editorWindow = this;
    211.  
    212.             Vector2 currentWindowSize = editorWindow.minSize;
    213.  
    214.             editorWindow.minSize = new Vector2(Mathf.Max(200, currentWindowSize.x), Mathf.Max(140, currentWindowSize.y));
    215.         }
    216.  
    217.         /// <summary>
    218.         ///
    219.         /// </summary>
    220.         /// <param name="filePath"></param>
    221.         /// <returns></returns>
    222.         private static bool ShouldIgnoreFile(string filePath)
    223.         {
    224.             string fileExtension = Path.GetExtension(filePath);
    225.             Type fileType = AssetDatabase.GetMainAssetTypeAtPath(filePath);
    226.  
    227.             if (m_IgnoreAssetTypes.Contains(fileType))
    228.                 return true;
    229.  
    230.             // Exclude FBX
    231.             if (fileType == typeof(GameObject) && fileExtension.ToLower() == ".fbx") { return true; }
    232.             return false;
    233.         }
    234.  
    235.         private IEnumerator ScanProjectFiles()
    236.         {
    237.             m_IsAlreadyScanningProject = true;
    238.             string packageFullPath = EditorUtilities.TMP_EditorUtility.packageFullPath;
    239.  
    240.             // List containing assets that have been modified.
    241.             m_ProjectScanResults = k_ProjectScanReportDefaultText;
    242.             assetFileRecord.Clear();
    243.             m_ProgressPercentage = 0;
    244.  
    245.             // Get list of GUIDs for assets that might contain references to previous GUIDs that require updating.
    246.             string searchFolder = "Assets";
    247.             string[] guids = AssetDatabase.FindAssets("t:prefab", new string[] { searchFolder }).Distinct().ToArray();
    248.  
    249.             k_ProjectScanLabelPrefix = "<b>Scanning:</b> ";
    250.             m_ScanningTotalFiles = guids.Length;
    251.             m_ScanningCurrentFileIndex = 0;
    252.  
    253.             List<AssetFileRecord> projectFilesToScan = new List<AssetFileRecord>();
    254.  
    255.             foreach (var guid in guids)
    256.             {
    257.                 if (m_CancelScanProcess)
    258.                     break;
    259.  
    260.                 string assetFilePath = AssetDatabase.GUIDToAssetPath(guid);
    261.  
    262.                 m_ScanningCurrentFileIndex += 1;
    263.                 m_ScanningCurrentFileName = assetFilePath;
    264.                 m_ProgressPercentage = (float)m_ScanningCurrentFileIndex / m_ScanningTotalFiles;
    265.  
    266.                 // Filter out file types we have no interest in searching
    267.                 if (ShouldIgnoreFile(assetFilePath))
    268.                     continue;
    269.  
    270.                 Debug.Log("Scanning:" + assetFilePath);
    271.  
    272.                 var asset = AssetDatabase.LoadAssetAtPath<GameObject>(assetFilePath);
    273.                 var prefab = PrefabUtility.InstantiatePrefab(asset) as GameObject;
    274.                 var tmproUGUIComponents = prefab.GetComponentsInChildren<TextMeshProUGUI>(true);
    275.  
    276.                 var tmproComponents = prefab.GetComponentsInChildren<TextMeshPro>(true);
    277.  
    278.                 if (tmproUGUIComponents.Length > 0 || tmproComponents.Length > 0)
    279.                 {
    280.                     string assetMetaFilePath = AssetDatabase.GetTextMetaFilePathFromAssetPath(assetFilePath);
    281.                     projectFilesToScan.Add(new AssetFileRecord(assetFilePath, assetMetaFilePath));
    282.                     m_ProjectScanResults += $"{assetFilePath}\n";
    283.                 }
    284.                 DestroyImmediate(prefab);
    285.                 //Resources.UnloadAsset(asset);
    286.  
    287.                 yield return null;
    288.             }
    289.             assetFileRecord = projectFilesToScan;
    290.             Resources.UnloadUnusedAssets();
    291.             m_IsAlreadyScanningProject = false;
    292.         }
    293.  
    294.         /// <summary>
    295.         /// Check project Asset Serialization and Source Control modes
    296.         /// </summary>
    297.         private static bool CheckProjectSerializationAndSourceControlModes()
    298.         {
    299.             // Check Project Asset Serialization and Visible Meta Files mode.
    300.             if (EditorSettings.serializationMode != SerializationMode.ForceText || EditorSettings.externalVersionControl != "Visible Meta Files")
    301.             {
    302.                 return false;
    303.             }
    304.  
    305.             return true;
    306.         }
    307.  
    308.         private IEnumerator UpdateProjectFiles()
    309.         {
    310.             List<string> lines = new List<string>();
    311.             m_ScanningTotalFiles = assetFileRecord.Count;
    312.             foreach (var assetfile in assetFileRecord)
    313.             {
    314.                 string path = Path.Combine(Application.dataPath, "..", assetfile.assetFilePath);
    315.                 if (!File.Exists(path))
    316.                 {
    317.                     Debug.LogError($"Path:{path} doesn't exist!");
    318.                     continue;
    319.                 }
    320.  
    321.                 lines.AddRange(File.ReadAllLines(path));
    322.                 var newLines = new List<string>();
    323.                 int lineIndex = 0;
    324.                 foreach(var line in lines)
    325.                 {
    326.                     lineIndex++;
    327.                     if (line.Contains("m_textAlignment"))
    328.                     {
    329.                         Debug.Log("Old :" + line);
    330.                         int index = line.IndexOf(":", StringComparison.Ordinal);
    331.                         string value = line.Substring(index + 1, line.Length - (index + 1));
    332.                         int oldValue = int.Parse(value);
    333.                         int newValue = ConvertOldToNewTextAlignment(oldValue);
    334.                         string newLine = line.Replace(oldValue.ToString(), newValue.ToString());
    335.                         Debug.Log("Old :" + newLine);
    336.                         newLines.Add(newLine);
    337.                     }
    338.                     else
    339.                     {
    340.                         newLines.Add(line);
    341.                     }
    342.                 }
    343.                 File.WriteAllLines(path, newLines.ToArray());
    344.                 lines.Clear();
    345.                 newLines.Clear();
    346.                 newLines = null;
    347.  
    348.                 m_ScanningCurrentFileIndex += 1;
    349.                 m_ProgressPercentage = (float)m_ScanningCurrentFileIndex / m_ScanningTotalFiles;
    350.  
    351.                 yield return null;
    352.             }
    353.             AssetDatabase.Refresh();
    354.  
    355.             m_ProgressPercentage = 0;
    356.             m_ProjectScanResults = k_ProjectScanReportDefaultText;
    357.         }
    358.  
    359.         #region Text Alignment Converter.
    360.  
    361.         public enum TextAlignmentOptions_old
    362.         {
    363.             TopLeft = 0, Top = 1, TopRight = 2, TopJustified = 3,
    364.             Left = 4, Center = 5, Right = 6, Justified = 7,
    365.             BottomLeft = 8, Bottom = 9, BottomRight = 10, BottomJustified = 11,
    366.             BaselineLeft = 12, Baseline = 13, BaselineRight = 14, BaselineJustified = 15,
    367.             MidlineLeft = 16, Midline = 17, MidlineRight = 18, MidlineJustified = 19
    368.         };
    369.  
    370.         public enum TextAlignmentOptions
    371.         {
    372.             TopLeft = _HorizontalAlignmentOptions.Left | _VerticalAlignmentOptions.Top,
    373.             Top = _HorizontalAlignmentOptions.Center | _VerticalAlignmentOptions.Top,
    374.             TopRight = _HorizontalAlignmentOptions.Right | _VerticalAlignmentOptions.Top,
    375.             TopJustified = _HorizontalAlignmentOptions.Justified | _VerticalAlignmentOptions.Top,
    376.             TopFlush = _HorizontalAlignmentOptions.Flush | _VerticalAlignmentOptions.Top,
    377.             TopGeoAligned = _HorizontalAlignmentOptions.Geometry | _VerticalAlignmentOptions.Top,
    378.  
    379.             Left = _HorizontalAlignmentOptions.Left | _VerticalAlignmentOptions.Middle,
    380.             Center = _HorizontalAlignmentOptions.Center | _VerticalAlignmentOptions.Middle,
    381.             Right = _HorizontalAlignmentOptions.Right | _VerticalAlignmentOptions.Middle,
    382.             Justified = _HorizontalAlignmentOptions.Justified | _VerticalAlignmentOptions.Middle,
    383.             Flush = _HorizontalAlignmentOptions.Flush | _VerticalAlignmentOptions.Middle,
    384.             CenterGeoAligned = _HorizontalAlignmentOptions.Geometry | _VerticalAlignmentOptions.Middle,
    385.  
    386.             BottomLeft = _HorizontalAlignmentOptions.Left | _VerticalAlignmentOptions.Bottom,
    387.             Bottom = _HorizontalAlignmentOptions.Center | _VerticalAlignmentOptions.Bottom,
    388.             BottomRight = _HorizontalAlignmentOptions.Right | _VerticalAlignmentOptions.Bottom,
    389.             BottomJustified = _HorizontalAlignmentOptions.Justified | _VerticalAlignmentOptions.Bottom,
    390.             BottomFlush = _HorizontalAlignmentOptions.Flush | _VerticalAlignmentOptions.Bottom,
    391.             BottomGeoAligned = _HorizontalAlignmentOptions.Geometry | _VerticalAlignmentOptions.Bottom,
    392.  
    393.             BaselineLeft = _HorizontalAlignmentOptions.Left | _VerticalAlignmentOptions.Baseline,
    394.             Baseline = _HorizontalAlignmentOptions.Center | _VerticalAlignmentOptions.Baseline,
    395.             BaselineRight = _HorizontalAlignmentOptions.Right | _VerticalAlignmentOptions.Baseline,
    396.             BaselineJustified = _HorizontalAlignmentOptions.Justified | _VerticalAlignmentOptions.Baseline,
    397.             BaselineFlush = _HorizontalAlignmentOptions.Flush | _VerticalAlignmentOptions.Baseline,
    398.             BaselineGeoAligned = _HorizontalAlignmentOptions.Geometry | _VerticalAlignmentOptions.Baseline,
    399.  
    400.             MidlineLeft = _HorizontalAlignmentOptions.Left | _VerticalAlignmentOptions.Geometry,
    401.             Midline = _HorizontalAlignmentOptions.Center | _VerticalAlignmentOptions.Geometry,
    402.             MidlineRight = _HorizontalAlignmentOptions.Right | _VerticalAlignmentOptions.Geometry,
    403.             MidlineJustified = _HorizontalAlignmentOptions.Justified | _VerticalAlignmentOptions.Geometry,
    404.             MidlineFlush = _HorizontalAlignmentOptions.Flush | _VerticalAlignmentOptions.Geometry,
    405.             MidlineGeoAligned = _HorizontalAlignmentOptions.Geometry | _VerticalAlignmentOptions.Geometry,
    406.  
    407.             CaplineLeft = _HorizontalAlignmentOptions.Left | _VerticalAlignmentOptions.Capline,
    408.             Capline = _HorizontalAlignmentOptions.Center | _VerticalAlignmentOptions.Capline,
    409.             CaplineRight = _HorizontalAlignmentOptions.Right | _VerticalAlignmentOptions.Capline,
    410.             CaplineJustified = _HorizontalAlignmentOptions.Justified | _VerticalAlignmentOptions.Capline,
    411.             CaplineFlush = _HorizontalAlignmentOptions.Flush | _VerticalAlignmentOptions.Capline,
    412.             CaplineGeoAligned = _HorizontalAlignmentOptions.Geometry | _VerticalAlignmentOptions.Capline
    413.         };
    414.  
    415.         public enum _HorizontalAlignmentOptions
    416.         {
    417.             Left = 0x1, Center = 0x2, Right = 0x4, Justified = 0x8, Flush = 0x10, Geometry = 0x20
    418.         }
    419.  
    420.         public enum _VerticalAlignmentOptions
    421.         {
    422.             Top = 0x100, Middle = 0x200, Bottom = 0x400, Baseline = 0x800, Geometry = 0x1000, Capline = 0x2000,
    423.         }
    424.  
    425.         private static int ConvertOldToNewTextAlignment(int oldValue)
    426.         {
    427.             if (oldValue < 0 || oldValue > (int)TextAlignmentOptions_old.MidlineJustified)
    428.                 return oldValue;
    429.  
    430.  
    431.             TextAlignmentOptions_old textAlignmentOld = (TextAlignmentOptions_old) oldValue;
    432.  
    433.             //Debug.Log("Old :" + textAlignmentOld.ToString());
    434.  
    435.             TextAlignmentOptions textAlignmentNew = TextAlignmentOptions.Midline;
    436.             switch (textAlignmentOld)
    437.             {
    438.                 case TextAlignmentOptions_old.TopLeft:
    439.                     textAlignmentNew = TextAlignmentOptions.TopLeft;
    440.                     break;
    441.                 case TextAlignmentOptions_old.Top:
    442.                     textAlignmentNew = TextAlignmentOptions.Top;
    443.                     break;
    444.                 case TextAlignmentOptions_old.TopRight:
    445.                     textAlignmentNew = TextAlignmentOptions.TopRight;
    446.                     break;
    447.                 case TextAlignmentOptions_old.TopJustified:
    448.                     textAlignmentNew = TextAlignmentOptions.TopJustified;
    449.                     break;
    450.                 case TextAlignmentOptions_old.Left:
    451.                     textAlignmentNew = TextAlignmentOptions.Left;
    452.                     break;
    453.                 case TextAlignmentOptions_old.Center:
    454.                     textAlignmentNew = TextAlignmentOptions.Center;
    455.                     break;
    456.                 case TextAlignmentOptions_old.Right:
    457.                     textAlignmentNew = TextAlignmentOptions.Right;
    458.                     break;
    459.                 case TextAlignmentOptions_old.Justified:
    460.                     textAlignmentNew = TextAlignmentOptions.Justified;
    461.                     break;
    462.                 case TextAlignmentOptions_old.BottomLeft:
    463.                     textAlignmentNew = TextAlignmentOptions.BottomLeft;
    464.                     break;
    465.                 case TextAlignmentOptions_old.Bottom:
    466.                     textAlignmentNew = TextAlignmentOptions.Bottom;
    467.                     break;
    468.                 case TextAlignmentOptions_old.BottomRight:
    469.                     textAlignmentNew = TextAlignmentOptions.BottomRight;
    470.                     break;
    471.                 case TextAlignmentOptions_old.BottomJustified:
    472.                     textAlignmentNew = TextAlignmentOptions.BottomJustified;
    473.                     break;
    474.                 case TextAlignmentOptions_old.BaselineLeft:
    475.                     textAlignmentNew = TextAlignmentOptions.BaselineLeft;
    476.                     break;
    477.                 case TextAlignmentOptions_old.Baseline:
    478.                     textAlignmentNew = TextAlignmentOptions.Baseline;
    479.                     break;
    480.                 case TextAlignmentOptions_old.BaselineRight:
    481.                     textAlignmentNew = TextAlignmentOptions.BaselineRight;
    482.                     break;
    483.                 case TextAlignmentOptions_old.BaselineJustified:
    484.                     textAlignmentNew = TextAlignmentOptions.BaselineJustified;
    485.                     break;
    486.                 case TextAlignmentOptions_old.MidlineLeft:
    487.                     textAlignmentNew = TextAlignmentOptions.MidlineLeft;
    488.                     break;
    489.                 case TextAlignmentOptions_old.Midline:
    490.                     textAlignmentNew = TextAlignmentOptions.Midline;
    491.                     break;
    492.                 case TextAlignmentOptions_old.MidlineRight:
    493.                     textAlignmentNew = TextAlignmentOptions.MidlineRight;
    494.                     break;
    495.                 case TextAlignmentOptions_old.MidlineJustified:
    496.                     textAlignmentNew = TextAlignmentOptions.MidlineJustified;
    497.                     break;
    498.             }
    499.  
    500.             //Debug.Log("New :" + textAlignmentOld.ToString());
    501.             return (int)textAlignmentNew;
    502.         }
    503.  
    504.         #endregion #region Text Alignment Converter.
    505.     }
    506. }
    507.  

    Sharing it here, because hope someone will get help from this editor script if they can't move to a newer TMPro version.

    Basically it scans all prefabs in the project which contains TMProText component and changes it's serialized property "m_textAlignment" value from the old enum range (0-19) to the new enum range(257-2048) and writes it in the prefab.
     
    ortin and Stephan_B like this.
  23. PabloC3

    PabloC3

    Joined:
    Oct 3, 2018
    Posts:
    4
    Hi.

    I uploaded a project from Unity 2018.3.1f1 to 2019.3.7f1 (previously backed up) and with that TMPro was updated from 1.5.0-preview1 to 2.0.1. The first thing I noticed was all text alignment was broken, and I have to re-edit one by one every TMP element. Is there a way to solve it for the entire project?
     
    Last edited: Apr 6, 2020
  24. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Please update to version 2.1.0-preview.8 where this issue should have been addressed.

    You might need to go back to the backup.

    P.S. In 1.5.0-preview.x, the alignment was split into separate serialized properties for horizontal and vertical alignment. This is the same in 2.1.0-preview.x. However, version 2.0.1 is the same as the old version 1.4.0 for Unity 2018.4 which does not contain this new alignment. As such upgrading to 2019.x with 2.0.1 will most certainly mess up the alignment.
     
    PabloC3 likes this.
  25. PabloC3

    PabloC3

    Joined:
    Oct 3, 2018
    Posts:
    4
    Thanks Stephan_B, that worked very well. I noticed after that my prefabs with TMP components became misaligned after being spawn. It's weird because the prefabs themselves are looking good, so I don't know what could be.

    EDIT: By the way, I can restore their alignment after modifying them, but I have to do that one by one.
     
    Last edited: Apr 6, 2020
  26. paulgullettMR

    paulgullettMR

    Joined:
    Jun 23, 2019
    Posts:
    13
    Can anyone assist in the right steps to move to ver 2 from ver 1 . Upgrade from Unity 2018.4.25 with 1.5.1 to Unity 2019.4.6 with 2.0.1 gives the alignment errors described. Move to 2.1.1 makes it worse. I can't go back to 1.4 and would prefer not to have to go through and set the Font Asset and vertical and horizontal alignment of each object.
     
  27. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    If you go from 1.5.1 to 2.1.1, everything should work as expected.

    The issue comes from version 2.0.1 using the same old alignment as 1.4.x. When you upgraded to 1.5.1, the alignment was converted so if you go from 1.5.1 to Unity 2019.x + 2.1.1, it should be fine as long as you didn't load all the scenes / objects in 2.0.1 and then saved again. If so, you will have to go back to a backup prior to upgrading to 2019.x.

    Let me know if you are able to go back to your backup.
     
    Jiaquarium likes this.
  28. paulgullettMR

    paulgullettMR

    Joined:
    Jun 23, 2019
    Posts:
    13
    @Stephan_B thank you, worked perfectly. Slight two-step as the project was loading a scene when you opened it, but once we had a blank scene loading when Unity opened we could then upgrade to 2.1.1 from the default 2.0.1 that gets loaded with 2019.4. Loading a scene after the upgrade and everything is in its place.
     
  29. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The default for Unity 2019.4 has been updated to 2.1.1 and will be available in 2019.4.7f1.