-->

using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using Object = UnityEngine.Object;
/// <summary>
/// Project内のSceneやPrefabを変更するための便利クラス
/// </summary>
public class AssetChangeBase : EditorWindow
{
/// <summary>
/// Project内の全てのAssetから指定のファイル形式のObjectを取得
/// </summary>
protected static T[] FindAssets<T>(string specified = "") where T : Object
{
List<T> result = new List<T>();
string[] assetList = null;
if (string.IsNullOrEmpty(specified))
{
assetList = AssetDatabase.FindAssets(string.Format("t:{0}", typeof(T).Name));
}
else
{
assetList = AssetDatabase.FindAssets(string.Format("t:{0}", specified));
}
for (int i = 0; i < assetList.Length; i++)
{
string assetPath = AssetDatabase.GUIDToAssetPath(assetList[i]);
T asset = AssetDatabase.LoadAssetAtPath<T>(assetPath);
if (asset != null)
{
result.Add(asset);
}
}
return result.ToArray();
}
/// <summary>
/// 新しいシーンで全プレハブを生成するだけ
/// </summary>
/// <param name="targetType">Prefab内に指定したComponentがあるものだけを生成する</param>
protected static List<Object> InstantiateAllPrefabs(Type targetType = null)
{
//新しいシーンを作り、そこで全てのプレハブを生成する
EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
List<Object> instantiatedPrefabs = new List<Object>();
var prefabsDic = FindAssets<GameObject>("Prefab");
foreach (var item in prefabsDic)
{
if (targetType == null)
{
instantiatedPrefabs.Add(PrefabUtility.InstantiatePrefab(item));
}
else
{
if (item.GetComponentsInChildren(targetType, true) != null &&
item.GetComponentsInChildren(targetType, true).Length > 0)
{
instantiatedPrefabs.Add(PrefabUtility.InstantiatePrefab(item));
}
}
}
return instantiatedPrefabs;
}
/// <summary>
/// 全てのPrefabを生成してコンポーネントを操作
/// </summary>
/// <param name="callback">生成した全てのGameObjectに対して実行するcallback</param>
/// <param name="isApply">callbackを呼んだ後Applyするかどうか</param>
/// <param name="targetType">Prefab内に指定したComponentがあるものだけをApply対象にする</param>
protected static void ChangeComponentAllPrefabs(Action<GameObject> callback, bool isApply = true, Type targetType = null)
{
//後で戻ってくるので現在のシーンのパスを保存
string curScenePath = SceneManager.GetActiveScene().path;
List<Object> instantiatedPrefabs = InstantiateAllPrefabs(targetType);
ChangeActionForeach(callback);
//PrefabのApply
if (isApply)
{
int i = 0;
foreach (var item in instantiatedPrefabs)
{
EditorUtility.DisplayProgressBar("Replacing in prefab...", item.name, (float)i / instantiatedPrefabs.Count);
//Unity標準のプレハブでなければApply
if (!PrefabUtility.IsPartOfImmutablePrefab((GameObject)item))
{
try
{
PrefabUtility.ApplyPrefabInstance((GameObject)item, InteractionMode.UserAction);
}
catch (System.Exception e)
{
Debug.LogError(e);
Debug.LogError("Prefabの更新ができませんでした。対象のPrefabの中身を確かめてください。");
EditorUtility.ClearProgressBar();
EditorSceneManager.OpenScene(curScenePath);
return;
}
}
i++;
}
EditorUtility.ClearProgressBar();
}
if (!String.IsNullOrEmpty(curScenePath))
{
EditorSceneManager.OpenScene(curScenePath);
}
}
/// <summary>
/// 現在のシーンの全てのコンポーネントを操作
/// </summary>
/// <param name="callback">シーン上の全てのGameObjectに対して実行するcallback</param>
/// <param name="isSave">callbackを呼んだあとシーンをSaveするかどうか</param>
protected static void ChangeComponentCurrentScene(Action<GameObject> callback, bool isSave = true)
{
ChangeActionForeach(callback);
if (isSave)
{
EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
}
}
/// <summary>
/// 全てのシーンの全てのコンポーネントを操作
/// </summary>
/// <param name="callback">シーン上の全てのGameObjectに対して実行するcallback</param>
/// <param name="isSave">callbackを呼んだあとシーンをSaveするかどうか</param>
protected static void ChangeComponentAllScenes(Action<GameObject> callback, bool isSave = true)
{
//後で戻ってくるので現在のシーンのパスを保存
string curScenePath = SceneManager.GetActiveScene().path;
//全てのシーンを順々に読み込んでコンポーネントを操作
SceneAsset[] scenes = FindAssets<SceneAsset>();
for (int i = 0; i < scenes.Length; i++)
{
SceneAsset scene = scenes[i];
Debug.Log("Sceneの読み込み = " + scene.name);
EditorUtility.DisplayProgressBar("Replacing in scene...", scene.name, (float)i / scenes.Length);
Scene loadedScene = EditorSceneManager.OpenScene(AssetDatabase.GetAssetPath(scene), OpenSceneMode.Single);
while (!loadedScene.isLoaded) {}
ChangeActionForeach(callback);
if (isSave)
{
EditorSceneManager.SaveScene(loadedScene);
}
}
EditorUtility.ClearProgressBar();
EditorSceneManager.OpenScene(curScenePath);
}
/// <summary>
/// 再起的に子要素に潜る
/// </summary>
private static void DeepSerch(GameObject root, System.Action<GameObject> callback)
{
callback(root);
if (root.transform.childCount != 0)
{
for (int j = 0; j < root.transform.childCount; j++)
{
GameObject targetObj = root.transform.GetChild(j).gameObject;
DeepSerch(targetObj, callback);
}
}
}
/// <summary>
/// ルートオブジェクトを回してCallbackを呼ぶ
/// </summary>
private static void ChangeActionForeach(Action<GameObject> callback)
{
GameObject[] rootGameObjects = SceneManager.GetActiveScene().GetRootGameObjects();
for (int i = 0; i < rootGameObjects.Length; i++)
{
GameObject root = rootGameObjects[i];
DeepSerch(root, (targetObj) =>
{
callback(targetObj);
});
}
}
/// <summary>
/// RootのプレハブをApply
/// </summary>
protected static void AllPrefabsApply()
{
GameObject[] rootGameObjects = SceneManager.GetActiveScene().GetRootGameObjects();
for (int i = 0; i < rootGameObjects.Length; i++)
{
var item = rootGameObjects[i];
//Unity標準のプレハブでなければApply
if (!PrefabUtility.IsPartOfImmutablePrefab(item))
{
try
{
PrefabUtility.ApplyPrefabInstance(item, InteractionMode.UserAction);
}
catch (System.Exception e)
{
Debug.LogError(e);
Debug.LogError("Prefabの更新ができませんでした。対象のPrefabの中身を確かめてください。");
EditorUtility.ClearProgressBar();
return;
}
}
}
}
}

