Guest User

Unity Replace Text with TextMeshProUGUI

a guest
Sep 11th, 2018
669
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.38 KB | None | 0 0
  1. using UnityEngine;
  2. using UnityEditor;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using TMPro;
  7. using UnityEngine.UI;
  8. using System;
  9. using System.Reflection;
  10.  
  11. public class ReplaceFont {
  12.     public Font OriginalFont;
  13.     public TMP_FontAsset TargetFont;
  14. }
  15.  
  16. public class ReplaceTextForTextMeshPro : EditorWindow {
  17.     private int currentSize = 0;
  18.     public List<ReplaceFont> ReplaceFonts = new List<ReplaceFont>();
  19.     private List<TextMeshProUGUI> m_needUpdate = new List<TextMeshProUGUI>();
  20.  
  21.     bool m_supposedToCheckTime = false;
  22.     float m_time = 0.0f;
  23.  
  24.     [MenuItem("Tools/Text for TextMeshPro Component")]
  25.     public static void ShowWindow() {
  26.         EditorWindow.GetWindow(typeof(ReplaceTextForTextMeshPro));
  27.     }
  28.  
  29.     void OnGUI() {
  30.         int newSize = EditorGUILayout.IntField("Number of Font Assets:", currentSize);
  31.         if (newSize != currentSize) {
  32.             currentSize = newSize;
  33.             ReplaceFonts = new List<ReplaceFont>();
  34.             for (int i = 0; i < currentSize; i++) {
  35.                 ReplaceFonts.Add(new ReplaceFont());
  36.             }
  37.  
  38.         }
  39.  
  40.         foreach (ReplaceFont replaceFont in ReplaceFonts) {
  41.             EditorGUILayout.BeginHorizontal();
  42.             replaceFont.OriginalFont = (Font)EditorGUILayout.ObjectField(replaceFont.OriginalFont, typeof(Font), false);
  43.             EditorGUILayout.PrefixLabel(" to: ");
  44.             replaceFont.TargetFont = (TMP_FontAsset)EditorGUILayout.ObjectField(replaceFont.TargetFont, typeof(TMP_FontAsset), false);
  45.             EditorGUILayout.EndHorizontal();
  46.         }
  47.  
  48.         if (GUILayout.Button("Execute!")) {
  49.             Text[] allTextObjects = Resources.FindObjectsOfTypeAll<Text>();
  50.             Debug.Log("Total text field founds: " + allTextObjects.Length);
  51.  
  52.             m_needUpdate = new List<TextMeshProUGUI>();
  53.             foreach (Text textObject in allTextObjects) {
  54.                 Undo.RegisterFullObjectHierarchyUndo(textObject.gameObject, "Text Undo");
  55.  
  56.                 TMP_FontAsset textMeshProFont = GetTextMeshProFont(textObject);
  57.                 if (textMeshProFont == null)
  58.                     continue;
  59.  
  60.                 if (textObject.transform.parent.GetComponent<InputField>() || textObject.GetComponent<InputField>()) {
  61.                     Debug.LogWarning(string.Format("We can't mess with: {0} because {1} possible depend on the Text Component", textObject, FullPath(textObject.transform.parent.gameObject)), textObject);
  62.                     continue;
  63.                 }
  64.  
  65.                 GameObject tempObject = new GameObject();
  66.                 Text tempTextObject = tempObject.AddComponent<Text>(textObject);
  67.                 GameObject parentObject = textObject.gameObject;
  68.                 DestroyImmediate(textObject, true);
  69.  
  70.                 TextMeshProUGUI textMeshPro = parentObject.GetComponent<TextMeshProUGUI>() ?? parentObject.gameObject.AddComponent<TextMeshProUGUI>();
  71.                
  72.                 m_needUpdate.Add(textMeshPro);
  73.                 textMeshPro.font = textMeshProFont;
  74.                 textMeshPro.fontSize = tempTextObject.fontSize;
  75.                 textMeshPro.fontSizeMax = tempTextObject.resizeTextMaxSize;
  76.                 textMeshPro.enableAutoSizing = tempTextObject.resizeTextForBestFit;
  77.                 textMeshPro.alignment = GetAligmentFromTextObject(tempTextObject.alignment);
  78.                 textMeshPro.color = tempTextObject.color;
  79.                 textMeshPro.enableWordWrapping = tempTextObject.horizontalOverflow != HorizontalWrapMode.Wrap;
  80.                 textMeshPro.overflowMode = GetOverflowMode(tempTextObject.verticalOverflow);
  81.                 textMeshPro.text = tempTextObject.text;
  82.                 textMeshPro.richText = tempTextObject.supportRichText;
  83.  
  84.                 DestroyImmediate(tempObject, true);
  85.             }
  86.  
  87.             foreach (TextMeshProUGUI textMeshProUgui in m_needUpdate) {
  88.                 textMeshProUgui.enabled = false;
  89.             }
  90.  
  91.             m_supposedToCheckTime = true;
  92.         }
  93.     }
  94.  
  95.     private TextOverflowModes GetOverflowMode(VerticalWrapMode verticalOverflow) {
  96.         if (verticalOverflow == VerticalWrapMode.Truncate)
  97.             return TextOverflowModes.Truncate;
  98.  
  99.         return TextOverflowModes.Overflow;
  100.     }
  101.  
  102.     private TextAlignmentOptions GetAligmentFromTextObject(TextAnchor alignment) {
  103.         if (alignment == TextAnchor.LowerCenter)
  104.             return TextAlignmentOptions.Bottom;
  105.  
  106.         else if (alignment == TextAnchor.LowerLeft)
  107.             return TextAlignmentOptions.BottomLeft;
  108.  
  109.         else if (alignment == TextAnchor.LowerRight)
  110.             return TextAlignmentOptions.BottomRight;
  111.  
  112.         else if (alignment == TextAnchor.MiddleCenter)
  113.             return TextAlignmentOptions.Midline;
  114.  
  115.         else if (alignment == TextAnchor.MiddleLeft)
  116.             return TextAlignmentOptions.MidlineLeft;
  117.  
  118.         else if (alignment == TextAnchor.MiddleRight)
  119.             return TextAlignmentOptions.MidlineRight;
  120.  
  121.         else if (alignment == TextAnchor.UpperCenter)
  122.             return TextAlignmentOptions.Top;
  123.  
  124.         else if (alignment == TextAnchor.UpperLeft)
  125.             return TextAlignmentOptions.TopLeft;
  126.  
  127.         else if (alignment == TextAnchor.UpperRight)
  128.             return TextAlignmentOptions.TopRight;
  129.  
  130.         return TextAlignmentOptions.Center;
  131.     }
  132.  
  133.     private TMP_FontAsset GetTextMeshProFont(Text textObject) {
  134.         foreach (ReplaceFont replaceFont in ReplaceFonts) {
  135.             if (replaceFont.OriginalFont == textObject.font)
  136.                 return replaceFont.TargetFont;
  137.         }
  138.         return null;
  139.     }
  140.  
  141.  
  142.     private void Update() {
  143.         if (m_supposedToCheckTime) {
  144.             m_time += 0.01f;
  145.  
  146.             if (m_time >= 3.0f) {
  147.                 //make sure you reset your time
  148.                 m_time = 0.0f;
  149.                 m_supposedToCheckTime = false;
  150.  
  151.                 //TODO: take action
  152.  
  153.                 foreach (TextMeshProUGUI textMeshProUgui in m_needUpdate) {
  154.                     textMeshProUgui.enabled = true;
  155.                 }
  156.                 FindMissingReferencesInCurrentScene();
  157.             }
  158.         }
  159.     }
  160.  
  161.     private static void FindMissingReferences(string context, GameObject[] objects) {
  162.         foreach (var go in objects) {
  163.             var components = go.GetComponents<Component>();
  164.  
  165.             foreach (var c in components) {
  166.                 if (!c) {
  167.                     Debug.LogError("Missing Component in GO: " + FullPath(go), go);
  168.                     continue;
  169.                 }
  170.  
  171.                 SerializedObject so = new SerializedObject(c);
  172.                 var sp = so.GetIterator();
  173.  
  174.                 while (sp.NextVisible(true)) {
  175.                     if (sp.propertyType == SerializedPropertyType.ObjectReference) {
  176.                         if (sp.objectReferenceValue == null
  177.                             && sp.objectReferenceInstanceIDValue != 0) {
  178.                             ShowError(context, go, c.GetType().Name, ObjectNames.NicifyVariableName(sp.name));
  179.                         }
  180.                     }
  181.                 }
  182.             }
  183.         }
  184.     }
  185.  
  186.     [MenuItem("Tools/Show Missing Object References in scene", false, 50)]
  187.     public static void FindMissingReferencesInCurrentScene() {
  188.         var objects = GetSceneObjects();
  189.         FindMissingReferences(EditorApplication.currentScene, objects);
  190.     }
  191.  
  192.     private static GameObject[] GetSceneObjects() {
  193.         return Resources.FindObjectsOfTypeAll<GameObject>()
  194.             .Where(go => string.IsNullOrEmpty(AssetDatabase.GetAssetPath(go))
  195.                    && go.hideFlags == HideFlags.None).ToArray();
  196.     }
  197.  
  198.     private const string err = "Missing Ref in: [{3}]{0}. Component: {1}, Property: {2}";
  199.     private const string CAUUTION_S = "We can't update: [{3}]{0}. Component: {1}, Property: {2}";
  200.  
  201.     private static void ShowError(string context, GameObject go, string c, string property) {
  202.         Debug.LogError(string.Format(err, FullPath(go), c, property, context), go);
  203.     }
  204.  
  205.     private static string FullPath(GameObject go) {
  206.         return go.transform.parent == null
  207.             ? go.name
  208.                 : FullPath(go.transform.parent.gameObject) + "/" + go.name;
  209.     }
  210.  
  211. }
  212.  
  213.  
  214. public static class TextReplacerExtensions {
  215.     public static T GetCopyOf<T>(this Component comp, T other) where T : Component {
  216.         Type type = comp.GetType();
  217.         if (type != other.GetType()) return null; // type mis-match
  218.         BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default | BindingFlags.DeclaredOnly;
  219.         PropertyInfo[] pinfos = type.GetProperties(flags);
  220.         foreach (var pinfo in pinfos) {
  221.             if (pinfo.CanWrite) {
  222.                 try {
  223.                     pinfo.SetValue(comp, pinfo.GetValue(other, null), null);
  224.                 }
  225.                 catch { } // In case of NotImplementedException being thrown. For some reason specifying that exception didn't seem to catch it, so I didn't catch anything specific.
  226.             }
  227.         }
  228.         FieldInfo[] finfos = type.GetFields(flags);
  229.         foreach (var finfo in finfos) {
  230.             finfo.SetValue(comp, finfo.GetValue(other));
  231.         }
  232.         return comp as T;
  233.     }
  234.  
  235.     public static T AddComponent<T>(this GameObject go, T toAdd) where T : Component {
  236.         return go.AddComponent<T>().GetCopyOf(toAdd) as T;
  237.     }
  238. }
Advertisement
Add Comment
Please, Sign In to add comment