using UnityEngine; using UnityEditor; using TMPro; using UnityEngine.UI; public class ReplaceTMPInputFieldFinal : EditorWindow { private TMP_FontAsset targetFontAsset; [MenuItem("Tools/Replace TMP InputField")] public static void ShowWindow() { GetWindow("Replace TMP InputField"); } private void OnGUI() { GUILayout.Label("一键替换所有 TMP_InputField 为 CustomTMPInputField", EditorStyles.boldLabel); GUILayout.Space(10); targetFontAsset = (TMP_FontAsset)EditorGUILayout.ObjectField( "目标 Font Asset", targetFontAsset, typeof(TMP_FontAsset), false ); GUILayout.Space(20); GUI.enabled = targetFontAsset != null; if (GUILayout.Button("替换场景中所有 TMP_InputField", GUILayout.Height(30))) { ReplaceAllInScene(); } GUI.enabled = true; } private void ReplaceAllInScene() { TMP_InputField[] fields = FindObjectsOfType(true); int count = 0; Undo.RecordObjects(fields, "Replace TMP_InputField"); foreach (var oldField in fields) { ReplaceOne(oldField); count++; } EditorUtility.DisplayDialog("替换完成", $"成功替换 {count} 个 TMP_InputField", "确定"); } private void ReplaceOne(TMP_InputField oldField) { GameObject go = oldField.gameObject; // ---- 备份必要字段 ---- var textViewport = oldField.textViewport; var textComponent = oldField.textComponent; var placeholder = oldField.placeholder; // ---- 备份输入行为属性 ---- var contentType = oldField.contentType; var lineType = oldField.lineType; var charLimit = oldField.characterLimit; var interactable = oldField.interactable; var readOnly = oldField.readOnly; var caretBlinkRate = oldField.caretBlinkRate; var caretWidth = oldField.caretWidth; var selectionColor = oldField.selectionColor; var inputType = oldField.inputType; var keyboardType = oldField.keyboardType; var characterValidation = oldField.characterValidation; var lineLimit = oldField.lineLimit; Undo.DestroyObjectImmediate(oldField); // ---- 添加新组件 ---- CustomTMPInputField newField = Undo.AddComponent(go); SerializedObject so = new SerializedObject(newField); so.Update(); // ---- 还原关键引用 ---- so.FindProperty("m_TextViewport").objectReferenceValue = textViewport; so.FindProperty("m_TextComponent").objectReferenceValue = textComponent; so.FindProperty("m_Placeholder").objectReferenceValue = placeholder; // ---- 还原输入属性 ---- so.FindProperty("m_ContentType").enumValueIndex = (int)contentType; so.FindProperty("m_LineType").enumValueIndex = (int)lineType; so.FindProperty("m_CharacterLimit").intValue = charLimit; so.FindProperty("m_Interactable").boolValue = interactable; so.FindProperty("m_ReadOnly").boolValue = readOnly; so.FindProperty("m_CaretBlinkRate").floatValue = caretBlinkRate; so.FindProperty("m_CaretWidth").intValue = caretWidth; so.FindProperty("m_SelectionColor").colorValue = selectionColor; so.FindProperty("m_InputType").enumValueIndex = (int)inputType; so.FindProperty("m_KeyboardType").enumValueIndex = (int)keyboardType; so.FindProperty("m_CharacterValidation").enumValueIndex = (int)characterValidation; so.FindProperty("m_LineLimit").intValue = lineLimit; so.ApplyModifiedProperties(); // ---- 设置 Input Field Settings → Font Asset ---- SetInputFieldFontAsset(newField, targetFontAsset); EditorUtility.SetDirty(newField); } private void SetInputFieldFontAsset(CustomTMPInputField field, TMP_FontAsset fontAsset) { SerializedObject so = new SerializedObject(field); so.Update(); // TMP_InputField 的 InputFieldSettings → Font Asset 对应这个字段 SerializedProperty prop = so.FindProperty("m_GlobalFontAsset"); if (prop != null) { prop.objectReferenceValue = fontAsset; } else { Debug.LogWarning($"未找到 m_GlobalFontAsset 字段:{field.name}"); } so.ApplyModifiedProperties(); } }