Unity AssetBundle打包的代码 Tools 工具(可选择平台)

本文介绍如何通过AssetBundle在iOS和PC平台分别打包资源,实现跨平台资源加载,强调了大小写敏感性问题和命名规范。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.最近为了精简IOS端的安装包,几乎所有超过5M的资源与模型都放在了服务器上,加载方式为AssetBundle,也方便更新客户后期的修改,功能没问题就没开发啥事儿,改图片或者视频或者模型,让美工部改完了,打AB包上传服务器即可,省事儿!

2.打AB包之前要确定好平台,PC与IOS 不能混用,要区分开。不然加载不出来的,把要打包的资源做成 Prefab并打上标签, 形成资源依赖关系,这样就不会丢失资源了,把Prefab 放到 Assets/Resources/Build 目录下即可。

3.下面上打包代码,打包到处路径为  Assets同级目录  AssetBundle 文件夹下。已加入打包进度与提示,已加入MD5校验。

PS:PC平台   AssetBundle加载不区分字母大小写, IOS平台区分大小写!!! 太坑了,浪费我一天开发时间搞这个(第一次做IOS端AB加载) 建议所有资源都小写命名,(什么驼峰命名,蛇形命名,帕斯卡在这都不中用),加载字符串用 String.ToLower

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;

public class AssetBuilder
{
    public static List<string> Select()
    {
        List<string> Selectpaths = new List<string>();
        string[] strs = Selection.assetGUIDs;
        for (int i = 0; i < strs.Length; i++)
        {
            var Selectpath = AssetDatabase.GUIDToAssetPath(strs[i]);

            Selectpaths.Add(Selectpath);
        }

        //UnityEngine.Debug.Log("Selectpath:" + Newtonsoft.Json.JsonConvert.SerializeObject(Selectpaths));
        return Selectpaths;
    }


    //[MenuItem("Assets/BuildAssetBundles/ALL")]
    public static void BuildOldAssetBundle()
    {
#if UNITY_IPHONE
        BuildIOS();
        BuildPC();
#elif UNITY_STANDALONE_WIN
        BuildPC();
        BuildIOS();
#endif
    }

    [MenuItem("Assets/BuildAssetBundles/PC")]
    public static void BuildPC()
    {
        ClearAssetBundlesName();
        List<string> data = GetBuildPath();
        for (int i = 0; i < data.Count; i++)
            SetABName(data[i], Path.GetFileNameWithoutExtension(data[i]));
        string paths = Path.GetDirectoryName(Application.dataPath) + "/AssetBundle/win";
        if (!Directory.Exists(paths))
            Directory.CreateDirectory(paths);
        BuildAssetBundle(paths, BuildTarget.StandaloneWindows);
    }
    [MenuItem("Assets/BuildAssetBundles/IOS")]
    public static void BuildIOS()
    {
        ClearAssetBundlesName();
        List<string> data = GetBuildPath();
        for (int i = 0; i < data.Count; i++)
            SetABName(data[i], Path.GetFileNameWithoutExtension(data[i]));
        string paths = Path.GetDirectoryName(Application.dataPath) + "/AssetBundle/ios";
        if (!Directory.Exists(paths))
            Directory.CreateDirectory(paths);
        BuildAssetBundle(paths, BuildTarget.iOS);
    }

    private static List<string> GetBuildPath()
    {
        string datapath = Application.dataPath + "/Resources/Build";
        DirectoryInfo directoryInfo = new DirectoryInfo(datapath);
        var ass = directoryInfo.GetFiles().ToList();
        List<string> list1 = new List<string>();
        foreach (var item in ass)
        {
            if (item.Extension != ".meta")
            {
                string _Path = item.FullName.Replace("\\", "/").Replace(Application.dataPath, "Assets");
                UnityEngine.Debug.Log(_Path);
                list1.Add(_Path);
            }
        }
        return list1;
    }
    [MenuItem("Assets/BuildAssetBundles/Clear")]
    static void ClearAssetBundlesName()
    {
        //获取所有的AssetBundle名称
        string[] abNames = AssetDatabase.GetAllAssetBundleNames();
        //强制删除所有AssetBundle名称
        for (int i = 0; i < abNames.Length; i++)
        {
            AssetDatabase.RemoveAssetBundleName(abNames[i], true);
        }
    }

    /// <summary>
    /// 设置单个AssetBundle的Name
    /// </summary>
    /// <param name="filePath">路径</param>
    static void SetABName(string assetPath, string bundlename)
    {
        //string importerPath = "Assets" + assetPath.Substring(Application.dataPath.Length);  //这个路径必须是以Assets开始的路径
        AssetImporter assetImporter = AssetImporter.GetAtPath(assetPath);  //得到Asset
        //string tempName = assetPath.Substring(assetPath.LastIndexOf(@"\") + 1);
        //string assetName = tempName.Remove(tempName.LastIndexOf(".")); //获取asset的文件名称
        assetImporter.assetBundleName = bundlename;
    }

    private static void BuildAssetBundle(string Spath, BuildTarget target)
    {
        BuildPipeline.BuildAssetBundles(Spath, BuildAssetBundleOptions.DeterministicAssetBundle, target);//DeterministicAssetBundle
        //刷新编辑器
        AssetDatabase.Refresh();
        UnityEngine.Debug.Log("打包" + target.ToString() + "资源完成!");
        
        DirectoryInfo info = new DirectoryInfo(Spath);
        var files = info.GetFiles("*.manifest", SearchOption.AllDirectories);
        for (int i = 0; i < files.Length; i++)
        {
            files[i].Delete();
        }
        //SetMd5(Spath);
        Process.Start(Spath);
        ClearAssetBundlesName();

    }



    //private static void SetMd5(string spath)
    //{
    //    DirectoryInfo directoryInfo = new DirectoryInfo(spath);
    //    var files = directoryInfo.GetFiles();
    //    List<AssBundleInfo> lists = new List<AssBundleInfo>();
    //    foreach (var item in files)
    //    {
    //        if (item.Extension == ".json") continue;
    //        AssBundleInfo assBundleInfo = new AssBundleInfo();
    //        assBundleInfo.name = Path.GetFileNameWithoutExtension(item.FullName);
    //        assBundleInfo.md5 = GetMD5HashFromFile(item.FullName);
    //        lists.Add(assBundleInfo);
    //    }
    //    if (!File.Exists(spath + "/Versions.json"))
    //    {
    //        File.Create(spath + "/Versions.json").Close();
    //    }
    //    string json = Tools.ObjectToJson(lists);
    //    File.WriteAllText(spath + "/Versions.json", json);
    //}

    /// <summary>
	/// 获取 MD5 值
	/// </summary>
	/// <returns> 返回MD5值.</returns>
	/// <param name="fileName">文件地址 </param>
	private static string GetMD5HashFromFile(string fileName)
    {
        try
        {
            FileStream file = new FileStream(fileName, FileMode.Open);
            System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] retVal = md5.ComputeHash(file);
            file.Close();

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < retVal.Length; i++)
            {
                sb.Append(retVal[i].ToString("x2"));
            }
            return sb.ToString();
        }
        catch (Exception ex)
        {
            throw new Exception("GetMD5HashFromFile() fail,error:" + ex.Message);
        }
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值