using Thousandto.Cinematic; using Thousandto.Launcher.ExternalLibs; using System; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; using UnityEngine.Playables; using UnityEngine.Timeline; using Thousandto.Package.Tool; using Thousandto.DIY; namespace Thousandto.Package { /// <summary> /// /// </summary> public class PackageProxy { static PackageProxy() { Initialize(); } private static void Initialize() { PrefabAssetEditorUtil.SetHandler(ShaderUtil.GetPropertyCount, GetShaderPropertyTypeHandler, ShaderUtil.GetPropertyName, AssetDatabase.GetAssetPath); } //获取Shader属性类型的方法 private static int GetShaderPropertyTypeHandler(Shader s, int idx) { return (int)ShaderUtil.GetPropertyType(s, idx); } public static void Register() { Thousandto.Package.Register.ChangeLabelText = ChangeLabelText; Thousandto.Package.Register.PeekLabelText = PeekLabelText; Thousandto.Package.Register.ReplaceAtlas = ChangeAtlasLan; Thousandto.Package.Register.ReplaceFont = ChangeFontLan; Thousandto.Package.Register.FlsAction = FlsAction; Thousandto.Package.Register.CreateScriptableObject = CreateScriptableObject; Thousandto.Package.Register.ExportConfigFiles = ExportConfigFiles; Thousandto.Package.Register.NewDisAtlasReference = NewDisAtlasReference; Thousandto.Package.Register.NewDisFontReference = NewDisFontReference; Thousandto.Package.Register.NewPkgBeforeDealForm = NewPkgBeforeDealForm; Thousandto.Package.Register.NewPkgBeforeDealAtlas = NewPkgBeforeDealAtlas; Thousandto.Package.Register.NewPkgBeforeDealFont = NewPkgBeforeDealFont; Thousandto.Package.Register.NewCheckUITexture = NewCheckUITexture; #if UNITY_ANDROID Thousandto.Package.Register.SetBuildTarget(BuildTarget.Android); #elif UNITY_IPHONE Thousandto.Package.Register.SetBuildTarget(BuildTarget.iOS); #elif UNITY_WEBGL Thousandto.Package.Register.SetBuildTarget(BuildTarget.WebGL); #elif UNITY_STANDALONE Thousandto.Package.Register.SetBuildTarget(BuildTarget.StandaloneWindows); #else Thousandto.Package.Register.SetBuildTarget(BuildTarget.NoTarget); #endif } /// <summary> /// 根据语言来改变atlas的replacement /// </summary> /// <param name="old">源atlas</param> /// <param name="replace">用来替换源的atlas</param> private static void ChangeAtlasLan(string old, string replace) { var atlasGo = AssetDatabase.LoadAssetAtPath(old, typeof(UIAtlas)) as UIAtlas; if (atlasGo == null) { UnityEngine.Debug.LogError("ChangeAtlasLan加载失败: " + old); return; } var atlasReference = AssetDatabase.LoadAssetAtPath(replace, typeof(UIAtlas)) as UIAtlas; atlasGo.replacement = atlasReference; EditorUtility.SetDirty(atlasGo); AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); } /// <summary> /// 改变font字体,替换对应语言版本 /// </summary> /// <param name="oldPath"></param> /// <param name="lanPath"></param> private static void ChangeFontLan(string oldPath, string lanPath) { var oldFont = AssetDatabase.LoadAssetAtPath(oldPath, typeof(UIFont)) as UIFont; var ttfAssets = AssetDatabase.LoadAssetAtPath(lanPath, typeof(Font)) as Font; if (oldFont == null) { UnityEngine.Debug.LogError("ChangeFontLan 加载失败: " + oldPath); return; } oldFont.dynamicFont = ttfAssets; EditorUtility.SetDirty(oldFont); AssetDatabase.SaveAssets(); } /// <summary> /// 改变UILabel中的文字,替换语言 /// </summary> /// <param name="go"></param> /// <param name="lanDict">语言数据</param> /// <param name="unFindLanList">没有翻译的中文文字List</param> private static void ChangeLabelText(GameObject go, Dictionary<string, string> lanDict, List<string> unFindLanList) { UILabel[] labels = go.GetComponentsInChildren<UILabel>(true); foreach (UILabel label in labels) { if (label == null) continue; string oldText = label.text; if (oldText.Contains("\r")) oldText = oldText.Replace("\r", ""); if (oldText.EndsWith("\t")) oldText = oldText.TrimEnd('\t'); if (string.IsNullOrEmpty(oldText)) continue; //根据选择语言,将翻译好的内容重新填入到label中 string lanText = ""; if (lanDict.TryGetValue(oldText.Replace("\n", "\\n"), out lanText) && !string.IsNullOrEmpty(lanText)) { label.text = lanText.Replace("\\n", "\n"); } //去掉前后空格再试一次 else if (lanDict.TryGetValue(oldText.Replace("\n", "\\n").Trim(), out lanText) && !string.IsNullOrEmpty(lanText)) { label.text = lanText.Replace("\\n", "\n"); } else { //到这里就是还没找到翻译 string unFindLan = string.Format("Prefab:{0},未找到翻译中文:{1}", go.name, oldText); //判断下是否包含有汉字 if (charactorContainsChinese(oldText)) { if (!unFindLanList.Contains(unFindLan)) { unFindLanList.Add(unFindLan); } } } } if (labels.Length > 0) { EditorUtility.SetDirty(go); AssetDatabase.SaveAssets(); } } /// <summary> /// 收集UILabel上的文字,用来做语音转换 /// </summary> /// <param name="go"></param> /// <param name="lanDict"></param> private static void PeekLabelText(GameObject go, Dictionary<string, string> labelTextDic) { UILabel[] labels = go.GetComponentsInChildren<UILabel>(true); foreach (var label in labels) { string oldText = label.text; oldText = oldText.Replace("\r", "").Replace("\n", "\\n").Replace("\t", ""); //判断是否含有中文,或者已经存放在语言表中了,直接跳过 if (!charactorContainsChinese(oldText) || string.IsNullOrEmpty(oldText)) { continue; } var trimText = oldText.Trim(); //将label中的文字保存起来,等会儿写入到文件中,用于翻译 if (!labelTextDic.ContainsKey(oldText) && !labelTextDic.ContainsKey(trimText)) { labelTextDic.Add(trimText, trimText); } } } /// <summary> /// 生成fls文件和二进制资源 /// </summary> /// <param name="name"></param> /// <param name="language"></param> private static void FlsAction(string name, string language) { FlsUtils.Build(language); List<string> resList = new List<string>(); FlsUtils.CreateBinaryRes(name + "_" + language, out resList); } /// <summary> /// prefab转成ScriptableObject /// </summary> /// <param name="go"></param> /// <param name="useTexName">是否添加额外的文件夹路径</param> /// <returns></returns> private static object[] CreateScriptableObject(GameObject go, bool useTexName, string savePath) { var data = PrefabAssetData.CreateInstance<PrefabAssetData>(); //当GameObject是Vfx路径下的资源时,这里需要设置为true //因为特效贴图会拷贝到Texture/VFX目录下 data = data.FromPrefabGo(go, useTexName, "Texture/VFX/", savePath, CheckAnim); EditorUtility.SetDirty(go); AssetDatabase.SaveAssets(); return new object[] { data, null }; } private static void CheckAnim(AnimListScript anim, string goName, string savePath) { //检查插槽 DIY.UniScene.AnimChangeEditor.FillSlots(anim.gameObject); savePath = savePath.Substring(0, savePath.LastIndexOf("/")); savePath = string.Format("{0}/{1}", savePath, goName); var isPlayer = savePath.Contains("player_"); if(!isPlayer) { anim.AnimTranslate(false); } var animList = new List<string>(); var selfAnimList = new List<string>(); var curAnims = anim.AnimList; var selfAnims = anim.SelfAnimList; //玩家的话不挂载普通动作 if (!isPlayer && curAnims != null && curAnims.Count > 0) { for (int i = 0; i < curAnims.Count; ++i) { var oriAnim = curAnims[i]; if(oriAnim == null) { continue; } var oldPath = AssetDatabase.GetAssetPath(oriAnim); #if UNITY_STANDALONE_WIN if(oriAnim.legacy) { oriAnim.legacy = false; EditorUtility.SetDirty(oriAnim); } animList.Add(oldPath); #else oldPath = oldPath.Replace("Assets/GameAssets/RawResources/", ""); var saveFilePath = string.Format("{0}/{1}", savePath, oldPath); saveFilePath = saveFilePath.Substring(0, saveFilePath.LastIndexOf("/")); if (!Directory.Exists(saveFilePath)) { Directory.CreateDirectory(saveFilePath); } saveFilePath = string.Format("{0}/{1}.anim", saveFilePath, oriAnim.name); if(File.Exists(saveFilePath)) { //文件已经存在,直接添加 animList.Add(saveFilePath); } else { //动作优化 AnimationClip newClip = AnimEventTool.TrimAnimationClip(oriAnim); if (newClip == null) { animList.Add(AssetDatabase.GetAssetPath(oriAnim)); continue; } newClip.name = oriAnim.name; newClip.legacy = false; AnimEventTool.SaveAnim(newClip, saveFilePath); animList.Add(saveFilePath); } #endif } } if (selfAnims != null && selfAnims.Count > 0) { for (int i = 0; i < selfAnims.Count; ++i) { var oriAnim = selfAnims[i]; if (oriAnim == null) { continue; } var oldPath = AssetDatabase.GetAssetPath(oriAnim); #if UNITY_STANDALONE_WIN if(oriAnim.legacy) { oriAnim.legacy = false; EditorUtility.SetDirty(oriAnim); } selfAnimList.Add(oldPath); #else oldPath = oldPath.Replace("Assets/GameAssets/RawResources/", ""); var saveFilePath = string.Format("{0}/{1}", savePath, oldPath); saveFilePath = saveFilePath.Substring(0, saveFilePath.LastIndexOf("/")); if (!Directory.Exists(saveFilePath)) { Directory.CreateDirectory(saveFilePath); } saveFilePath = string.Format("{0}/{1}.anim", saveFilePath, oriAnim.name); if (File.Exists(saveFilePath)) { //文件已经存在,直接添加 selfAnimList.Add(saveFilePath); } else { //动作优化 AnimationClip newClip = AnimEventTool.TrimAnimationClip(oriAnim); if (newClip == null) { selfAnimList.Add(AssetDatabase.GetAssetPath(oriAnim)); continue; } newClip.name = oriAnim.name; newClip.legacy = false; AnimEventTool.SaveAnim(newClip, saveFilePath); selfAnimList.Add(saveFilePath); } #endif } } anim.AnimList = new List<AnimationClip>(); anim.SelfAnimList = new List<AnimationClip>(); if (animList.Count > 0 || selfAnimList.Count > 0) { //挂载优化后的动作 AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); for(int i = 0; i < animList.Count; ++i) { var newClip = AssetDatabase.LoadAssetAtPath<AnimationClip>(animList[i]); if(newClip != null) { anim.AnimList.Add(newClip); } } for (int i = 0; i < selfAnimList.Count; ++i) { var newClip = AssetDatabase.LoadAssetAtPath<AnimationClip>(selfAnimList[i]); if (newClip != null) { anim.SelfAnimList.Add(newClip); } } } } private static void ExportConfigFiles(Action finish, string lan, string version) { DLLComplierEditor.Main.ExecuteCfg(BuildTarget.Android, lan, version, true, false, finish); } public static void ModifyAtlasRefer(GameObject go) { var spriteList = go.GetComponentsInChildren<UISprite>(true); for (int i = 0; spriteList != null && i < spriteList.Length; ++i) { var uiAtlas = spriteList[i].atlas; if (uiAtlas == null) continue; string atlasPath = AssetDatabase.GetAssetPath(uiAtlas.gameObject); if (atlasPath.IndexOf("/Base/") == -1) { string atlasPrefabName = uiAtlas.gameObject.name; atlasPath = string.Format("Assets/GameAssets/Resources/GameUI/Base/Atlas/{0}/{1}.prefab", atlasPrefabName, atlasPrefabName); spriteList[i].atlas = AssetDatabase.LoadAssetAtPath<UIAtlas>(atlasPath); //EditorUtility.SetDirty(spriteList[i].atlas); } } EditorUtility.SetDirty(go); AssetDatabase.Refresh(); AssetDatabase.SaveAssets(); } public static void ChangeLauncherFontToBaseFont(GameObject go) { var labelList = go.GetComponentsInChildren<UILabel>(true); for (int i = 0; labelList != null && i < labelList.Length; ++i) { var font = labelList[i].bitmapFont; if (font == null) continue; string fontPath = AssetDatabase.GetAssetPath(font.gameObject); if (fontPath.IndexOf("/GameUI/") == -1) { string atlasPrefabName = font.gameObject.name; fontPath = ("Assets/GameAssets/Resources/GameUI/Base/Font/UINewMainFont.prefab"); labelList[i].bitmapFont = AssetDatabase.LoadAssetAtPath<UIFont>(fontPath); } } EditorUtility.SetDirty(go); } private static bool charactorContainsChinese(string str) { char[] chars = str.ToCharArray(); foreach (char c in chars) { if ((c >= 0x4e00) && (c <= 0x9fbb)) { return true; } } return false; } private static void DestroyScript<T>(GameObject go) where T : Component { var scripts = go.GetComponentsInChildren<T>(true); for (int i = 0; i < scripts.Length; ++i) { GameObject.DestroyImmediate(scripts[i], true); } EditorUtility.SetDirty(go); } [MenuItem("Test/TestLoadCinematicCH")] static void TestLoadCinematicCH() { Dictionary<string, string> dict = new Dictionary<string, string>(); PeekCinematicCH(dict); } private static void PeekCinematicCH(Dictionary<string, string> dict) { var rootDir = "Assets/StreamingAssets/Cinematics"; var files = Directory.GetFiles(rootDir, "*.bytes"); for (int n = 0; n < files.Length; ++n) { var cs = CinematicSerialize.BinaryDeserialize(Path.GetFileNameWithoutExtension(files[n])); if (cs.ObjList.Count > 0) { PeekCinematicCH(cs.ObjList, dict); } } } private static void PeekCinematicCH(List<CinematicObj> objs, Dictionary<string, string> dict) { for (int i = 0; i < objs.Count; ++i) { var keyFrames = objs[i].KeyframeList; for (int j = 0; j < keyFrames.Count; ++j) { var keyFramData = keyFrames[j].EventData; for (int n = 0; n < keyFramData.Count; ++n) { var param = keyFramData[n].Param; var editParam = keyFramData[n].EditorParam; if (ContainsCH(param)) { param = param.Trim(); if (!dict.ContainsKey(param)) dict.Add(param, param); } if (ContainsCH(editParam)) { editParam = editParam.Trim(); if (!dict.ContainsKey(editParam)) dict.Add(editParam, editParam); } } } } } private static bool ContainsCH(string text) { char[] c = text.ToCharArray(); for (int i = 0; i < c.Length; i++) if (c[i] >= 0x4e00 && c[i] <= 0x9fbb) return true; return false; } //解除atlas引用 private static bool NewDisAtlasReference(string path) { var atlas = AssetDatabase.LoadAssetAtPath(path, typeof(UIAtlas)) as UIAtlas; if (atlas != null && atlas.replacement != null) { //解除成功 atlas.ClearSerializeFields(); EditorUtility.SetDirty(atlas); return true; } return false; } //解除font引用 private static bool NewDisFontReference(string path) { var font = AssetDatabase.LoadAssetAtPath(path, typeof(UIFont)) as UIFont; if (font != null && (font.dynamicFont != null || font.material != null || font.bmFont != null || font.replacement != null)) { //先清理引用,防止清理错误 font.replacement = null; //清理动态字体 font.dynamicFont = null; //清理材质球 font.material = null; //清理bm字体 font.bmFont = null; EditorUtility.SetDirty(font); return true; } return false; } //form打包前处理 private static bool NewPkgBeforeDealForm(string path, Dictionary<string, string> lanCovertDic, GameObject normalFontGo) { var isChange = false; var go = AssetDatabase.LoadAssetAtPath<GameObject>(path); if (go == null) { return isChange; } //收集图集 var _atlasList = new List<UIAtlas>(); var _atlasName = new List<string>(); //收集字体 var _fontList = new List<UIFont>(); var _fontName = new List<string>(); var _animaClipList = new List<AnimationClip>(); var _animatorsControllerList = new List<RuntimeAnimatorController>(); var _playableAssetList = new List<PlayableAsset>(); var normalFont = normalFontGo.GetComponent<UIFont>(); var behaviors = go.GetComponentsInChildren<Behaviour>(true); if (behaviors != null && behaviors.Length > 0) { for (int i = 0; i < behaviors.Length; ++i) { var be = behaviors[i]; var label = be as UILabel; var texture = be as UITexture; var sprite = be as UISprite; var animator = be as Animator; var playable = be as PlayableDirector; if (label != null) { if (label.bitmapFont != null) { var font = label.bitmapFont; //规范label连接的文字 string fontPath = AssetDatabase.GetAssetPath(font.gameObject); if (fontPath.IndexOf("/GameUI/Base/Font") < 0) { //文件资源不在指定目录下,强制设为默认字体 label.bitmapFont = normalFont; isChange = true; } font = label.bitmapFont; if (font != null) { var idx = _fontList.IndexOf(font); if (idx < 0) { _fontList.Add(font); var arr = font.name.Split(new char[] { '/' }); string name = arr[arr.Length - 1]; _fontName.Add(name); } } } if (lanCovertDic != null && !string.IsNullOrEmpty(label.text)) { string oldText = label.text; if (oldText.Contains("\r")) oldText = oldText.Replace("\r", ""); if (oldText.EndsWith("\t")) oldText = oldText.TrimEnd('\t'); if (!string.IsNullOrEmpty(oldText)) { //根据选择语言,将翻译好的内容重新填入到label中 string lanText = ""; if (lanCovertDic.TryGetValue(oldText.Replace("\n", "\\n"), out lanText) && !string.IsNullOrEmpty(lanText)) { lanText = lanText.Replace("\\n", "\n"); if (string.IsNullOrEmpty(lanText)) { //没有找到翻译,需要写日志 PkgLogFile.Write("翻译错误 go={0} name={1} text={2}", go.name, label.name, oldText); } else { label.text = lanText; isChange = true; } } //去掉前后空格再试一次 else if (lanCovertDic.TryGetValue(oldText.Replace("\n", "\\n").Trim(), out lanText) && !string.IsNullOrEmpty(lanText)) { lanText = lanText.Replace("\\n", "\n"); if(string.IsNullOrEmpty(lanText)) { //没有找到翻译,需要写日志 PkgLogFile.Write("翻译错误 go={0} name={1} text={2}", go.name, label.name, oldText); } else { label.text = lanText; isChange = true; } } else { //没有找到翻译 //判断下是否包含有汉字 if (charactorContainsChinese(oldText)) { //没有找到翻译,需要写日志 PkgLogFile.Write("翻译错误 go={0} name={1} text={2}", go.name, label.name, oldText); } } } } } else if (texture != null && texture.mainTexture != null) { //去掉图片 texture.mainTexture = null; isChange = true; } else if (sprite != null) { var uiAtlas = sprite.atlas; if (uiAtlas != null) { string atlasPath = AssetDatabase.GetAssetPath(uiAtlas.gameObject); if (atlasPath.IndexOf("GameUI/Base/Atlas/") == -1) { string atlasPrefabName = uiAtlas.gameObject.name; atlasPath = string.Format("Assets/GameAssets/Resources/GameUI/Base/Atlas/{0}/{1}.prefab", atlasPrefabName, atlasPrefabName); sprite.atlas = AssetDatabase.LoadAssetAtPath<UIAtlas>(atlasPath); isChange = true; } uiAtlas = sprite.atlas; if (uiAtlas != null) { var idx = _atlasList.IndexOf(uiAtlas); if (idx < 0) { _atlasList.Add(uiAtlas); var arr = uiAtlas.name.Split(new char[] { '/' }); string name = arr[arr.Length - 1]; _atlasName.Add(name); } } } } else if(animator != null) { var _animatorController = animator.runtimeAnimatorController; if (_animatorController != null) { _animatorsControllerList.Add(_animatorController); var animationClips = _animatorController.animationClips; if (animationClips != null) { var clipsCnt = animationClips.Length; for (int j = 0; j < clipsCnt; j++) { _animaClipList.Add(animationClips[i]); } } } } else if(playable != null) { var _playableAsset = playable.playableAsset; if(_playableAsset != null) { _playableAssetList.Add(_playableAsset); foreach (var item in _playableAsset.outputs) { var _animationTrack = item.sourceObject as AnimationTrack; if (_animationTrack) { var clips = _animationTrack.GetClips(); foreach (var clipsItem in clips) { var _animationClip = clipsItem.animationClip; if (_animationClip) { _animaClipList.Add(_animationClip); } } } } } } else if (be != null) { var typeName = be.GetType().ToString(); if (typeName.StartsWith("Thousandto.GameUI.Form")) { //自定义脚本,直接删除 GameObject.DestroyImmediate(be, true); isChange = true; } } else if (be == null) { //miss脚本,需要写日志 PkgLogFile.Write("有Miss的脚本 go={0}", go.name); return false; } } } var scriptIns = go.GetComponent<UIFormAssetDataScript>(); if (scriptIns == null) { scriptIns = go.AddComponent<UIFormAssetDataScript>(); } scriptIns.RefAtlasList = _atlasList.ToArray(); scriptIns.RefAtlasNameList = _atlasName.ToArray(); scriptIns.RefFontList = _fontList.ToArray(); scriptIns.RefFontNameList = _fontName.ToArray(); scriptIns.RefAnimClipArray = _animaClipList.ToArray(); scriptIns.RefAnimControllerArray = _animatorsControllerList.ToArray(); scriptIns.RefPlayableAssetArray = _playableAssetList.ToArray(); isChange = true; //删除脚本 if (isChange) { EditorUtility.SetDirty(go); } return isChange; } //atlas打包前处理 private static bool NewPkgBeforeDealAtlas(string path, string lan) { var isChange = false; var atlas = AssetDatabase.LoadAssetAtPath<UIAtlas>(path); if (atlas == null) { return isChange; } var newPath1For = string.Format("Assets/GameAssets/RawResources/uinew/Local/{0}/Atlas/", lan); var oriPathFor = string.Format("Assets/GameAssets/Resources/GameUI_{0}/Base/Atlas/", lan); var oriResPath1 = path.Replace(oriPathFor, newPath1For); var oriResPath2 = path.Replace(oriPathFor, "Assets/GameAssets/RawResources/uinew/Global/Atlas/"); var oriAtlas = AssetDatabase.LoadAssetAtPath<UIAtlas>(oriResPath1); if(oriAtlas != null) { #if UNITY_STANDALONE_WIN var matPath = oriResPath1.Replace(".prefab", ".mat"); var mat = AssetDatabase.LoadAssetAtPath<Material>(matPath); if (mat != null) { oriAtlas.spriteMaterial = mat; EditorUtility.SetDirty(oriAtlas); } #else var matPath = oriResPath1.Replace(".prefab", "_rgb.mat"); var mat = AssetDatabase.LoadAssetAtPath<Material>(matPath); if(mat != null) { oriAtlas.spriteMaterial = mat; EditorUtility.SetDirty(oriAtlas); } #endif atlas.replacement = oriAtlas; isChange = true; } else { oriAtlas = AssetDatabase.LoadAssetAtPath<UIAtlas>(oriResPath2); if(oriAtlas != null) { #if UNITY_STANDALONE_WIN var matPath = oriResPath2.Replace(".prefab", ".mat"); var mat = AssetDatabase.LoadAssetAtPath<Material>(matPath); if (mat != null) { oriAtlas.spriteMaterial = mat; EditorUtility.SetDirty(oriAtlas); } #else var matPath = oriResPath2.Replace(".prefab", "_rgb.mat"); var mat = AssetDatabase.LoadAssetAtPath<Material>(matPath); if (mat != null) { oriAtlas.spriteMaterial = mat; EditorUtility.SetDirty(oriAtlas); } #endif } atlas.replacement = oriAtlas; isChange = true; } if (isChange) { EditorUtility.SetDirty(atlas); } return isChange; } //font打包前处理 private static bool NewPkgBeforeDealFont(string path, string lan, Font normalFont) { var isChange = false; var font = AssetDatabase.LoadAssetAtPath<UIFont>(path); if (font == null) { return isChange; } var newPathFormat = string.Format("Assets/GameAssets/RawResources/uinew/Local/{0}/Fonts/", lan); var oriPathFor = string.Format("Assets/GameAssets/Resources/GameUI_{0}/Base/Font/", lan); var oriResPath = path.Replace(oriPathFor, newPathFormat); var oriResPath2 = oriResPath.Replace(".prefab", ".ttf"); var uiFont = AssetDatabase.LoadAssetAtPath<UIFont>(oriResPath); if (uiFont != null) { //尝试使用fnt文件 font.replacement = uiFont; font.dynamicFont = null; isChange = true; } else { //再次尝试使用ttf文件 var oriFont = AssetDatabase.LoadAssetAtPath<Font>(oriResPath2); if(oriFont != null) { font.dynamicFont = oriFont; font.replacement = null; isChange = true; } else { //尝试使用默认文件 font.dynamicFont = normalFont; font.replacement = null; isChange = true; } } if (isChange) { EditorUtility.SetDirty(font); } return isChange; } //uitexture打包前处理 private static bool NewCheckUITexture(string path) { if(path.Contains("/UI/") && !path.Contains("/Android/") && !path.Contains("/IOS/")) { ChangeUITextureSize.SetTextureFormat(path); } return true; } } }