Unity的Addressables学习日志

1.构建Player的时候,项目的资产数据是如何放进Player中的 由下图可以看出来Unity中的资产分成了4个主要类别: 1.被场景引用的资源 2.放在Resources文件夹中的资源 3.标记为了Addressables Group的资源 4.放在了StreamingAssets文件夹中的资源 2.如果同一个资产被划分到了不止一个类别上,那么该资产在构建的时候就会产生重复,划分了多少个就会复制多少个 3.Addressables Groups中的共享资产 对于一个标记为非Adressables的资产,如果有不止一个Adressablees的资产引用了它,那么它会在每个引用了它的Addressables的bundle中都复制一份。如下图所示: 为了消除这种复制,那么可以将这个共有的资产也标记为Addressables。然后把它引入到一个已存在的bundle中就可以了。如果此时一个bundle要引用它,那么必须在该bundle实例化前,将引入了共有资产的bundle先加载才可以。 4.Sprite的依赖 图集的引用跟其他资产不一样。 情形一 三张纹理,分别在三个不同的group中,它们会分别进入三个不同的ab包,彼此之间没有依赖,每个ab中图片的大小是500KB 情形二 还是这三张图片,它们被放进了一个图集,这个图集没有被标记为Addressables。那么包含这个图集的ab包将有图集的1500KB的大小。而另外两个ab包则只包含Sprite的元数据(只有很小的几KB),并且将包含图集的ab包列为自己的依赖。无论是哪个ab包包含这个图集,在重新构建之后都是跟前面一样的结果,这个过程由Unity控制,用户决定不了。这是跟标准的处理依赖重复资源过程的最大不同。Sprites的加载依赖它的图集,而图集的加载只依赖包含它的ab包的加载。 情形三 在上面的情形二的基础上,图集被标记成了Addressables并且单独放在它自己的图集中。这时候就会创建4个ab包。如果使用的是Unity2020.x或者更新的版本,那么在构建之后,4个ab包之间的依赖关系会和期待的一样,即图集资源在图集的这个ab包,有1500KB。另外三个ab包把图集的ab包作为依赖,只有几KB的引用数据而已。如果使用的是Unity2019.x或者更旧的版本,那么纹理资源就可能存在于这4个ab包中的某一个。另外三个ab包依然把图集所在的ab包作为依赖。然而此时图集所在的ab包可能仅仅只包含了图集的一些元数据,而真正的纹理资源可能在其他的另外3个ab包中。 5.Addressable预制体跟Sprite的依赖 情形一 跟三个标记为Addressables的纹理不同的是,这里是三个标记为Addressables的Sprite的预制体。每个预制体包含它独自的Sprite。在构建之后,三个ab包的大小如期望的那样,都是500KB。 情形二 跟情形一类似,3个预制体分别引用不同的Sprite,只不过所有的3个Sprite添加到一个图集中,但是这个图集没有标记为Addressables。在这种情形下,图集的纹理机会产生重复。在构建之后,三个ab包都大概有1500KB。这个重复资源的规则类似于一般的Addressables重复资源规则,但是跟前面介绍的 Sprite的依赖 中的情形二又不一样。 情形三 基于上面的情形二的预制体,纹理和图集,不过这里把图集标记为Addressables。此时图集纹理就仅仅只存在在包含图集的ab包中。另外的三个预制体的ab包就把这个图集的ab包作为依赖。 6.ab包的分包规则 1.可以将一个group中所有Addressables的资源都打进一个ab包中 2.可以将一个group中的每个Addressables资源分别打进它独自的ab包中 3.可以将使用同一个label的所有的Addressables资源打包进一个ab包中 7.同一个group中的场景资源会跟其他的Addressables资源分开打包 也就是说一个group中如果含有场景资源和其他非场景资源,那么构建之后,至少会得到两个bundle,一个包含场景资源,一个是除了场景外的其他资源。

August 29, 2023 · 1 min · 35 words · LINK

Ubuntu22.04运行unity2020.3.xx报错unity_csc.sh_Aborted