using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using TMPro;
/// <summary>
/// TextMeshPro Componentに対し、指定のFontに入れ替えるEditor
/// </summary>
public class FontReplacerTmp : AssetChangeBase
{
private static TMP_FontAsset[] fonts;
private static List<string> fontsStrings;
private static int selectFontIdx = 0;
private static TMP_FontAsset targetFont;
private static bool isInitialize = false;
/// <summary>
/// 全てのフォントを取得して保存
/// </summary>
private static void Reload()
{
fonts = FindAssets<TMP_FontAsset>();
fontsStrings = fonts.Select(x => x.ToString()).ToList();
}
[MenuItem("Editor/Font Replacer Tmp", priority = 2)]
private static void Init()
{
FontReplacerTmp window = (FontReplacerTmp)GetWindow(typeof(FontReplacerTmp));
window.Show();
}
void OnGUI()
{
if (!isInitialize)
{
Reload();
targetFont = fonts.First();
isInitialize = true;
}
if (GUILayout.Button("フォントアセットのリロード"))
{
Reload();
}
if (fonts == null || fonts.Length == 0)
{
return;
}
selectFontIdx = EditorGUILayout.Popup("上書きするフォント:", selectFontIdx, fontsStrings.ToArray());
targetFont = fonts[selectFontIdx];
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("[全てのプレハブ]");
if (GUILayout.Button("フォントを上書き"))
{
ChangeComponentAllPrefabs(FontChange);
}
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("[現在のシーン]");
if (GUILayout.Button("フォントを上書き"))
{
ChangeComponentCurrentScene(FontChange);
}
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("[全てのシーン]");
if (GUILayout.Button("フォントを上書き"))
{
ChangeComponentAllScenes(FontChange);
}
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("-------------");
EditorGUILayout.LabelField("手作業で確認");
if (GUILayout.Button("全プレハブを生成"))
{
InstantiateAllPrefabs();
}
if (GUILayout.Button("Rootの全プレハブをApply"))
{
AllPrefabsApply();
}
}
/// <summary>
/// Fontを変更
/// </summary>
private void FontChange(GameObject targetObj)
{
TextMeshProUGUI text = targetObj.GetComponent<TextMeshProUGUI>();
if (text != null)
{
if (text.font != targetFont)
{
text.font = targetFont;
//シーン変更を通知
EditorUtility.SetDirty(text);
}
}
}
}



