Unity 简单打包脚本

news2025/1/21 8:48:32

打包脚本

这个打包脚本适用于做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 依赖关系树

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

构建第一个事件驱动型 Serverless 应用

我相信&#xff0c;我们从不缺精彩的应用创意&#xff0c;我们缺少的把这些想法变成现实的时间和付出。 我认为&#xff0c;无服务器技术真的有助于最大限度节省应用开发和部署的时间&#xff0c;并且无服务器技术用可控的成本&#xff0c;实现了我的那些有趣的想法。 在我 2…

kali学习

目录 黑客法则&#xff1a; 一&#xff1a;页面使用基础 二&#xff1a;msf和Windows永恒之蓝漏洞 kali最强渗透工具——metasploit 介绍 使用永恒之蓝进行攻击 ​编辑 使用kali渗透工具生成远程控制木马 渗透测试——信息收集 域名信息收集 黑客法则&#xff1a; 一&…

Java架构师系统架构设计原则应用

目录 1 导语2 如何设计高并发系统:局部并发原则3 如何设计高并发系统:服务化与拆分4 高可用系统有哪些设计原则?5 如何保持简单轻量的架构-DRY、KISS,YAGNI原则6 如何设计组件间的交互和行为-HCLC,CQS,SOC7 框架层面的发展趋势-约定大于配置想学习架构师构建流程请跳转:…

有源滤波器在矿区配电网中的应用

针对目前有源滤波器应用于矿区谐波治理时电网频率适应能力较低的问题&#xff0c;针对定采样点数字控制系统提出了一种具有频率自适应能力的谐振控制策略。该策略不仅可以实现对电网频率波动的自适应&#xff0c;提高滤波器补偿效果&#xff0c;而且不需要在线对控制器参数进行…

ansible常用模块介绍

ansible运行模块的两种方式 Ad - Hoc 利用 ansible 命令直接完成管理 &#xff0c; 主要用于临时命令使用场景 ansible westos -m shell -a ls /mnt playbook ansible 脚本 &#xff0c; 主要用于大型项目场景 &#xff0c; 需要前期的规划 vim test.yml - hosts: all task…

【Docker】从零开始:13.Docker安装tomcat

Docker】从零开始&#xff1a;13.Docker安装Tomcat 下载Tomcat镜像启动Tomcat镜像新版本Tomcat修改访问Tomact首页 下载Tomcat镜像 [rootdocker ~]# docker pull tomcat Using default tag: latest latest: Pulling from library/tomcat 0e29546d541c: Pull complete 9b829c7…

IDEA加载阿里Java规范插件

IDEA加载阿里巴巴Java开发手册插件&#xff0c;在写代码的时候会自动扫描代码规范。 1、打开Settings 2、打开Plugins 3、搜索Alibaba Java Code Guidelines&#xff08;XenoAmess TPM&#xff09;插件&#xff0c;点击Install进行安装&#xff0c;然后重启IDE生效。 4、鼠标右…

Zabbix 5.0 安装部署

一、系统准备工作&#xff1a; Linux &#xff1a; centos 7 mini zabbix-server版本 5.0 LTS 二、安装配置步骤 系统更新 yum update -y 关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 0 #临时 sed -i s/SELINUXenforcing/SELINU…

User: zhangflink is not allowed to impersonate zhangflink

使用hive2连接进行添加数据是报错&#xff1a; [08S01][1] Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask. User: zhangflink is not allowed to impersonate zhangflink 有些文章说需要修…

烟感监控:这个技巧是真的香,后悔没早点知道!

在现代社会&#xff0c;安全意识的提升成为各行各业关注的焦点之一。特别是在建筑、工业和住宅领域&#xff0c;火灾作为一种突发性、破坏性极强的灾害&#xff0c;给人们的生命和财产安全带来了巨大的威胁。 因此&#xff0c;为了有效预防和应对火灾&#xff0c;烟感监控系统逐…