在Ubuntu22.04中出现,而且出现这个错误的版本是低于Unity2022.x的版本。自己测试了Unity2020.x和Unity2021.x都会出现这个错误。 重现的步骤也很简单,创建一个空项目并进入就会报错,然后提示进入safety mode。 这个错误会在Unity的Editor.log中留下线索,不过在打开项目前,记得先把Editor.log先删除,这样在报错的时候会生成一个新的Editor.log文件。也可以不用这样做,这样做的主要目的是日志少检查起来比较简单。 打开Unity编辑器的日志:Editor.log。发现以下关键信息 -----CompilerOutput:-stderr---------- No usable version of the libssl was found /home/eyap/Unity/Hub/Editor/2020.3.33f1/Editor/Data/Tools/RoslynScripts/unity_csc.sh: line 3: 25959 Aborted (core dumped) "/home/eyap/Unity/Hub/Editor/2020.3.33f1/Editor/Data/Tools/RoslynScripts/../../Tools/Roslyn/csc" /shared /noconfig @temp/UnityTempFi -----EndCompilerOutput--------------- 从 No usable version of the libssl was found 可以看出是缺少了 libssl库导致的。用下面的命令安装一个就行了: echo "deb http://security.ubuntu.com/ubuntu focal-security main" | sudo tee /etc/apt/sources.list.d/focal-security.list sudo apt-get update sudo apt-get install libssl1.1 相关的讨论连接: https://forum.unity.com/threads/unity2020-3-doesnt-works-on-linux.1338869/

August 29, 2023 · 1 min · 55 words · LINK

Xlua集成第三方库

XLua集成第三方库(Rapidjson举例) 参考教程:https://zhuanlan.zhihu.com/p/389424029 1.环境准备 (1)cmake的安装 https://cmake.org/download/ (2)安装Visual Studio最新版(2017,2019,2022)都行,去微软官网下载 (3)安卓的话,下载Android Studio,然后安装好Android SDK,NDK,并且配置好ANDROID_SDK和ANDROID_NDK 2.将XLua克隆到本地 xlua的地址 https://github.com/Tencent/xLua 进入到拉取下来的xlua文件夹, 在build文件夹中新建lua-rapidjson文件夹,并在该文件夹下新建include和source文件夹 4.拉取lua-rapidjson的项目到本地 这里需要说明一下,lua-rapidjson两个版本: 一个是原作者的最新版 https://github.com/xpol/lua-rapidjson 另一个是XLua的做过兼容的版本: https://github.com/chexiongsheng/build_xlua_with_libs 新版肯定是更新,但是再编译的过程中会遇到很多错误,非常的麻烦浪费时间,所以我们还是选择XLua做过兼容的版本,节省时间,并且也能满足要求。 将build_xlua_with_libs克隆到本地。 5,直接将build_xlua_with_libs中build文件夹下的lua-rapidjson文件夹复制到自己的xlua的build文件夹下面。 6.修改xlua/build/CMakeList.txt文件,在头部加入如下代码 #begin lua-rapidjson set (RAPIDJSON_SRC lua-rapidjson/source/rapidjson.cpp ) set_property( SOURCE ${RAPIDJSON_SRC} APPEND PROPERTY COMPILE_DEFINITIONS LUA_LIB ) list(APPEND THIRDPART_INC lua-rapidjson/include) set (THIRDPART_SRC ${THIRDPART_SRC} ${RAPIDJSON_SRC}) #end lua-rapidjson 并且把头部的VERSION 改成自己的cmake版本(在控制台输入cmake –version),我这里是cmake_minimum_required(VERSION 3.26.4) 6.编译windows的xlua.dll 这里我们选择lua54版本 所有编译脚本都是按这个方式命名:make_平台_lua版本.后缀。 比如windows 64位lua53版本是make_win64_lua53.bat,android的luajit版本是make_android_luajit.sh,要编译哪个版本就执行相应的脚本即可。 执行完编译脚本会自动拷贝到plugin_lua53或者plugin_luajit目录,前者是lua53版本放置路径,后者是luajit。 用代码编辑器打开这个bat文件,将Visual Studio版本改成自己安装的对应版本, 如果不知道就打开 Developer Command Prompt这个控制台,里面会有如图所示 修改完后如下所示 然后运行这个bat文件,注意看控制台输出日志,如果没有什么错误,并且有如下图中的第三库编译的输出,那就说明成功了 跟据日志可以知道,下图的文件夹是临时生成的,每次编译记得先把这两个文件夹删除,不同的平台的编译,这两个文件夹的名字会不一样,编译前记得删除 7.编译成功后,记得查看日志 生成的xlua.dll会复制到 build/plugin_lua54/Plugins文件夹中, 将其中的文件全部复制到Unity的Plugins文件夹下面即可...

