Unity 简单打包脚本

打包脚本

这个打包脚本适用于做demo,脚本放在Editor目录下

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

public class BuildAB
{
    [MenuItem("Tools/递归遍历文件夹下的资源并打包")]
    public static void BuildDirectory()
    {
        //需要打包的文件夹路径
        string path = Application.dataPath + "/Res";
        List<string> list = new List<string>();
        GetFilePath(path, ref list);

        List<AssetBundleBuild> mult = new List<AssetBundleBuild>();
        for (int i = 0; i < list.Count; i++)
        {
            string assetName = list[i].Replace(Application.dataPath, "Assets").Replace("\\", "/");
            string bundleName = Path.GetFileNameWithoutExtension(assetName);

            AssetBundleBuild ab = new AssetBundleBuild();
            ab.assetBundleName = bundleName;
            //assetNames记录bundle中所有资源的相对路径
            ab.assetNames = new string[] { assetName };
            mult.Add(ab);

            Debug.Log($"{assetName} {bundleName}");
        }

        string targetPath = Application.streamingAssetsPath;
        if (Directory.Exists(targetPath))
            Directory.Delete(targetPath, true);
        Directory.CreateDirectory(targetPath);

        BuildPipeline.BuildAssetBundles(targetPath, mult.ToArray(),
            BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows64);

        AssetDatabase.Refresh();
    }

    [MenuItem("Tools/遍历文件夹下的资源,处理依赖并打包")]
    public static void BuildDirectoryDependence()
    {
        string path = Application.dataPath + "/Res";
        List<string> list = new List<string>();
        GetFilePath(path, ref list);

        //key 资源路径,value 引用计数
        Dictionary<string, int> abDict = new Dictionary<string, int>();
        for (int i = 0; i < list.Count; i++)
        {
            string assetName = list[i].Replace(Application.dataPath, "Assets").Replace("\\", "/");

            //获取依赖资源,返回相对路径
            string[] dependences = AssetDatabase.GetDependencies(assetName);
            for(int j = 0; j < dependences.Length; ++j)
            {
                if (dependences[j].EndsWith(".cs"))
                {
                    continue;
                }

                Debug.Log($"{assetName} 依赖 {j} => {dependences[j]}");
                if (abDict.ContainsKey(dependences[j]))
                {
                    abDict[dependences[j]]++;
                }
                else
                {
                    abDict.Add(dependences[j], 1);
                }
            }
        }

        var enumerator = abDict.GetEnumerator();
        List<AssetBundleBuild> mult = new List<AssetBundleBuild>();
        while (enumerator.MoveNext())
        {
            string fileName = enumerator.Current.Key;
            int refCount = enumerator.Current.Value;

            string bundleName = Path.GetFileNameWithoutExtension(fileName);
            if(refCount > 1)
            {
                //引用计数大于1的为公共资源,单独打包
                bundleName = "common/" + bundleName;
            }

            AssetBundleBuild ab = new AssetBundleBuild();
            ab.assetBundleName = bundleName;
            //assetNames记录bundle中所有资源的相对路径
            ab.assetNames = new string[] { fileName };
            mult.Add(ab);
        }

        string targetPath = Application.streamingAssetsPath;
        if (Directory.Exists(targetPath))
            Directory.Delete(targetPath, true);
        Directory.CreateDirectory(targetPath);

        BuildPipeline.BuildAssetBundles(targetPath, mult.ToArray(),
            BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows64);

        AssetDatabase.Refresh();
    }

    /// <summary>
    /// 递归获取所有文件路径
    /// </summary>
    public static void GetFilePath(string path, ref List<string> list)
    {
        string[] files = Directory.GetFiles(path);
        for (int i = 0; i < files.Length; i++)
        {
            if (files[i].EndsWith(".cs") || files[i].EndsWith(".meta"))
            {
                continue;
            }

            list.Add(files[i]);
        }

        string[] dirs = Directory.GetDirectories(path);
        for(int i = 0; i < dirs.Length; i++)
        {
            GetFilePath(dirs[i], ref list);
        }
    }
}

在这里插入图片描述
前面的选项不会处理依赖关系,公共资源会打进不同的bundle里
后面的选项会处理依赖资源,引用计数大于1的认为是公共资源,单独打包到common文件夹

