【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的进阶版。
官方样例:
现将官方示例输入,查看输出情况:
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可以在导入贴图资源时,按照项目规范自动修改贴图属性。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值