July 13, 2023 · 1 min · 211 words · Link

Unity编辑器为切换平台,工程加载完成事件添加自动处理

有时候我们在Unity项目中,需要在切换平台后,或者项目加载完后,做一些自动化的处理,比如项目加载完后检测一些配置,或者检测项目版本。或者在切换项目平台的时候,需要跟据不同的平台设置不同的字体移除不属于该平台的一些资源等等。下面记录一下如何添加对这两个事件的处理。 1.Unity切换平台事件的处理 要处理这个事件,我们需要将类实现 IActiveBuildTargetChanged 接口,并重写该接口的 OnActiveBuildTargetChanged方法。那么当切换平台的时候,就会执行这个类的 OnActiveBuildTargetChanged 方法。在这个方法中,我们就可以添加自定义的一些处理逻辑了。代码如下: /// <summary> /// 切换平台后,对一些资源的处理 /// 有些资源只有再特定的平台才会使用,再切换平添后,不要的资源要移除或者移动到别的地方 /// </summary> public class BuildTargetChangedTool : IActiveBuildTargetChanged { public int callbackOrder { get; } public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget) { //切换平台后的一些处理 PlatformResTool.ProcessFonts(newTarget); PlatformResTool.ProcessThirdSDK(newTarget); LinkXmlBuildProcessor.LinkXmlOp(newTarget); AssetDatabase.Refresh(); } } 2.Unity项目加载完事件的处理 项目加载完成的事件跟切换平台的事件的处理方式不一样,这里需要使用 InitializeOnLoad 这个特性来实现。我们需要给类添加这个特性,同时它需要一个静态构造方法,当项目加载完成后,Unity编辑器就会调用这个静态构造方法,然后在这个静态构造方法中我们就可以添加一些自己的处理逻辑了。代码如下: /// <summary> /// 工程加载完,要处理这些跟平台相关的资源 /// </summary> [InitializeOnLoad] public class StartUpTools { static StartUpTools() { if (!EditorApplication.isPlayingOrWillChangePlaymode) { BuildTarget buildTarget = Packager.GetBuildTarget(); PlatformResTool.ProcessFonts(buildTarget); PlatformResTool.ProcessThirdSDK(buildTarget); LinkXmlBuildProcessor.LinkXmlOp(buildTarget); AssetDatabase....

June 26, 2023 · 1 min · 74 words · Link

XLua框架,Unity3D,WEBGL,报错ArgumentException-Destination-array-was-not-long-enough

Unity使用XLua框架,打WEBGL包,运行时报错:ArgumentException: Destination array was not long enough 具体的错误如下: dangerArgumentException: Destination array was not long enough. Check destIndex and length, and the array's lower bounds {: .prompt-danger } 由于我们UI使用的时FGUI,所以这个错误的具体表现是: 错误表现 在编辑器中运行良好,没有任何问题 打包成WEBGL运行就报这个错,但不是每次都报错, 如果报错,那么UI逻辑是正常的,如果不报错,那么UI逻辑异常,比如按钮的绑定事件错乱 解决办法 我在XLua的Issue中,找到了大佬的解决办法。是XLua在释放资源时的Lock操作引起的。原issue地址。但是大佬的贴的代码,不能直接运行,需要稍加修改才行【大佬可能给的时伪代码】。我在这里把解决步骤归纳一下: 1.添加一个非锁互斥队列【也可以不用添加,就用系统的也行】: using System.Threading; namespace XLua { public class LockFreeQueue<T> { internal class SingleLinkNode<U> where U : T { public SingleLinkNode<U> Next; public U Item; } static private bool CAS<T>(ref T location, T comparand, T newValue) where T : class { return comparand == Interlocked....

October 31, 2022 · 2 min · 376 words · Link