加载脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LoadAB : MonoBehaviour
{
    private AssetBundleManifest _manifest;
    private List<string> _abList = new List<string>();
    private Dictionary<string, GameObject> _assetDict = new Dictionary<string, GameObject>();

    void Start()
    {
        LoadManifest();
        LoadGameObject("cube");
    }

    void LoadManifest()
    {
        AssetBundle assetBundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/StreamingAssets");
        _manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
    }

    private void LoadGameObject(string abName)
    {
        if (string.IsNullOrEmpty(abName))
            return;

        abName = abName.ToLower();

		//先加载依赖资源
        string[] dependens = _manifest.GetAllDependencies(abName);
        for (int i = 0; i < dependens.Length; ++i)
        {
            if (!_abList.Contains(dependens[i]))
            {
                AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + dependens[i]);
                _abList.Add(dependens[i]);
            }
        }

        if (!_abList.Contains(abName))
        {
            AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/" + abName);
            _abList.Add(abName);
            _assetDict.Add(abName, ab.LoadAsset<GameObject>(abName));
        }

        if (_assetDict.ContainsKey(abName))
        {
            GameObject.Instantiate(_assetDict[abName]);
        }
    }
}

参考

untiy AssetBundle 依赖关系树

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/213157.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【蓝桥杯】带分数

带分数 题目要求用一个ab/c的形式得到一个值&#xff0c;而且只能在1~9里面不重复的组合。 可以对1~9进行全排列&#xff0c;然后不断划分区间。 #include<iostream> #include<vector> using namespace std; int st[15]; int num[15]; int res; int n;int calc(i…

基于Python实现的滑动验证码自动识别工具源码

滑动验证码识别 今天的目标地址是字节的巨量纵横&#xff0c;目前东家是一家广告营销型的公司&#xff0c;专注于在各大平台投放信息流广告。巨量纵横为字节跳动的广告平台&#xff0c;用于管理推广账户。今天破解一下这个平台的登陆入口&#xff0c;为今后的数据爬取开个头。…

Android 源码编译

一&#xff0c;虚拟机安装 ​ 1.1 进入https://cn.ubuntu.com/download中文官网下载iso镜像 1.2 这里我们下载Ubuntu 18.04 LTS 1.3虚拟VM机安装ubuntu系统&#xff0c;注意编译源码需要至少16G运行内存和400G磁盘空间&#xff0c;尽量设大点 二 配置编译环境 2.1 下载andr…

进行主从复制时出现的异常FATAL CONFIG FILE ERROR (Redis 6.2.6)Reading the configuration file

错误如下所示&#xff1a; FATAL CONFIG FILE ERROR (Redis 6.2.6) Reading the configuration file, at line 1 >>> include/myredis/redis.conf Bad directive or wrong number of arguments出现错误的原因是.conf文件中命令之间缺少空格&#xff0c;如下所示&…

Sharding-Jdbc(4):Sharding-Jdbc分库

1 新建数据库 创建ds_0数据库和ds_1数据库&#xff0c;在两个数据库新建表如下&#xff1a; CREATE TABLE t_order (order_id bigint(20) NOT NULL,user_id bigint(20) NOT NULL,PRIMARY KEY (order_id) ) ENGINEInnoDB DEFAULT CHARSETutf8 COLLATEutf8_bin; 2 新建maven项目…

GAMES101:作业2记录

总览 在上次作业中&#xff0c;虽然我们在屏幕上画出一个线框三角形&#xff0c;但这看起来并不是那么的有趣。所以这一次我们继续推进一步——在屏幕上画出一个实心三角形&#xff0c;换言之&#xff0c;栅格化一个三角形。上一次作业中&#xff0c;在视口变化之后&#xff0…

yolo.txt格式与voc格式互转,超详细易上手

众所周知,yolo训练所需的标签文件类型是.txt的,但我们平时使用标注软件(labelimage等)标注得到的标签文件是.xml类型的,故此xml2txt之间的转换就至关重要了,这点大家不可能想不到,但是网上的文章提供的代码大多数都是冗余,或者难看,难以上手,故此作者打算提供一个相对…

51单片机PWM讲解

前言 51单片机我已经很久没用过了&#xff0c;毕竟是十年前的产物了&#xff0c;但是由于工作室的学弟学妹需要学习&#xff0c;加之马上就要举行循迹小车比赛&#xff0c;很多人反映看不懂PWM&#xff0c;或者看了不会用&#xff0c;于是写一篇文章简单介绍一下。 PWM普遍应…

“B2B+OMS方案”,赋能家电巨头构建BC订单一体化能力,促进业务增长|徐礼昭

