Files
aibis-dream/Assets/Editor/Typography/TypographyFirstRoundBuilder.cs

170 lines
6.1 KiB
C#

using System;
using System.Collections.Generic;
using AibisDream.Framework;
using TMPro;
using UnityEditor;
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;
using UnityEditor.AddressableAssets.Settings.GroupSchemas;
using UnityEngine;
namespace AibisDream.EditorTools
{
public static class TypographyFirstRoundBuilder
{
private const string GroupName = "Shared_Typography";
private const string ProfileFolder = "Assets/GameContent/Common/Typography/Profiles";
private const string WenQuanYiPath = "Assets/Font/Assets/WenQuanYi Bitmap Song 14px SDF.asset";
private const string ChillBitmapPath = "Assets/Font/Assets/ChillBitmap_16px SDF.asset";
private const string ArkPixelPath = "Assets/Font/TTF/ark-pixel-16px-proportional-latin SDF.asset";
[MenuItem("Tools/AIBIS Dream/Typography/Rebuild First Round Assets")]
public static void BuildFirstRoundAssets()
{
EnsureFolder(ProfileFolder);
TMP_FontAsset wenQuanYi = LoadRequiredFont(WenQuanYiPath);
TMP_FontAsset chillBitmap = LoadRequiredFont(ChillBitmapPath);
TMP_FontAsset arkPixel = LoadRequiredFont(ArkPixelPath);
AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings;
if (settings == null)
throw new InvalidOperationException("AddressableAssetSettings 不存在。");
AddressableAssetGroup group = GetOrCreateGroup(settings);
CreateOrUpdateProfile(
settings,
group,
TypographyProfileKind.ZhHans,
wenQuanYi,
new[] { chillBitmap });
CreateOrUpdateProfile(
settings,
group,
TypographyProfileKind.Japanese,
chillBitmap,
new[] { wenQuanYi });
CreateOrUpdateProfile(
settings,
group,
TypographyProfileKind.Latin,
arkPixel,
new[] { chillBitmap });
CreateOrUpdateProfile(
settings,
group,
TypographyProfileKind.Russian,
arkPixel,
new[] { chillBitmap });
TerminalTypographyMigration.MigrateTerminalPrefabs();
EditorUtility.SetDirty(settings);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log("[TypographyFirstRoundBuilder] Profile、Addressables 和首轮试点绑定已更新。");
}
public static void BuildFromCommandLine()
{
try
{
BuildFirstRoundAssets();
}
catch (Exception exception)
{
Debug.LogException(exception);
throw;
}
}
private static TMP_FontAsset LoadRequiredFont(string path)
{
TMP_FontAsset font = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(path);
if (font == null)
throw new InvalidOperationException($"找不到字体资产:{path}");
return font;
}
private static AddressableAssetGroup GetOrCreateGroup(AddressableAssetSettings settings)
{
AddressableAssetGroup group = settings.FindGroup(GroupName);
if (group == null)
{
group = settings.CreateGroup(
GroupName,
false,
false,
true,
null,
typeof(BundledAssetGroupSchema),
typeof(ContentUpdateGroupSchema));
}
BundledAssetGroupSchema bundled = group.GetSchema<BundledAssetGroupSchema>();
if (bundled != null)
{
bundled.IncludeInBuild = true;
bundled.BundleMode = BundledAssetGroupSchema.BundlePackingMode.PackTogether;
EditorUtility.SetDirty(bundled);
}
ContentUpdateGroupSchema update = group.GetSchema<ContentUpdateGroupSchema>();
if (update != null)
{
update.StaticContent = false;
EditorUtility.SetDirty(update);
}
return group;
}
private static void CreateOrUpdateProfile(
AddressableAssetSettings settings,
AddressableAssetGroup group,
TypographyProfileKind kind,
TMP_FontAsset font,
IReadOnlyCollection<TMP_FontAsset> fallbacks)
{
string path = $"{ProfileFolder}/{kind}.asset";
TypographyProfile profile = AssetDatabase.LoadAssetAtPath<TypographyProfile>(path);
if (profile == null)
{
profile = ScriptableObject.CreateInstance<TypographyProfile>();
AssetDatabase.CreateAsset(profile, path);
}
var styles = new List<TypographyStyle>();
foreach (TypographyRole role in Enum.GetValues(typeof(TypographyRole)))
{
styles.Add(new TypographyStyle(
role,
font,
fallbackFonts: fallbacks,
fontSizeMultiplier: 1f));
}
profile.Configure(kind, styles);
EditorUtility.SetDirty(profile);
string guid = AssetDatabase.AssetPathToGUID(path);
AddressableAssetEntry entry = settings.CreateOrMoveEntry(guid, group, false, false);
entry.address = $"Typography/Profile/{kind}";
entry.SetLabel("Typography", true, true, false);
}
private static void EnsureFolder(string path)
{
string[] segments = path.Split('/');
string current = segments[0];
for (int i = 1; i < segments.Length; i++)
{
string next = $"{current}/{segments[i]}";
if (!AssetDatabase.IsValidFolder(next))
AssetDatabase.CreateFolder(current, segments[i]);
current = next;
}
}
}
}