引言:
上一篇文章介绍了,利用System.IO的接口,收集路径下所有文件夹的方式设置asset bundle name,这一次介绍另一种方法。
原理:
经同事提醒,发现Unity有原生的资源管理器AssetPostprocessor,官方描述:AssetPostprocessor lets you hook into the import pipeline and run scripts prior or after importing assets.
其内部提供了很多接口,本次要用到的是OnPostprocessAllAssets,官方描述:This is called after importing of any number of assets is complete (when the Assets progress bar has reached the end).
上一篇文章,收集asset bundle name需要在打包之前,手动执行脚本;而OnPostprocessAllAssets会在每次资源的增删改后自动执行,那么就有了自动设置asset bundle name的进阶版。
官方样例:
现将官方示例输入,查看输出情况:
- using UnityEngine;
- using System.Collections;
- using UnityEditor;
-
- public class AutoGenerateAssetBundleNameImproved : AssetPostprocessor
- {
- static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
- {
- for (int i = 0; i < importedAssets.Length; ++i)
- {
- Debug.Log("Imported asset: " + importedAssets[i]);
- }
- for (int i = 0; i < deletedAssets.Length; ++i)
- {
- Debug.Log("Deleted asset: " + deletedAssets[i]);
- }
- for (int i = 0; i < movedAssets.Length; ++i)
- {
- Debug.Log("Moved Asset: " + movedAssets[i] + " ---- From: " + movedFromAssetPaths[i]);
- }
- }
- }
在Assets/路径下增删改资源做测试,新建两个测试文件夹Assets/Demo/Resources/PathA,Assets/Demo/Resources/PathB:
分别添加,移动和删除一张测试用的图片资源:
输出结果如下:
考虑到文件移动可能会出现移动文件夹的情况,需要多做一个测试,移动下面文件夹:
从当前路径移动到PathB路径下
可以看到会遍历文件夹 下的3个文件,不过最后文件夹自己也触发了移动move asset,需要人为进行排除。
此处应该有代码:
- using UnityEngine;
- using System.Collections;
- using UnityEditor;
- using System.Collections.Generic;
- using System.IO;
-
- public class AutoGenerateAssetBundleNameImproved : AssetPostprocessor
- {
- static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
- {
- for (int i = 0; i < importedAssets.Length; ++i)
- {
- Debug.Log("Imported asset: " + importedAssets[i]);
- UpdateAssetBundleName(importedAssets[i]);
- }
- for (int i = 0; i < deletedAssets.Length; ++i)
- {
- Debug.Log("Deleted asset: " + deletedAssets[i]);
- // 当删除的文件是命名为当前asset bundle name的最后一个文件时,移除asset bundle name
- AssetDatabase.RemoveUnusedAssetBundleNames();
- AssetDatabase.Refresh();
- }
- for (int i = 0; i < movedAssets.Length; ++i)
- {
- Debug.Log("Moved Asset: " + movedAssets[i] + " ---- From: " + movedFromAssetPaths[i]);
- UpdateAssetBundleName(movedAssets[i]);
- }
- }
-
- static void UpdateAssetBundleName(string filePath)
- {
- // 当filePath的输入为.meta文件时,调用AssetImporter.GetAtPath会报错。
- if (IsBlockedByExtension(filePath))
- {
- Debug.Log("UpdateAssetBundleName IsBlockedByExtension: " + filePath);
- return;
- }
-
- AssetImporter importer = AssetImporter.GetAtPath(filePath);
- if (importer != null)
- {
- if (IsBlockedByDirectories(filePath))
- {
- Debug.Log("UpdateAssetBundleName IsBlockedByDirectories: " + filePath);
- importer.assetBundleName = "";
- return;
- }
-
- if (IsBlockedByBlackList(filePath))
- {
- Debug.Log("UpdateAssetBundleName IsBlockedByBlackList: " + filePath);
- importer.assetBundleName = "";
- return;
- }
-
- int position = filePath.LastIndexOf(@"/");
- string assetBundlePath = filePath.Substring(0, position);
- importer.assetBundleName = assetBundlePath.Replace('/', '_');
- importer.assetBundleVariant = "";
- Debug.Log("UpdateAssetBundleName assetBundleName: " + importer.assetBundleName);
- }
- }
-
- // 黑名单关键字列表,遍历文件夹时忽略
- static public string[] skip_dirs_all = { "testBlackList" };
- /// <summary>
- /// 判断是否被黑名单文件夹列表过滤
- /// </summary>
- static bool IsBlockedByBlackList(string filePath)
- {
- List<string> PathblackList = new List<string>(skip_dirs_all);
- string[] folderNames = filePath.Split('/');
- foreach (string path in PathblackList)
- {
- for (int i = 0; i < folderNames.Length; ++i)
- {
- if (string.Compare(path, folderNames[i], true) == 0)
- return true;
- }
- }
- return false;
- }
-
- // 黑名单后缀名列表,遍历文件夹时忽略
- static public string[] skip_extensions_all = { ".cs", ".meta" };
- /// <summary>
- /// 判断是否被黑名单后缀名列表过滤
- /// </summary>
- static bool IsBlockedByExtension(string filePath)
- {
- List<string> ExtBlackList = new List<string>(skip_extensions_all);
- string extension = Path.GetExtension(filePath);
- foreach(string ext in ExtBlackList)
- {
- if (string.Compare(extension.ToLower(), ext, true) == 0)
- return true;
- }
- return false;
- }
-
- /// <summary>
- /// 判断是否为文件夹
- /// </summary>
- static bool IsBlockedByDirectories(string filePath)
- {
- return Directory.Exists(filePath);
- }
- }
再次测试将图片添加到PathA,移动到PathB
,删除图片运行结果如下:添加到PathA时,asset bundle name:
移动到PathB时,asset bundle name:
小结:
本次介绍的方法可以实现真正自动设置asset bundle name,而无需手动运行脚本。利用AssetPostprocessor的其他接口可以实现更多特殊的自动化处理,比如利用OnPostprocessTexture、OnPreprocessTexture可以在导入贴图资源时,按照项目规范自动修改贴图属性。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。