当前位置: 首页 > news >正文

Unity构建详解(4)——SBP的依赖后处理

【AddHashToBundleNameTask】

这个Task的作用很明确,给Bundle的名字附加一个Hash值:

  • 根据bundle所包含的asset计算出来一个hash值添加在原来Bundle的末尾
  • 替换了BundleBuildContent.BundleLayout和aa.bundleToAssetGroup中的key

有两个问题,为什么要计算Hash值,以及如何计算。

Hash有两个作用:一是数据压缩;二是数据加密。这里是为了给Bundle的名字加密。

Hash值计算流程:

  • 从BundleBuildContent.BundleLayout中得到bundleName和及该Bundle包含的Asset
    • SBP有一个配置界面,可以配置某个Bundle的Name和哪些Asset同属于某个Bundle
  • 计算该asset的依赖关系得到一个Hash128
    • AssetDatabase.GetAssetDependencyHash来计算

    • 如果有缓存,可以直接从缓存中读取

  • 用所有Asset的Hash128算出来一个RawHash

    •  HashingMethods.Calculate(hashes.ToArray()

 Hash计算算法:

默认的Hash算法是MD5,用的C#的MD5CryptoServiceProvider

另一种是SpookyHash,一种比较新的Hash算法,Unity按照算法原理自己实现的

Hash算法接受的输入是byte[],通常我们需要将输入数据转为byte[],转化的实现看HashingMethods.GetRawBytes。

这里主要是因为要根据依赖计算Hash值,所以才放在后面,如果仅仅根据指定的Bundle的名字来算Hash值,可以去掉这个Task。

【Hash算法】

hash算法不用自己去实现,知道在什么样的情况下用什么样的Hash算法即可:

  • 获取一个文件、图片等的Hash值
    • 使用MD5或SHA系列
  • 获取各种基元数据组合起来的Hash值,例如获取一个类的hash值,或者一系列类的hash值
    • 使用MD5或SHA系列
  • 获取几个int类型的数组组合的Hash值
    • 用简单的乘法Hash,例如计算3个数的hash值,hash = hash *n + x1,hash = hash *n+x2,hash = hash*n +x3。为防止产生hash冲突。一般n取素数,例如31,131,397等,可以每次计算时用不同的n,也可以用相同的n
    • 如果是float和int的混合,先将float乘以100,1000等换算成int
  • 获取一个或多个短字符串的hash值
    • 使用FNV、MurMurHash、FramHash、SpookyHash、xxhash等
    • 内置的String.GetHashCode()

【StripUnusedSpriteSources】

  • 从SpriteData中找到所有需要打包的(PackedSprite)的Sprites的SourceTexture
  • 拿到所有引用的Object
    • 从DependencyData.AssetInfo拿到所有Asset引用的Object
    • 从DependencyData.SceneInfo拿到到所有Scene引用的Object
  • 两者可以选出没被引用的SourceTexture
  • DependencyData.AssetInfo中找到没被引用的sprite对应的SourceTexture的includedObjects,并剔除第一个object,也即sprite对应的object
  • 如果ExtendedAssetData也包含该asset,一样剔除

这里Task存在的主要原因是:指定哪些Asset要被打包时不是一个个指定的,可以指定贴图所在的文件夹,此时文件夹内的贴图都被认为是要打包的Aseert,但实际上可能有些贴图根本不需要被打包,这里就是为了去掉不需要使用的贴图。

【CreateBuiltInShadersBundle】

  • 内置的资源有一个独特的guid
    • UnityBuiltInExtraGuid = "0000000000000000f000000000000000"
  • 从DependencyData.AssetInfo的所有引用的Object中寻找guid等于该内置的guid的Object
  • 从DependencyData.SceneInfo的所有引用的Object中寻找guid等于该内置的guid的Object
  • 获取该资源的类型BuildCacheUtility.GetMainTypeForObjects
    • 依赖计算时有获取Object包含的Type,第一个Type就是MainType
  • 从这些类型中找到资源类型是Shader的Obejct,添加进BundleExplictObjectLayout中
    • m_Layout.ExplicitObjectLocation.Add(usedSet[i], ShaderBundleName)
    • ShaderBundleName可以自己指定

【CreateMonoScriptBundle】

处理流程类同Shader,只是资源类型变成MonoScript,ShaderBundleName变成MonoScriptBundleName。

我们写的每个脚本都会有一个对应的MonoScript,MonoScript.FromMonoBehaviour这个函数能够通过MonoBehaviour对象,找到MonoScript对象。反之,通过MonoScript对象能够找到对应的脚本类。

因此,bundle内不会包含脚本内容数据,有的是MonoScript,进而找到对应的类。

相关文章:

Unity构建详解(4)——SBP的依赖后处理

【AddHashToBundleNameTask】 这个Task的作用很明确,给Bundle的名字附加一个Hash值: 根据bundle所包含的asset计算出来一个hash值添加在原来Bundle的末尾替换了BundleBuildContent.BundleLayout和aa.bundleToAssetGroup中的key 有两个问题&#xff0c…...

使用GO对PostgreSQL进行有意思的多线程压测

前言 针对PostgreSQL进行压缩,有很多相关的工具。有同学又要问了,为何还要再搞一个?比如,pgbench, sysbench之类的,已经很强大了。是的,它们都很强大。但有时候,在一些特殊的场景,可…...

CI/CI实战-jenkis结合gitlab 4

实时触发 安装gitlab插件 配置项目触发器 生成令牌并保存 配置gitlab 测试推送 gitlab的实时触发 添加jenkins节点 在jenkins节点上安装docker-ce 新建节点server3 安装git和jdx 在jenkins配置管理中添加节点并配置从节点 关闭master节点的构建任务数...

修复ubuntu引导

一、制作ubuntu启动U盘 进入启动盘后,点击Try ubuntu,进入U盘的ubuntu系统。 二、配置和添加源 sudo add-apt-repository ppa:yannubuntu/boot-repair && sudo apt-get update三、运行 Boot Repair重新制作引导 sudo boot-repair注意&#x…...

11.Notepad++

文章目录 一、下载和安装设置练习 以前在记事本上写的代码看上去有点累,因为所有的单词看上去都是黑色的,并且当代码出现问题后,它提示第三行,我们还需要一行一行去数。这些问题都可以由一个高级记事本: Notepad 来解…...

实现阻塞队列

import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class Main  { public static void main(String[] args) throws InterruptedException { BlockingQue…...

MySQL8.X驱动datetime映射问题

MySQL8.X驱动datetime映射问题 背景:项目由SSM项目迁移至SpringBoot,对mysql数据库驱动进行了升级导致出现问题。 原因:mysql驱动的8.X版本对数据库类型datetime映射为LocalDateTime。 解决:暂时不升级mysql驱动,mys…...

【Selenium】隐藏元素的定位和操作|隐藏与isDisplay方法

一、selenium 中隐藏元素如何定位? 如果单纯的定位的话,隐藏元素和普通不隐藏元素定位没啥区别,用正常定位方法就行了 但是吧~~~能定位到并不意味着能操作元素(如click,clear,send_keys) 二、隐藏元素 如下图有个输入框…...

视图的作用

目录 视图的作用 创建视图 为 scott 分配创建视图的权限 查询视图 复杂视图的创建 视图更新的限制问题 更新视图中数据的部门编号(视图的存在条件) 限制通过视图修改数据表内容 创建只读的视图 复杂视图创建 oracle从入门到总裁:​​​​​​h…...

动态ip白名单频繁更改问题解决方案

1. 使用静态IP地址:可以通过向ISP申请静态IP地址来解决动态IP地址的变化问题,但是这种方法会比较贵。 2. 使用动态DNS:可以使用动态DNS服务,它可以将动态IP地址映射到一个固定的域名,从而使得动态IP地址处理为域名一直…...

什么是物联网监控平台?部署物联网平台有什么作用?

随着物联网技术的飞速发展,越来越多的企业开始关注并投入到这一领域。物联网监控平台作为连接物理世界与数字世界的桥梁,正逐渐成为企业数字化转型的关键组件。今天,我们将深入探讨物联网监控平台的定义、部署物联网平台的作用,以…...

netty构建udp服务器以及发送报文到客户端客户端详细案例

目录 一、基于netty创建udp服务端以及对应通道设置关键 二、发送数据 三、netty中的ChannelOption常用参数说明 1、ChannelOption.SO_BACKLOG 2、ChannelOption.SO_REUSEADDR 3、ChannelOption.SO_KEEPALIVE 4、ChannelOption.SO_SNDBUF和ChannelOption.SO_RCVBUF 5、Ch…...

Selenium 学习(0.22)——软件测试之小结

Junit 等一系列自动化工具不用啰嗦了,自己就是小白再搞科普就装了。 把后面相关内容看了一下,使用这些测试工具一样编写代码(驱动模块【调用接口的代码片段】,桩模块【响应输出结果的代码片段,也就是被测模块调用的模块…...

贪心算法问题

分发饼干-455 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i ,都有一个胃口值 gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有…...

深入理解 @Transactional 注解在 Spring 中的应用

前言:在 Java 开发中,事务管理是非常重要的一环。Spring 框架提供了Transactional注解来简化事务管理的操作,本文将深入介绍Transactional注解的用法,并结合代码示例进行详细讨论。 1.Transactional 注解简介 Transactional注解是…...

Python爬虫之爬取网页图片

当我们想要下载网页的图片时,发现网页的图片太多了,无从下手,那我们写一个脚本来爬取呗。 这次的脚本是专门针对某个外国网站使用的,因此仅供参考思路。 在测试的过程中,我发现网站使用了发爬虫机制,具体就…...

AI Agent(LLM Agent)入门解读

1. 什么是AI Agent? AI Agent可以理解为一个智能体,包括感知模块、规划决策模块和行动模块,类似于人类的五官、大脑和肢体。它能帮助人类处理复杂的任务,并能根据环境反馈进行学习和调整。 五官可以理解为感知模块,大…...

自动化面试常见算法题!

1、实现一个数字的反转,比如输入12345,输出54321 num 12345 num_str str(num) reversed_num_str num_str[::-1] reversed_num int(reversed_num_str) print(reversed_num) # 输出 54321代码解析:首先将输入的数字转换为字符串&#xff…...

CCF-CSP真题202206-2《寻宝!大冒险!》

题目背景 暑假要到了。可惜由于种种原因,小 P 原本的出游计划取消。失望的小 P 只能留在西西艾弗岛上度过一个略显单调的假期……直到…… 某天,小 P 获得了一张神秘的藏宝图。 问题描述 西西艾弗岛上种有 n 棵树,这些树的具体位置记录在…...

Rust编程(三)生命周期与异常处理

生命周期 生命周期,简而言之就是引用的有效作用域。在大多数时候,我们无需手动的声明生命周期,因为编译器可以自动进行推导。生命周期的主要作用是避免悬垂引用,它会导致程序引用了本不该引用的数据: {let r;{let x …...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

无法与IP建立连接,未能下载VSCode服务器

如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

AspectJ 在 Android 中的完整使用指南

一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...