230 lines
9.1 KiB
C#
230 lines
9.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using AibisDream.Framework;
|
|
using AibisDream.UI;
|
|
using TMPro;
|
|
using UnityEditor;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
namespace AibisDream.EditorTools
|
|
{
|
|
public static class TerminalTypographyMigration
|
|
{
|
|
public const string PrefabFolder = "Assets/GameContent/Feature_MainUI/Prefabs";
|
|
public const string PersistenceScenePath = "Assets/Scenes/Persistence.unity";
|
|
|
|
// Sources must be migrated before their consumers so existing added-component
|
|
// overrides can be replaced by the component inherited from the source prefab.
|
|
public static readonly IReadOnlyList<string> PrefabPaths = new[]
|
|
{
|
|
$"{PrefabFolder}/Common/Select Item.prefab",
|
|
$"{PrefabFolder}/Common/Slider Item.prefab",
|
|
$"{PrefabFolder}/Common/TerminalButton.prefab",
|
|
$"{PrefabFolder}/Common/TerminalChapterCard.prefab",
|
|
$"{PrefabFolder}/Common/TerminalHeader.prefab",
|
|
$"{PrefabFolder}/Common/TerminalMenuItem.prefab",
|
|
$"{PrefabFolder}/Common/TerminalOptionItem.prefab",
|
|
$"{PrefabFolder}/Common/TerminalRecordItem.prefab",
|
|
$"{PrefabFolder}/Common/TerminalSliderItem.prefab",
|
|
$"{PrefabFolder}/Common/TerminalChapterPanel.prefab",
|
|
$"{PrefabFolder}/TerminalChapterPanel.prefab",
|
|
$"{PrefabFolder}/TerminalLoadingPanel.prefab",
|
|
$"{PrefabFolder}/TerminalRecordPanel.prefab",
|
|
$"{PrefabFolder}/TerminalSettingPanel.prefab",
|
|
$"{PrefabFolder}/TerminalSettingPanelMini.prefab",
|
|
$"{PrefabFolder}/TerminalStartPanel.prefab"
|
|
};
|
|
|
|
[MenuItem("Tools/AIBIS Dream/Typography/Migrate Terminal Prefabs")]
|
|
public static void MigrateTerminalPrefabs()
|
|
{
|
|
int textCount = 0;
|
|
int addedCount = 0;
|
|
int removedOverrideCount = 0;
|
|
|
|
foreach (string path in PrefabPaths)
|
|
{
|
|
MigrationResult result = MigratePrefab(path);
|
|
textCount += result.TextCount;
|
|
addedCount += result.AddedCount;
|
|
removedOverrideCount += result.RemovedOverrideCount;
|
|
}
|
|
|
|
int sceneBindingCount = MigratePersistenceScene();
|
|
AssetDatabase.SaveAssets();
|
|
Debug.Log(
|
|
$"[TerminalTypographyMigration] Migrated {PrefabPaths.Count} prefabs and " +
|
|
$"{textCount} TMP texts. Added {addedCount} bindings; removed " +
|
|
$"{removedOverrideCount} redundant nested overrides; added " +
|
|
$"{sceneBindingCount} scene-owned bindings.");
|
|
}
|
|
|
|
public static void MigrateFromCommandLine()
|
|
{
|
|
try
|
|
{
|
|
MigrateTerminalPrefabs();
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
Debug.LogException(exception);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
private static MigrationResult MigratePrefab(string path)
|
|
{
|
|
GameObject root = PrefabUtility.LoadPrefabContents(path);
|
|
try
|
|
{
|
|
TMP_Text[] texts = root.GetComponentsInChildren<TMP_Text>(true);
|
|
if (texts.Length == 0)
|
|
throw new InvalidOperationException($"Terminal prefab contains no TMP text: {path}");
|
|
|
|
int addedCount = 0;
|
|
int removedOverrideCount = 0;
|
|
foreach (TMP_Text text in texts)
|
|
{
|
|
int removedForText = RemoveRedundantNestedOverrides(text);
|
|
removedOverrideCount += removedForText;
|
|
|
|
LocalizedTypography[] bindings = text.GetComponents<LocalizedTypography>();
|
|
if (bindings.Length == 0)
|
|
{
|
|
// Saving the removed override makes the source component visible
|
|
// again when this consumer prefab is next loaded.
|
|
if (removedForText > 0)
|
|
continue;
|
|
|
|
LocalizedTypography binding = text.gameObject.AddComponent<LocalizedTypography>();
|
|
binding.ConfigureForEditor(TypographyRole.Terminal);
|
|
addedCount++;
|
|
}
|
|
else if (bindings.Length == 1)
|
|
{
|
|
ConfigureIfOwnedByCurrentPrefab(bindings[0]);
|
|
}
|
|
else
|
|
{
|
|
throw new InvalidOperationException(
|
|
$"TMP text has multiple typography bindings after cleanup: {path} / {text.name}");
|
|
}
|
|
}
|
|
|
|
PrefabUtility.SaveAsPrefabAsset(root, path);
|
|
return new MigrationResult(texts.Length, addedCount, removedOverrideCount);
|
|
}
|
|
finally
|
|
{
|
|
PrefabUtility.UnloadPrefabContents(root);
|
|
}
|
|
}
|
|
|
|
private static int MigratePersistenceScene()
|
|
{
|
|
Scene scene = SceneManager.GetSceneByPath(PersistenceScenePath);
|
|
bool openedForMigration = !scene.IsValid() || !scene.isLoaded;
|
|
if (openedForMigration)
|
|
scene = EditorSceneManager.OpenScene(PersistenceScenePath, OpenSceneMode.Additive);
|
|
try
|
|
{
|
|
int addedCount = 0;
|
|
var visited = new HashSet<TMP_Text>();
|
|
foreach (GameObject root in scene.GetRootGameObjects())
|
|
{
|
|
Component[] hosts = root.GetComponentsInChildren<Component>(true);
|
|
foreach (Component host in hosts)
|
|
{
|
|
if (host is not TerminalPanel && host is not InGameTerminalPanel)
|
|
continue;
|
|
|
|
foreach (TMP_Text text in host.GetComponentsInChildren<TMP_Text>(true))
|
|
{
|
|
if (!visited.Add(text))
|
|
continue;
|
|
|
|
LocalizedTypography[] bindings = text.GetComponents<LocalizedTypography>();
|
|
if (bindings.Length == 1)
|
|
continue;
|
|
if (bindings.Length > 1)
|
|
{
|
|
throw new InvalidOperationException(
|
|
$"Scene TMP text has multiple typography bindings: {text.name}");
|
|
}
|
|
if (PrefabUtility.IsPartOfPrefabInstance(text))
|
|
{
|
|
throw new InvalidOperationException(
|
|
$"Terminal prefab instance is missing its source binding: {text.name}");
|
|
}
|
|
|
|
LocalizedTypography binding = text.gameObject.AddComponent<LocalizedTypography>();
|
|
binding.ConfigureForEditor(TypographyRole.Terminal);
|
|
addedCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (addedCount > 0)
|
|
{
|
|
EditorSceneManager.MarkSceneDirty(scene);
|
|
EditorSceneManager.SaveScene(scene);
|
|
}
|
|
|
|
return addedCount;
|
|
}
|
|
finally
|
|
{
|
|
if (openedForMigration)
|
|
EditorSceneManager.CloseScene(scene, true);
|
|
}
|
|
}
|
|
|
|
private static int RemoveRedundantNestedOverrides(TMP_Text text)
|
|
{
|
|
GameObject sourceObject = PrefabUtility.GetCorrespondingObjectFromSource(text.gameObject);
|
|
if (sourceObject == null || sourceObject.GetComponent<LocalizedTypography>() == null)
|
|
return 0;
|
|
|
|
int removed = 0;
|
|
LocalizedTypography[] bindings = text.GetComponents<LocalizedTypography>();
|
|
foreach (LocalizedTypography binding in bindings)
|
|
{
|
|
if (!PrefabUtility.IsAddedComponentOverride(binding))
|
|
continue;
|
|
|
|
UnityEngine.Object.DestroyImmediate(binding, true);
|
|
removed++;
|
|
}
|
|
|
|
return removed;
|
|
}
|
|
|
|
private static void ConfigureIfOwnedByCurrentPrefab(LocalizedTypography binding)
|
|
{
|
|
if (PrefabUtility.IsPartOfPrefabInstance(binding) &&
|
|
PrefabUtility.GetCorrespondingObjectFromSource(binding) != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
binding.ConfigureForEditor(TypographyRole.Terminal);
|
|
}
|
|
|
|
private readonly struct MigrationResult
|
|
{
|
|
public MigrationResult(int textCount, int addedCount, int removedOverrideCount)
|
|
{
|
|
TextCount = textCount;
|
|
AddedCount = addedCount;
|
|
RemovedOverrideCount = removedOverrideCount;
|
|
}
|
|
|
|
public int TextCount { get; }
|
|
public int AddedCount { get; }
|
|
public int RemovedOverrideCount { get; }
|
|
}
|
|
}
|
|
}
|