打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【Unity3d基础】Unity3d自动生成asset bundle name(2)
引言:
上一篇文章介绍了,利用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的进阶版。
官方样例:
现将官方示例输入,查看输出情况:
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using UnityEditor;  
  4.   
  5. public class AutoGenerateAssetBundleNameImproved : AssetPostprocessor  
  6. {  
  7.     static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)  
  8.     {  
  9.         for (int i = 0; i < importedAssets.Length; ++i)  
  10.         {  
  11.             Debug.Log("Imported asset: " + importedAssets[i]);  
  12.         }  
  13.         for (int i = 0; i < deletedAssets.Length; ++i)  
  14.         {  
  15.             Debug.Log("Deleted asset: " + deletedAssets[i]);  
  16.         }  
  17.         for (int i = 0; i < movedAssets.Length; ++i)  
  18.         {  
  19.             Debug.Log("Moved Asset: " + movedAssets[i] + " ---- From: " + movedFromAssetPaths[i]);  
  20.         }  
  21.     }  
  22. }  

在Assets/路径下增删改资源做测试,新建两个测试文件夹Assets/Demo/Resources/PathA,Assets/Demo/Resources/PathB:

分别添加,移动和删除一张测试用的图片资源:

输出结果如下:

考虑到文件移动可能会出现移动文件夹的情况,需要多做一个测试,移动下面文件夹:

从当前路径移动到PathB路径下

可以看到会遍历文件夹 下的3个文件,不过最后文件夹自己也触发了移动move asset,需要人为进行排除。
此处应该有代码:
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using UnityEditor;  
  4. using System.Collections.Generic;  
  5. using System.IO;  
  6.   
  7. public class AutoGenerateAssetBundleNameImproved : AssetPostprocessor  
  8. {  
  9.     static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)  
  10.     {  
  11.         for (int i = 0; i < importedAssets.Length; ++i)  
  12.         {  
  13.             Debug.Log("Imported asset: " + importedAssets[i]);  
  14.             UpdateAssetBundleName(importedAssets[i]);  
  15.         }  
  16.         for (int i = 0; i < deletedAssets.Length; ++i)  
  17.         {  
  18.             Debug.Log("Deleted asset: " + deletedAssets[i]);  
  19.             // 当删除的文件是命名为当前asset bundle name的最后一个文件时,移除asset bundle name  
  20.             AssetDatabase.RemoveUnusedAssetBundleNames();  
  21.             AssetDatabase.Refresh();  
  22.         }  
  23.         for (int i = 0; i < movedAssets.Length; ++i)  
  24.         {  
  25.             Debug.Log("Moved Asset: " + movedAssets[i] + " ---- From: " + movedFromAssetPaths[i]);  
  26.             UpdateAssetBundleName(movedAssets[i]);  
  27.         }  
  28.     }  
  29.   
  30.     static void UpdateAssetBundleName(string filePath)  
  31.     {  
  32.         // 当filePath的输入为.meta文件时,调用AssetImporter.GetAtPath会报错。  
  33.         if (IsBlockedByExtension(filePath))  
  34.         {  
  35.             Debug.Log("UpdateAssetBundleName IsBlockedByExtension: " + filePath);  
  36.             return;  
  37.         }  
  38.   
  39.         AssetImporter importer = AssetImporter.GetAtPath(filePath);  
  40.         if (importer != null)  
  41.         {  
  42.             if (IsBlockedByDirectories(filePath))  
  43.             {  
  44.                 Debug.Log("UpdateAssetBundleName IsBlockedByDirectories: " + filePath);  
  45.                 importer.assetBundleName = "";  
  46.                 return;  
  47.             }  
  48.   
  49.             if (IsBlockedByBlackList(filePath))  
  50.             {  
  51.                 Debug.Log("UpdateAssetBundleName IsBlockedByBlackList: " + filePath);  
  52.                 importer.assetBundleName = "";  
  53.                 return;  
  54.             }  
  55.   
  56.             int position = filePath.LastIndexOf(@"/");  
  57.             string assetBundlePath = filePath.Substring(0, position);  
  58.             importer.assetBundleName = assetBundlePath.Replace('/', '_');  
  59.             importer.assetBundleVariant = "";  
  60.             Debug.Log("UpdateAssetBundleName assetBundleName: " + importer.assetBundleName);  
  61.         }  
  62.     }  
  63.   
  64.     // 黑名单关键字列表,遍历文件夹时忽略   
  65.     static public string[] skip_dirs_all = { "testBlackList" };  
  66.     /// <summary>  
  67.     /// 判断是否被黑名单文件夹列表过滤  
  68.     /// </summary>  
  69.     static bool IsBlockedByBlackList(string filePath)  
  70.     {  
  71.         List<string> PathblackList = new List<string>(skip_dirs_all);  
  72.         string[] folderNames = filePath.Split('/');  
  73.         foreach (string path in PathblackList)  
  74.         {  
  75.             for (int i = 0; i < folderNames.Length; ++i)  
  76.             {  
  77.                 if (string.Compare(path, folderNames[i], true) == 0)  
  78.                     return true;  
  79.             }  
  80.         }  
  81.         return false;  
  82.     }  
  83.   
  84.     // 黑名单后缀名列表,遍历文件夹时忽略   
  85.     static public string[] skip_extensions_all = { ".cs", ".meta" };  
  86.     /// <summary>  
  87.     /// 判断是否被黑名单后缀名列表过滤  
  88.     /// </summary>  
  89.     static bool IsBlockedByExtension(string filePath)  
  90.     {  
  91.         List<string> ExtBlackList = new List<string>(skip_extensions_all);  
  92.         string extension = Path.GetExtension(filePath);  
  93.         foreach(string ext in ExtBlackList)  
  94.         {  
  95.             if (string.Compare(extension.ToLower(), ext, true) == 0)  
  96.                 return true;  
  97.         }  
  98.         return false;  
  99.     }  
  100.   
  101.     /// <summary>  
  102.     /// 判断是否为文件夹  
  103.     /// </summary>  
  104.     static bool IsBlockedByDirectories(string filePath)  
  105.     {  
  106.         return Directory.Exists(filePath);  
  107.     }  
  108. }  
再次测试将图片添加到PathA,移动到PathB,删除图片运行结果如下:
添加到PathA时,asset bundle name:

移动到PathB时,asset bundle name:

小结:
本次介绍的方法可以实现真正自动设置asset bundle name,而无需手动运行脚本。利用AssetPostprocessor的其他接口可以实现更多特殊的自动化处理,比如利用OnPostprocessTexture、OnPreprocessTexture可以在导入贴图资源时,按照项目规范自动修改贴图属性。


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
<a href="http://www.manew.com/forum-53-27-1.html" style="word-wrap: break-word; color: rgb(70, 70, 7
云风的 BLOG: Unity3D asset bundle 格式简析
Asset Bundles vs. Resources: A Memory Showdown – Unity Blog
asp.net Directory生成文件夹
Unity中资源的加载
【厚积薄发】揭开AssetBundle庐山真面目(一)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服