using System; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEditor.U2D; using UnityEngine; using UnityEngine.U2D; using YooAsset.Editor; namespace Stary.Evo.Editor { public class MarkAdressable { private static AssetBundleCollectorPackage package; private static string _packageName; public static string AbsoluteMemberRoot { get { return Application.dataPath + "/Member"; } } public static string RelativeMemberRoot { get { return "Assets/Member"; } } public static void CopyArtScenes() { List artScenes = new List(); string artSceneDataPath = $"Assets/Member/{_packageName}/Config/ArtSceneData.asset"; ArtSceneData artSceneData = AssetDatabase.LoadAssetAtPath(artSceneDataPath); if (artSceneData != null) { artScenes = artSceneData.artScenes; foreach (var artScene in artSceneData.artScenes) { artScene.LoadScenePath(); } } else { Debug.LogError($"UnityEvo:ArtSceneData不存在,无法打包,请检查路径{artSceneDataPath}"); return; } string destPath = $"{AbsoluteMemberRoot}/{_packageName}/Scenes"; if (Directory.Exists(destPath)) { Directory.Delete(destPath, true); } Directory.CreateDirectory(destPath); foreach (var artScene in artScenes) { string scenePath = artScene.scenePath; bool success = CopyUnityAsset(scenePath, $"{RelativeMemberRoot}/{_packageName}/Scenes/{artScene.sceneAsset.name}.unity"); if (success) { Debug.Log("场景复制成功!"); } // string destScenePath = $"{destPath}/{artScene.sceneAsset.name}.unity"; // File.Copy(sceneAsset.path, destScenePath, true); } } /// /// 拷贝Unity资源文件(推荐方法) /// /// 源文件在Assets下的相对路径 /// 目标文件在Assets下的相对路径 /// 是否拷贝成功 public static bool CopyUnityAsset(string sourcePath, string destPath) { if (string.IsNullOrEmpty(sourcePath) || string.IsNullOrEmpty(destPath)) { Debug.LogError("源路径或目标路径为空!"); return false; } if (!AssetDatabase.IsValidFolder(System.IO.Path.GetDirectoryName(destPath))) { Debug.LogError($"目标目录不存在: {System.IO.Path.GetDirectoryName(destPath)}"); return false; } try { // 使用AssetDatabase拷贝资源 bool result = AssetDatabase.CopyAsset(sourcePath, destPath); if (!result) { Debug.LogError($"拷贝失败: {sourcePath} -> {destPath}"); return false; } Debug.Log($"成功拷贝资源: {sourcePath} -> {destPath}"); AssetDatabase.Refresh(); // 刷新资源数据库 return true; } catch (System.Exception e) { Debug.LogError($"拷贝资源时出错: {e.Message}"); return false; } } public static void AddArtMark(Action complete) { _packageName = BuildArtAssetWindow.GetBuildPackageName(); CopyArtScenes(); AssetBundleCollectorPackage assetBundleCollectorPackage = null; foreach (var package in AssetBundleCollectorSettingData.Setting.Packages) { if (package.PackageName == _packageName) { assetBundleCollectorPackage = package; } } if (assetBundleCollectorPackage != null) { YooAsset.Editor.AssetBundleCollectorSettingData.RemovePackage(assetBundleCollectorPackage); } MarkArt(); CollectSVC(AbsoluteMemberRoot, _packageName, complete); } #region 自动标记 public static Dictionary addressDic = new Dictionary(); public static Dictionary collectorGroupDic = new Dictionary(); public static void MarkArt() { addressDic.Clear(); collectorGroupDic.Clear(); ///创建分组 string remotedRoot = $"{AbsoluteMemberRoot}/{_packageName}"; DirectoryInfo[] dirs = new DirectoryInfo(remotedRoot).GetDirectories(); var setting = YooAsset.Editor.AssetBundleCollectorSettingData.Setting; setting.ShowPackageView = true; setting.UniqueBundleName = true; //创建Package文件 package = YooAsset.Editor.AssetBundleCollectorSettingData.CreatePackage(_packageName); //检测Packages是否存在TestPackage package.PackageName = _packageName; package.EnableAddressable = true; package.IncludeAssetGUID = true; package.AutoCollectShaders = true; package.IgnoreRuleName = "NormalIgnoreRule"; //检测Packages是否存在Group foreach (var info in dirs) { string groupName = info.Name; if (info.Name == "Scenes" || info.Name == "Config") { AssetBundleCollectorGroup collectorGroup = YooAsset.Editor.AssetBundleCollectorSettingData.CreateGroup(package, groupName); collectorGroup.AssetTags = groupName; if (!collectorGroupDic.ContainsKey(groupName)) { collectorGroupDic.Add(groupName, collectorGroup); } else { Debug.LogError("分组 : " + groupName + "已存在,请检查资源目录,避免重复"); } AutoMarkRootAddress(info); } } // AssetDatabase.SaveAssets(); // AssetDatabase.Refresh(); MarkStatus(); YooAsset.Editor.AssetBundleCollectorSettingData.SaveFile(); // CreateRes(); Debug.Log("MarkAsset Successful"); } public static void AutoMarkRootAddress(DirectoryInfo dir) { List fileInfos = new List(); FilesUtils.GetFiles(dir.FullName, ref fileInfos); //检测用户config下是否存在config文件 if (dir.Name == "Config") { List fileNewInfos = new List(); foreach (var file in fileInfos) { if (Path.GetExtension(file) != ".meta") { fileNewInfos.Add(file); } } } if (fileInfos != null && fileInfos.Count > 0) { foreach (var file in fileInfos) { if (Path.GetExtension(file) != ".meta" && Path.GetExtension(file) != ".spriteatlas") { // string[] dirSplit = file.Split(new string[] { $"AddressableRes\\{dir.Name}\\" }, // StringSplitOptions.RemoveEmptyEntries); // string address = (dirSplit[dirSplit.Length - 1]).Replace("\\", "/"); // Debug.Log("address:" + address); string groupName = dir.Name; string assetPath = FilesUtils.AbsoluteToRelativePath("Assets", file); //Asset到文件的路径 var guid = AssetDatabase.AssetPathToGUID(assetPath); var group = collectorGroupDic[groupName]; if (group != null) { AssetBundleCollector collector = new AssetBundleCollector() { CollectPath = assetPath, CollectorGUID = guid, CollectorType = ECollectorType.MainAssetCollector, AddressRuleName = nameof(AddressByFolderAndFileName), AssetTags = groupName, }; //TODO 暂时不设置 // 如果是video目录,设置 // if (groupName == "Video") // { // collector.PackRuleName = nameof(PackVideoFile); // } YooAsset.Editor.AssetBundleCollectorSettingData.CreateCollector(group, collector); Debug.Log("GetAssetAddress:" + GetAssetAddress(file)); AddAddressInfo(file, GetAssetAddress(file)); } else { Debug.LogError("分组 = " + groupName + "不存在"); } } } } } private static void AddAddressInfo(string assetPath, string address) { if (addressDic.ContainsKey(assetPath)) { Debug.LogError("命名重复,已经存在:" + assetPath); } else { addressDic.Add(assetPath, address); } } private static string GetAssetAddress(string assetPath) { string fileName = Path.GetFileNameWithoutExtension(assetPath); FileInfo fileInfo = new FileInfo(assetPath); return $"{fileInfo.Directory.Name}_{fileName}"; } #endregion /// /// 标记为资源分组 /// private static void MarkStatus() { List deleteList = new List(); for (int i = 0; i < package.Groups.Count; i++) { var group = package.Groups[i]; if (group.GroupName != "Default Local Group" && group.GroupName != "Built In Data") { if (group.Collectors.Count <= 0) { ///删除没有资源的分组 deleteList.Add(group); } } } for (int i = 0; i < deleteList.Count; i++) { package.Groups.Remove(deleteList[i]); } } public static void CollectSVC(string root, string packageName, Action complete) { string remotedRoot = $"{root}/{packageName}/ShaderVariants"; string remotedRootFileName = $"{remotedRoot}/{packageName}.shadervariants"; if (!Directory.Exists(remotedRoot)) { Directory.CreateDirectory(remotedRoot); AssetDatabase.Refresh(); } string localSavePath = FilesUtils.AbsoluteToRelativePath("Assets", remotedRootFileName); //Asset到文件的路径 System.Action completedCallback = () => { ShaderVariantCollection collection = AssetDatabase.LoadAssetAtPath(localSavePath); if (collection != null) { Debug.Log( $"UnityEvo:【{packageName}】ShaderCount : {collection.shaderCount}"); Debug.Log( $"UnityEvo:【{packageName}】VariantCount : {collection.variantCount}"); CreateShaderVariantsGroup(packageName, localSavePath); complete?.Invoke(); } else { throw new Exception("Failed to Collect shader Variants."); } }; ShaderVariantCollector.Run(localSavePath, packageName, 1000, completedCallback); } // 新增方法:创建独立的ShaderVariants分组(防止多个package冲突) private static void CreateShaderVariantsGroup(string packageName, string localSavePath) { string groupname = $"ShaderVariants_{packageName}"; AssetBundleCollectorGroup collectorGroup = null; // 查找或创建package专属分组 foreach (var package in AssetBundleCollectorSettingData.Setting.Packages) { if (package.PackageName == packageName) { collectorGroup = YooAsset.Editor.AssetBundleCollectorSettingData.CreateGroup(package, groupname); break; } } var guid = AssetDatabase.AssetPathToGUID(localSavePath); AssetBundleCollector collector = new AssetBundleCollector() { CollectPath = localSavePath, CollectorGUID = guid, CollectorType = ECollectorType.MainAssetCollector, AddressRuleName = nameof(AddressByFolderAndFileName), PackRuleName = nameof(PackShaderVariants), FilterRuleName = nameof(CollectShaderVariants), AssetTags = groupname, }; YooAsset.Editor.AssetBundleCollectorSettingData.CreateCollector(collectorGroup, collector); YooAsset.Editor.AssetBundleCollectorSettingData.SaveFile(); } } }