シーンやプレハブでUnityEngine.UI.Textをアタッチしている部分をすべて
それを継承したMultilingualTextというコンポーネントに置き換えたいのですが、
手動で1つ1つRemoveしてAddしてフォント等の設定を変更して・・と手作業していくしかないのでしょうか。
もっと簡単な方法があれば教えてください。
◆環境
Unity2017 3.1f1
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
数が多いと面倒ですし、修正漏れも起こりそうですよね...
EditorUtility.CopySerializedでコンポーネントの設定を書き写すことができるそうですので、これを使って楽ができるんじゃないでしょうか。
プロジェクトに「Editor」フォルダを用意して下記のようなスクリプトを置き...
C#
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using UnityEditor; 5using UnityEditor.AnimatedValues; 6using UnityEngine; 7using UnityEngine.UI; 8 9public class ComponentReplacer : EditorWindow 10{ 11 // ウィンドウを開いたときのデフォルトの置き換え元、置き換え先を変える場合はこの2つを書き換える 12 private static readonly Type DefaultFromType = typeof(Text); 13 private static readonly Type DefaultToType = typeof(MultilingualText); 14 15 private AnimBool showInfo; 16 private string fromTypeString = $"{DefaultFromType.FullName}, {DefaultFromType.Assembly.GetName().Name}"; 17 private string toTypeString = $"{DefaultToType.FullName}, {DefaultToType.Assembly.GetName().Name}"; 18 19 // 「Utility」→「Replace Components」で置き換えウィンドウを開く 20 [MenuItem("Utility/Replace Components")] 21 private static void OpenWindow() 22 { 23 var window = GetWindow<ComponentReplacer>("Replace Components"); 24 window.Show(); 25 } 26 27 // エラーメッセージ表示用のAnimBoolを作成 28 private void OnEnable() 29 { 30 this.showInfo = new AnimBool(true); 31 this.showInfo.valueChanged.AddListener(this.Repaint); 32 } 33 34 private void OnGUI() 35 { 36 using (new EditorGUILayout.VerticalScope()) 37 { 38 // 「From Type」、「To Type」の文字列と対応する型を探す 39 var infoMessage = string.Empty; 40 var infoType = MessageType.None; 41 Type fromType = null; 42 Type toType = null; 43 try 44 { 45 this.fromTypeString = EditorGUILayout.TextField("From Type", this.fromTypeString); 46 fromType = Type.GetType(this.fromTypeString, true); 47 if (!typeof(Component).IsAssignableFrom(fromType)) 48 { 49 // 置き換え元の型がComponentから派生していなければ失敗 50 throw new Exception($"{this.fromTypeString} is not compatible with {typeof(Component)}."); 51 } 52 53 this.toTypeString = EditorGUILayout.TextField("To Type", this.toTypeString); 54 toType = Type.GetType(this.toTypeString, true); 55 if (!fromType.IsAssignableFrom(toType)) 56 { 57 // 置き換え先の型が置き換え元の型から派生していなければ失敗 58 throw new Exception($"{this.toTypeString} is not compatible with {fromType}."); 59 } 60 } 61 catch (Exception exception) 62 { 63 infoMessage = exception.Message; 64 infoType = MessageType.Error; 65 } 66 67 // もしエラーメッセージが出ていたら表示する 68 this.showInfo.target = !string.IsNullOrEmpty(infoMessage); 69 using (var fadeGroup = new EditorGUILayout.FadeGroupScope(this.showInfo.faded)) 70 { 71 if (fadeGroup.visible) 72 { 73 EditorGUILayout.HelpBox(infoMessage, infoType, true); 74 } 75 } 76 77 // 選択されているゲームオブジェクトやそれらの子階層からfromTypeコンポーネントを探し、 78 // 1つ以上見つかって、かつエラーが出ていなければ「Replace」ボタンを使用可能にする 79 var selectedObjects = Selection.gameObjects; 80 var selectedComponents = 81 selectedObjects.SelectMany(gameObject => gameObject.GetComponentsInChildren(fromType)).Distinct(); 82 using (new EditorGUI.DisabledScope((infoType == MessageType.Error) || !selectedComponents.Any())) 83 { 84 if (GUILayout.Button("Replace")) 85 { 86 this.Replace(fromType, toType, selectedComponents); 87 } 88 } 89 } 90 } 91 92 private void Replace(Type fromType, Type toType, IEnumerable<Component> components) 93 { 94 Debug.Log($"{fromType} -> {toType}"); 95 foreach (var component in components) 96 { 97 var gameObject = component.gameObject; 98 Debug.Log($"\t{gameObject.name}"); 99 Undo.SetCurrentGroupName($"Replace Components"); 100 101 // まず元のコンポーネントをゲームオブジェクトごと複製 102 var cloneObject = Instantiate(gameObject, gameObject.transform.parent); 103 var cloneComponent = cloneObject.GetComponent(fromType); 104 105 // 元のコンポーネントは削除し、置き換え先のコンポーネントをアタッチ 106 Undo.DestroyObjectImmediate(component); 107 var newComponent = Undo.AddComponent(gameObject, toType); 108 109 // 複製しておいた元コンポーネントから新しいコンポーネントにデータをコピー 110 EditorUtility.CopySerialized(cloneComponent, newComponent); 111 112 // 複製は不要になったので削除する 113 DestroyImmediate(cloneObject); 114 } 115 } 116}
- 処理対象のオブジェクトを選択する(複数選択、あるいは親オブジェクトを選択してもけっこうです)。
- 「Utility」→「Replace Components」で置き換えウィンドウを開く。
- 「From Type」に置き換え元、「To Type」に置き換え先の型を入力する(完全修飾・アセンブリ名付きでないと型が見つからないという不便な作りですが、そんなに多用するものでもないかと思いますのでご容赦ください...)。
- 処理対象が1つ以上選択されており、エラーもなければ「Replace」ボタンが使用可能になるのでクリックする。
- 取り消す場合はメニューの「Edit」→「Undo Replace Components」を実行する。
というのはどうでしょう。
投稿2019/05/19 13:04
総合スコア10811
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/05/19 13:20