using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 旧Text Componentに対し、指定のFontに入れ替えるEditor
/// </summary>
public class FontReplacer : AssetChangeBase
{
private static Font[] fonts;
private static List<string> fontsStrings;
private static int selectFontIdx = 0;
private static Font targetFont;
private static bool isInitialize = false;
/// <summary>
/// 全てのフォントを取得して保存
/// </summary>
private static void Reload()
{
fonts = FindAssets<Font>();
fontsStrings = fonts.Select(x => x.ToString()).ToList();
}
[MenuItem("Tools/Font Replacer/Editor Window", priority = 100)]
private static void Init()
{
FontReplacer window = (FontReplacer)GetWindow(typeof(FontReplacer));
window.Show();
}
void OnGUI()
{
if (!isInitialize)
{
Reload();
targetFont = fonts.First();
isInitialize = true;
}
if (GUILayout.Button("フォントアセットのリロード"))
{
Reload();
}
if (fonts == null || fonts.Length == 0)
{
return;
}
selectFontIdx = EditorGUILayout.Popup("上書きするフォント:", selectFontIdx, fontsStrings.ToArray());
targetFont = fonts[selectFontIdx];
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("[全てのプレハブ]");
if (GUILayout.Button("フォントを上書き"))
{
ChangeComponentAllPrefabs(FontChange);
}
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("[現在のシーン]");
if (GUILayout.Button("フォントを上書き"))
{
ChangeComponentCurrentScene(FontChange);
}
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("[全てのシーン]");
if (GUILayout.Button("フォントを上書き"))
{
ChangeComponentAllScenes(FontChange);
}
EditorGUILayout.Space(10);
EditorGUILayout.LabelField("-------------");
EditorGUILayout.LabelField("手作業で確認");
if (GUILayout.Button("全プレハブを生成"))
{
InstantiateAllPrefabs();
}
if (GUILayout.Button("Rootの全プレハブをApply"))
{
AllPrefabsApply();
}
}
/// <summary>
/// Fontを変更
/// </summary>
private void FontChange(GameObject targetObj)
{
Text text = targetObj.GetComponent<Text>();
if (text != null)
{
if (text.font != targetFont)
{
text.font = targetFont;
//シーン変更を通知
EditorUtility.SetDirty(text);
}
}
}
}