某国际知名家电电器品牌&#xff0c;年营收超过5000亿元。该电器企业其整体业务分三大类&#xff1a;线上线下B2B2C业务、线下B2B业务以及DTC零售业务。 随着业务的发展&#xff0c;该电器品牌对2B业务及DTC业务的数字化系统能力支撑需要更加全面和立体&#xff0c;以适应业务…

5个优质免费自然语言处理学习资源 | 语言技术导航

探索并利用我们的5个免费自然语言处理&#xff08;NLP&#xff09;学习资源&#xff0c;更有效地理解和实施自然语言处理技术。适合初学者和进阶者&#xff0c;涵盖基础理论到实际应用。 近年来&#xff0c;随着人工智能&#xff08;AI&#xff09;解决方案的商业应用&#xff…

前后端数据传输格式(上)

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 作为后端&#xff0c;写…

springboot足球社区管理系统

springboot足球社区管理系统 成品项目已经更新&#xff01;同学们可以打开链接查看&#xff01;需要定做的及时联系我&#xff01;专业团队定做&#xff01;全程包售后&#xff01; 2000套项目视频链接&#xff1a;https://pan.baidu.com/s/1N4L3zMQ9nNm8nvEVfIR2pg?pwdekj…

【论文阅读】Bayes’ Rays:神经辐射场的不确定性量化

【论文阅读】Bayes’ Rays&#xff1a;神经辐射场的不确定性量化 1. Introduction2. Related work3. Background3.2. Neural Laplace Approximations 4. Method4.1. Intuition4.2. Modeling perturbations4.3. Approximating H4.4. Spatial uncertainty 5. Experiments & A…

多线程(初阶七:阻塞队列和生产者消费者模型)

一、阻塞队列的简单介绍 二、生产者消费者模型 三、模拟实现阻塞队列 一、阻塞队列的简单介绍 首先&#xff0c;我们都知道&#xff0c;队列是先进先出的一种数据结构&#xff0c;而阻塞队列&#xff0c;是基于队列&#xff0c;做了一些扩展&#xff0c;在多线程有就非常有意…

Task中Wait()和Result造成死锁

在使用Task的时候&#xff0c;一不留神就会造成死锁&#xff0c;而且难以发现&#xff0c;尤其是业务繁多的情况下&#xff0c;一个Task嵌套另一个Task的时候&#xff0c;下面就演示一下&#xff0c;在什么情况下&#xff0c;会产生Wait()和Result的死锁&#xff0c;因此&#…

Java系类 之 String、StringBuffer和StringBuilder类的区别

我 | 在这里 &#x1f575;️ 读书 | 长沙 ⭐软件工程 ⭐ 本科 &#x1f3e0; 工作 | 广州 ⭐ Java 全栈开发&#xff08;软件工程师&#xff09; &#x1f383; 爱好 | 研究技术、旅游、阅读、运动、喜欢流行歌曲 ✈️已经旅游的地点 | 新疆-乌鲁木齐、新疆-吐鲁番、广东-广州…

07、基于LunarLander登陆器的强化学习案例(含PYTHON工程)

07、基于LunarLander登陆器的强化学习&#xff08;含PYTHON工程&#xff09; 开始学习机器学习啦&#xff0c;已经把吴恩达的课全部刷完了&#xff0c;现在开始熟悉一下复现代码。全部工程可从最上方链接下载。 基于TENSORFLOW2.10 0、实践背景 gym的LunarLander是一个用于…

【论文 | 联邦学习】 | Towards Personalized Federated Learning 走向个性化的联邦学习

Towards Personalized Federated Learning 标题&#xff1a;Towards Personalized Federated Learning 收录于&#xff1a;IEEE Transactions on Neural Networks and Learning Systems (Mar 28, 2022) 作者单位&#xff1a;NTU&#xff0c;Alibaba Group&#xff0c;SDU&…

【设计模式-4.1】行为型——观察者模式

说明&#xff1a;本文介绍设计模式中行为型设计模式中的&#xff0c;观察者模式&#xff1b; 商家与顾客 观察者模式属于行为型设计模式&#xff0c;关注对象的行为。以商家与顾客为例&#xff0c;商家有商品&#xff0c;顾客来购买商品&#xff0c;如果商家商品卖完了&#…

go语言学习-并发编程(并发并行、线程协程、通道channel)

1、 概念 1.1 并发和并行 并发:具有处理多个任务的能力 (是一个处理器在处理任务)&#xff0c;cpu处理不同的任务会有时间错位&#xff0c;比如有A B 两个任务&#xff0c;某一时间段内在处理A任务&#xff0c;这时A任务需要停止运行一段时间&#xff0c;那么会切换到处理B任…