【Angular开发】Angular中的高级组件

在这个博客中&#xff0c;我将解释Angular中的几个高级组件和机制&#xff0c;它们增强了灵活性、可重用性和性能。 通过熟悉这些高级组件和机制&#xff0c;您可以提高您的Angular开发技能&#xff0c;并在应用程序中利用灵活性、可重用性和性能优化的能力。让我们开始吧&…

iOS ------ 调用高德地图SDK

一&#xff0c;导入第三方库 这里使用CocoaPods安装SDK&#xff0c;方法和前面导入第三方库相同 1.打开终端&#xff0c;cd 文件路径 进入到所创建的项目文件中 2.输入pod init为该项目创建Podfile文件 3.编辑 Podfile 文件 Podfile文件内容如下&#xff1a; platform :ios,…

yolov1网络结构

YOLO神经网络结构如下图所示。把一幅480x480的原图分割成7x749个网格&#xff0c;每个网格要预测两个预选框&#xff08;bounding box&#xff09;的坐标&#xff08;x&#xff0c;y&#xff0c;w&#xff0c;h&#xff09;&#xff0c;其中x和y表示box中心点与该格子边界的相对…

Netty中Channel的isWritable方法理解

目录 初见 深入 需要注意 对待超SIZE情况开源项目怎么做 1、seata中 2、SUMMER中 3、一些资料中 总结 初见 以下是包中注释 Returns true if and only if the I/O thread will perform the requested write operation immediately. Any write requests made when t…

Elasticsearch,Kibana集成,x-pack鉴权配置

Elasticsearch,Kibana集成 Java8环境部署[CentOS7] cd /usr/local/src wget https://repo.huaweicloud.com/java/jdk/8u201-b09/jdk-8u201-linux-x64.tar.gztar -xzvf jdk-8u201-linux-x64.tar.gz -C /usr/local#配置环境变量 vim /etc/profile #文末添加 export JAVA_HOME/us…

PostgreSQL 元组统计与 pgstattuple 优化

第1章 简介 1.1 参考文档 https://www.percona.com/blog/postgresql-tuple-level-statistics-with-pgstattuple/ 1.2 关于pgstattuble 由于Postgres表膨胀会降低数据库性能&#xff0c;因此我们可以通过消除表膨胀来提高其性能。我们可以使用pgstattuple扩展来识别膨胀的表。 这…

DenseNet分类网络改进(添加SPP)--亲测有效

最近&#xff0c;我在做多分类问题。在针对基模型的选择中&#xff0c;我使用了DenseNet作为基本模型。我在阅读论文时&#xff0c;遇到了一种改进方式&#xff1a; 如上图所示&#xff0c;在全连接层之前引入SPP模块&#xff1a; 代码如下&#xff1a; SPP模块代码&#x…

VMware 虚拟机 电脑重启后 NAT 模式连不上网络问题修复

问题描述&#xff1a; 昨天 VMware 安装centos7虚拟机&#xff0c;网络模式配置的是NAT模式&#xff0c;配置好后&#xff0c;当时能连上外网&#xff0c;今天电脑重启后&#xff0c;发现连不上外网了 检查下各个配置&#xff0c;都没变动&#xff0c;突然就连不上了 网上查了…

Flink Flink数据写入Kafka

一、环境准备 flink 1.14写入Kafka&#xff0c;首先在pom.xml文件中导入相关依赖 <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><flink.version>1.14.6</flink.version><spark.version>2.4.3</spa…

MySQL联合查询、最左匹配、范围查询导致失效

服务器版本 客户端&#xff1a;navicat premium16.0.11 联合索引 假设有如下表 联合索引就是同时把多列设成索引&#xff0c;如(empno&#xff0c;ename)在查询的时候就会先按照empno进行查询&#xff0c;再按照ename进行查询其中empno是全局有序&#xff0c;ename是局部有…