Unity3D AssetBundles 动态加载游戏资源

2023-11-09

AssetBundles are files which you can export from Unity to contain assets of your choice. These files use a proprietary compressed format and can be loaded on demand in your application. This allows you to stream content like models, textures, audio clips and even entire scenes separately from the scene in which they will be used. They have been designed to make it easy to download content to your application.

在一些大型的网络游戏,或者加载比较多的一些场景时,如果要等待所有模型,贴图等各种资源文件加载完毕才能执行游戏,对用户将会是一个很头大的事情。所以就需要用到动态加载,即AssetBundles。比如玩家在进入游戏时先加载一些周围的场景文件,这样不仅可以提高速度还可以减少内存资源的消耗。

AssetBundles是可以把unity3d中你所创建的文件或任何资源导出的一种文件格式,这些文件导出后使用的是一种特定的文件格式(.Unity3d),这些特定格式的文件能在需要的时候加载到场景中。而这些特定的文件格式可以是模型,贴图,声音文件甚至是场景文件,它们是先前就被设计好的文件,所以很容易就可以被下载到你所建立的游戏或场景中来。

AssetBundles can contain any kind of asset type recognized by Unity, as determined by the filename extension. If you want to include files with custom binary data, then you must rename those files to have ".bytes" as the extension. Unity will import these files as TextAssets.

AssetBundles 可以是任意类型的文件只要是unity3d能识别的资源文件格式,识别主要是以文件扩展名为准,比如.prefab等等。当然如果你想包含自定义的二进制文件,需要命名这些文件为以".bytes"为后缀,Unity将会把这些文件导成TextAssets。

For some sample code showing how to use asset bundles, see the AssetBundles Example Project

如果想了解更多关于代码如何实现,可以参考 AssetBundles Example Project

Creating AssetBundles 创建资源包

There are three class methods you can use to build AssetBundles: BuildPipeline.BuildAssetBundleBuildPipeline.BuildStreamedSceneAssetBundleand BuildPipeline.BuildAssetBundleExplicitAssetNames..

有三个类方法可以用来构建资源包:BuildPipeline.BuildAssetBundleBuildPipeline.BuildStreamedSceneAssetBundle 和BuildPipeline.BuildAssetBundleExplicitAssetNames.

  • BuildPipeline.BuildAssetBundle allows you to build AssetBundles of any type of asset. 
    可以构建任意类型资源的资源包。【创建一个压缩好的包含Assets下的所有资源文件.unity3d。可以包含是项目目录下的任意资源,而把所有的资源压缩成一个.unity3d的文件,这个文件包括所有的预置物体(prefabs),纹理贴图(textures),模型,动画。使用AssetBundle.mainAsset这个函数可以很方便的让你指定一个定义好的物体。被压缩的资源储存在pathName. Options,会自动的允许用户包含相关的或者需要用到的】
  • BuildPipeline.BuildStreamedSceneAssetBundle is used when you want to include only scenes to be streamed and loaded as the data becomes available. 
    用来当你希望只包括流场景,使数据加载变为可用。【建立一个或多个场景,这些场景所需要的所有资源将被压缩入资源包,即asset bundle里面。资源包中的场景文件可以在任何平台上建立,而且这些文件往往是以一个单一的unity3d文件格式被用来创建。使用WWW类可以下载场景文件。当场景文件被下载好可以使用WWW.LoadFromCacheOrDownload来加载下载好的场景文件。】
  • BuildPipeline.BuildAssetBundleExplicitAssetNames is the same as BuildPipeline.BuildAssetBundle but has an extra parameter to specify a custom string identifier (name) for each object. 
    和BuildPipeline.BuildAssetBundle类似,但是有额外的参数来指定每个物体的自定义的字符串(名字)。【建立一个自定义名字的资源包方法: 创建一个包含所有资源的一个压缩好的unity3d文件。AssetBundle可以包括任何项目目录下的资源文件。在assetNames参数中提供一个与资源数目相同大小的字符串数组。在资源数组中存储的信息与资源文件名相同,可以传递AssetBundle.Load去加载一个指定的资源。使用BuildAssetBundle时,只需使用资源的路径名。压缩好的资源包文件将会被储存在pathName. Options,允许用户自动包含与之相关的或者总是包含完整的资源去代替确切的参照物体。】

当使用上面的三个函数做完准备工作,我们现在就需要去下载这些资源然后加载它们。

Downloading AssetBundles 下载资源包

The recommended way to download AssetBundles is to use WWW.LoadFromCacheOrDownload. Once the download is complete you can retrieve the AssetBundle with the assetBundle property. For example:

推荐使用WWW.LoadFromCacheOrDownload方法用来下载资源。当下载完成你就可以重新得到该资源的相关属性,例如:

string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d"; IEnumerator Start () {     // Start a download of the given URL 	// 从指定路径下载     WWW www = WWW.LoadFromCacheOrDownload (url, 1);      // Wait for download to complete 	// 等待下载完成     yield return www;      // Load and retrieve the AssetBundle 	// 加载并取回资源包     AssetBundle bundle = www.assetBundle; }

 

When you access the .assetBundle property the downloaded data is extracted and the AssetBundle object is created. At this point, you are ready to load the objects contained in the bundle. The second parameter passed to LoadFromCacheOrDownload specifies which version of the AssetBundle to download. LoadFromCacheOrDownload will download the AssetBundle if it doesn't exist in the cache or if it exists but is associated with a version that is lower than the one requested. Otherwise the AssetBundle will be loaded from cache.

以上代码中的url是资源路径的下载地址,首先使用LoadFromCacheOrDownload下载资源,括号中的url是路径,1代表版本号,当等待下载完成后即可加载相关资源。

当资源包中的对象创建好之后,就可以激活下载好的资源被解压。到这里,就需要用户去加载包含在资源包器中的对象。LoadFromCacheOrDownload函数中的第二个参数是指定下载资源的版本号。如果在存储器中的资源没有被下载或者资源下载了但是比需要资源的版本号低,LoadFromCacheOrDownload函数将会下载资源到资源包中。否则资源包其将会直接从存储器中加载。

Loading and unloading objects from an AssetBundle 从资源包加载和卸载对象

Having created an AssetBundle object from the downloaded data, you can load the objects contained in it using three different methods:AssetBundle.LoadAssetBundle.LoadAsync and AssetBundle.LoadAll.

如果下载数据已经建立了资源包,你就可以使用这三个不同的函数来加载物体了: AssetBundle.LoadAssetBundle.LoadAsync 和 AssetBundle.LoadAll.

  • AssetBundle.Load will load an object using its name identifier as a parameter. The name is the one visible in the Project view. You can optionally pass an object type as an argument to the Load method to make sure the object loaded is of a specific type. 
    AssetBundle.Load会加载物体,使用该物体的名字作为识别的参数。名字可以在Unity3d中Project view看到。你可以自由选择去传递对象变量的类型来确认该加载对象是否是被指定的类型。
  • AssetBundle.LoadAsync works the same as the Load method described above but it will not block the main thread while the asset is loaded. This is useful when loading large assets or many assets at once to avoid pauses in your application. 
    AssetBundle.LoadAsync 与AssetBundle.Load 函数相类似,但是当资源加载时它不会阻碍主线程。如果同时要加载比较大的资源或者很多资源时,这个函数会比较有用,它可以避免程序的暂停,因为它会同步加载。
  • AssetBundle.LoadAll will load all the objects contained in your AssetBundle. As with AssetBundle.Load, you can optionally filter objects by their type. 
    AssetBundle.LoadAll 顾名思义这个函数是用来加载所有在你资源包中的对象。作为AssetBundle.Load这个函数,你可以随意用该对象的类型去过滤。

To unload assets you need to use AssetBundle.Unload. This method takes a boolean parameter which tells Unity whether to unload all data (including the loaded asset objects) or only the compressed data from the downloaded bundle. If your application is using some objects from the AssetBundle and you want to free some memory you can pass false to unload the compressed data from memory. If you want to completely unload everything from the AssetBundle you should pass true which will destroy the Assets loaded from the AssetBundle.

使用AssetBundle.Unload这个函数可以卸载加载好的资源,这个函数有一个布尔值的参数是用来告诉Unity是否要卸载所有的数据(包含加载的资源对象)或者只是已经下载过的被压缩好的资源数据。如果要在资源包中从你的应用程序要使用一些对象或者你想释放一些内存,可以传递false这个值来卸载已经压缩好了的文件从你的内存中(即.unity3d文件)。如果要完全卸载所有的资源数据,需要传递true这个值,这将会销毁所有的资源包器中加载的资源。

Listing objects in an AssetBundle 从资源包列表物体

You can use AssetBundle.LoadAll to retrieve an array containing all objects from the AssetBundle. It is not possible to get a list of the identifiers directly. A common workaround is to keep a separate TextAsset with a known name to hold the names of the assets in the AssetBundle.

可以使用AssetBundle.LoadAll 去取回资源包中包含的所有对象的数组。不可能直接就取回一个列表。通常的做法是保持一个单独的TextAsset,这个TextAsset是控制资源包中资源的名称。

Instantiating objects from AssetBundles 从资源包实例化物体

Once you have loaded an object from your AssetBundle, you can instantiate it in your scene with the Instantiate function.

下载了资源,也加载好了,那么就该在场景中使用Instantiate函数去实例化它了。

string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d"; IEnumerator Start () {     // Start a download of the given URL 	// 开始从指定路径下载     WWW www = WWW.LoadFromCacheOrDownload (url, 1);      // Wait for download to complete 	// 等待下载完成     yield return www;      // Load and retrieve the AssetBundle 	// 加载并取回资源包     AssetBundle bundle = www.assetBundle;      // Load the TextAsset object 	// 加载文本资源对象     GameObject go = bundle.Load("myGameObject", typeof(GameObject)) as GameObject;      // Instantiate the GameObject 	// 实例化该对象     Instantiate(go); }

 

Keeping track of downloaded AssetBundles 保持跟踪下载的资源包

Unity doesn't provide an automatic way to retrieve a list of AssetBundles that have been downloaded. You can keep track of this information from a script by storing references to the AssetBundle objects and their URLs, say.

Unity不提供自动的一个可以取回所有被下载资源的列表。所以需要我们在脚本中要建立这些资源对象的信息和它们的路径以便我们去查找。

Storing and loading binary data in an AssetBundle 在资源包储存和加载二进制数据

The first step is to save your binary data file with the ".bytes" extension. Unity will treat this file as a TextAsset. As a TextAsset the file can be included when you build your AssetBundle. Once you have downloaded the AssetBundle in your application and loaded the TextAsset object, you can use the .bytes property of the TextAsset to retrieve your binary data.

第一步要储存文件的扩展名以" .bytes"为结尾的二进制数据。Unity会把它们看成TextAsset来使用。当你建立资源包就会包含一个TestAsset的文件。当在资源包应用程序中下载好这个二进制数据后也需要加载它们,可以使用TextAsset的.bytes的属性去取回你的二进制数据。

string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d"; IEnumerator Start () {     // Start a download of the given URL     WWW www = WWW.LoadFromCacheOrDownload (url, 1);      // Wait for download to complete     yield return www;      // Load and retrieve the AssetBundle     AssetBundle bundle = www.assetBundle;      // Load the TextAsset object     TextAsset txt = bundle.Load("myBinaryAsText", typeof(TextAsset)) as TextAsset;      // Retrieve the binary data as an array of bytes     byte[] bytes = txt.bytes; }

 

Including scripts in AssetBundles 在资源包中包含脚本

AssetBundles can contain scripts as TextAssets but as such they will not be actual executable code. If you want to include code in your AssetBundles that can be executed in your application it needs to be pre-compiled into an assembly and loaded using the Mono Reflection class (Note: Reflection is not available on iOS). You can create your assemblies in any normal C# IDE (e.g. Monodevelop, Visual Studio) or any text editor using the mono/.net compilers.

资源包可以作为TextAssets包含脚本但是不会实际执行代码。如果想要在资源包包含用来执行应用程序的代码,需要预先编译,然后使用Mono Reflection class来加载(注意:Reflection在iOS平台不可用)。可以在任何版本的C#IDE编辑器(如:Monodevelop, Visual Studio)或者使用mono/.net 文档编辑器。

string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d"; IEnumerator Start () {     // Start a download of the given URL     WWW www = WWW.LoadFromCacheOrDownload (url, 1);      // Wait for download to complete     yield return www;      // Load and retrieve the AssetBundle     AssetBundle bundle = www.assetBundle;      // Load the TextAsset object     TextAsset txt = bundle.Load("myBinaryAsText", typeof(TextAsset)) as TextAsset;      // Load the assembly and get a type (class) from it     var assembly = System.Reflection.Assembly.Load(txt.bytes);     var type = assembly.GetType("MyClassDerivedFromMonoBehaviour");      // Instantiate a GameObject and add a component with the loaded class     GameObject go = new GameObject();     go.AddComponent(type); }

 

Managing asset dependencies 管理相关资源

Any given asset in a bundle may depend on other assets. For example, a model may incorporate materials which in turn make use of textures and shaders. It is possible to include all an asset's dependencies along with it in its bundle. However, several assets from different bundles may all depend on a common set of other assets (eg, several different models of buildings may use the same brick texture). If a separate copy of a shared dependency is included in each bundle that has objects using it, then redundant instances of the assets will be created when the bundles are loaded. This will result in wasted memory.

任何在资源包中给出的资源可能主要依赖于其它的资源。举个例子,一个模型可能混合多种纹理和材质球中的材质,可能包括所有的某个资源相关的东西,然而,一些从不同资源包文件夹中的资源或许都要用到相同的一些其它资源(比如说一些不同的建筑模型会用到相同的纹理贴图)。如果在每个资源文件夹中包含一个被共享的资源要被某个对象用到,当资源文件加载的时候那就不需要去实例化多余的对象,换句话说就是只要把共享的资源实例化一次就可以了,这样就可以大大减少内存的占用。

To avoid such wastage, it is possible to separate shared dependencies out into a separate bundle and simply reference them from any bundles with assets that need them. First, the referencing feature needs to be enabled with a call to BuildPipeline.PushAssetDependencies. Then, the bundle containing the referenced dependencies needs to be built. Next, another call to PushAssetDependencies should be made before building the bundles that reference the assets from the first bundle. Additional levels of dependency can be introduced using further calls to PushAssetDependencies. The levels of reference are stored on a stack, so it is possible to go back a level using the correspondingBuildPipeline.PopAssetDependencies function. The push and pop calls need to be balanced including the initial push that happens before building.

要避免资源的浪费,可以单独建立一个专门的文件夹用来放要被共享的资源或者所有需要被加载的对象,官方提供的AssetBundles Example Project中的AssetBundles这个文件夹就是一个不错的选择,要查看该文件夹需要进入unity3D->在Project中右击会看到一个下拉菜单有Auto Build Rescources Files的选项,点击它,然后进入AsssetBundles资源目录下你会发现多了一个名为AssetBundles的文件夹,所有的资源已经被转化成.unity3d的格式存储在这里了。要把这些资源存储在指定的AssetBundles这个文件夹下,需要用到BuildPipeline.PushAssetDependencies和BuildPipeline.PopAssetDependencies这两个函数。首先需要BuildPipeline.PushAssetDependencies来激活将要使用到的资源文件夹(比如AssetBundles Example Project中的AssetBundles这个文件夹)。然后就需要建立你想在这个文件夹中存放什么资源了,比如说一个纹理贴图。接着再次呼叫BuildPipeline.PushAssetDependencies来激活下一个将要使用到的和先前存放资源相关的其它资源。比如说有一个角色的模型,这个角色模型有它自己的纹理贴图,那就需要先激活它的贴图然后激活模型本身。如此反复直到把所有与需要加载资源的其它相关资源都使用BuildPipeline.PushAssetDependencies加载完毕,最后再使用BuildPipeline.PopAssetDependencies来告诉程序这个模型所有的相关资源已经全部加载完成。

At runtime, you need to load a bundle containing dependencies before any other bundle that references them. For example, you would need to load a bundle of shared textures before loading a separate bundle of materials that reference those textures.

在运行时,需要考虑到优先加载资源的顺序。举个例子,现在有一张纹理贴图,这张贴图可能被很多个模型需要用到,而这个贴图又有很多不同的材质,那就得先加载纹理贴图,然后材质,最后才是模型。

具体的代码实现过程可参考AssetBundles Example Project中的AutoExportRescources这个脚本。

Can I reuse my AssetBundles in another game? 
可以在其他的游戏场景重新使用我的资源包吗?

AssetBundles allow you to share content between different games. The requirement is that any Assets which are referenced by GameObjects in your AssetBundle must either be included in the AssetBundle or exist in the application (loaded in the current scene). To make sure the referenced Assets are included in the AssetBundle when they are built you can pass the BuildAssetBundleOptions.CollectDependencies option.

资源包允许用户去共享资源包中的内容到其它不同的游戏。如果需要共享,前提需要你已经建立好这个资源包共享文件。可以使用BuildAssetBundleOptions.CollectDependencies这个函数来检测是否已经建立好资源包文件。

How are assets in AssetBundles identified?
资源包中的资源如何被识别?

When you build AssetBundles the assets are identified internally by their filename without the extension. For example a Texture located in your Project folder at "Assets/Textures/myTexture.jpg" is identified and loaded using "myTexture" if you use the default method. You can have more control over this by supplying your own array of ids (strings) for each object when Building your AssetBundle withBuildPipeline.BuildAssetBundleExplicitAssetNames.

当在内部建立资源包时,它们的文件名不包含扩展名就会被识别。举个例子,一个在你项目工程目录下比如说"Assets/Textures/myTextures.jpg"的贴图是用"myTexture"来识别。如果使用默认的方法,当你用BuildPipeline.BuildAssetBundleExplicitAssetNames这个函数建立你的资源包,那你可以有很多你自己编号的数组上的控制。

Loading objects from an AssetBundles asynchronously
从资源包异步加载对象

You can use the AssetBundle.LoadAsync method to load objects Asynchronously and reduce the likelihood of having hiccups in your application.

可以使用AssetBundle.LoadAsync方法来异步加载对象,这样一来可以减少在应用程序中被打断的可能性。

using UnityEngine;  IEnumerator Start () { 	// Start a download of the given URL 	WWW www = WWW.LoadFromCacheOrDownload (url, 1);  	// Wait for download to complete 	yield return www;  	// Load and retrieve the AssetBundle 	AssetBundle bundle = www.assetBundle;  	// Load the object asynchronously 	AssetBundleRequest request = bundle.LoadAsync ("myObject", typeof(GameObject));  	// Wait for completion 	yield return request;  	// Get the reference to the loaded object 	GameObject obj = request.asset as GameObject; }

 

Are AssetBundles cross-platform?
资源包可以跨平台吗?

AssetBundles are compatible between some platforms. Use the following table as a guideline.

在有一些平台中是可以兼容的,可以参考下面的这个表格。

Platform compatibility for AssetBundles 资源包在平台的兼容性
  Standalone Webplayer iOS Android
Editor Y Y Y Y
Standalone Y Y    
Webplayer Y Y    
iOS     Y  
Android       Y

How do I cache AssetBundles? 如何缓存资源包?

You can use WWW.LoadFromCacheOrDownload which automatically takes care of saving your AssetBundles to disk. Be aware that on the Webplayer you are limited to 50MB in total (shared between all webplayers). You can buy a separate caching license for your game if you require more space.

使用WWW.LoadFromCacheOrDownload就可以自动在你的硬盘上存储资源包文件。但是说明一下Webplayer被限制50MB的存储空间。如果需要更多空间则可以单独为游戏购买缓存许可证。

Protecting content 保护内容

Unity allows you to create an AssetBundle object from a byte[] array with AssetBundle.CreateFromMemory. You can use this as a way to enhance the security by encrypting your assetbundles before transmission and decrypt them at runtime.

Unity允许用户使用AssetBundle.CreateFromMemory从一个 byte[]数组中建立一个AssetBundle的对象。在运行时传输和解密之前,可以用这种加密方法来提高安全性和保护用户建立的资源包中内容。

string url = "http://www.mywebsite.com/mygame/assetbundles/assetbundle1.unity3d"; IEnumerator Start () {     // Start a download of the given URL     WWW www = new WWW (url);      // Wait for download to complete     yield return www;      // Get the byte data     byte[] encryptedData = www.bytes;      // Load the TextAsset object     byte[] decryptedData = YourDecryptionMethod(encryptedData);      // Create an AssetBundle from the bytes array     AssetBundle bundle = AssetBundle.CreateFromMemory(decryptedData);      // You can now use your AssetBundle }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity3D AssetBundles 动态加载游戏资源 的相关文章

随机推荐

  • multicycle path的概念和用法

    通常情况下 两个同步的reg进行timing check时 组合逻辑的delay必须在一个时钟周期内到达 才能满足setup的时序 但是在某些情况下 从一个寄存器输出到另外一个寄存器的data端需要不止一个cycle的时间 而且又不影响逻辑
  • c++之Vector(动态 )

    原文 Vector 向量 C 中的一种数据结构 确切的说是一个类 它相当于一个动态的数组 当无法知道数组的规模有多大时 用来解决问题可以达到最大节约空间的目的 1 用法 include
  • 《结构化思维》读书笔记

    读书使人进步 每天进步一点点 本周小萌精心读的一本书是 结构化思维 主要是讲结构化思考 很棒的一本书 推荐读 麦肯锡金字塔原理 以及其他的麦肯锡结构化思考方法 第一章 初识思维 思维是我们解读事实的起点 是产生行为的源头 是决定结果的根本
  • honeyd路由拓扑

    create router 创建路由器模版 set router personality Cisco 7206 running IOS 11 1 24 指纹 add router tcp port 23 usr share honeyd s
  • python+unittest+ddt,从0到1搭建接口自动化框架

    最近在学习纯代码的接口自动化框架 在网上查阅大量资料后 结合了多个文章 最后使用python unittest ddt实现了一个简单的接口自动化工具 可以实现读取excel中的测试用例 生成测试报告 并发送邮件的功能 下图是项目的框架结构
  • Activiti7正式版- Activiti Cloud SR1

    2019年3月18版本 Activiti7正式版 Activiti Cloud SR1正式发布 我很高兴地宣布第一个服务版本的Activiti Cloud 和Activiti Core artefacts 在从我们的第一次GA迭代中获得大量
  • Andorid平台GB28181设备接入端如何生成黑帧并推送至国标平台

    我们在做Android平台GB28181设备接入模块的时候 遇到这样的需求 做移动对讲的时候 是不需要视频数据的 但是国标平台侧 没有视频的话 大多平台又无法播纯音频打包的数据 网页端大多基于http flv或webrtc实现 基于此 我们
  • python3 nonetype_“ NoneType”对象在python3中不可迭代

    TypeError Traceback most recent call last in 15 execute Align rsUnitedSpecPolicyDataFeed 16 gt 17 df pd read sql sql con
  • mpaas小程序如何实现摇一摇功能

    因为公司需要特意研究一下mpaas小程序框架 公司要实现摇一摇功能 如下 手机晃动调用其代码api 实现其功能 代码如下 axml片段
  • python-sklearn数据拆分与决策树的实现

    python sklearn数据拆分与决策树的实现 前言 一 数据拆分的sklearn实现 1 拆分为训练集与测试集 2 交叉验证法 1 留一交叉验证 2 验证集验证 3 k折交叉验证 4 s折交叉验证 s fold 3 sklearn交叉
  • .md即markdown文件的基本常用编写语法(图文并茂)

    序言 很久没有写博客了 感觉只要是不写博客 人就很变得很懒 学的知识点感觉还是记不住 渐渐地让我明白 看的越多 懂的越少 你这话不是有毛病吗 应该是看的越多 懂的越多才对 此话怎讲 当你在茫茫的前端知识库里面东看看 西看看的时候 很快就被海
  • 知乎热议:国家何时整治程序员的高薪现象?

    国家何时整治程序员的高薪现象 看到这个标题 可能大多数人的第一反应都是 提出这种问题的人 非蠢即坏 我当时看到突然吓了一跳 难道这是要拿程序员开刀 本身知乎平台上就有不少程序员群体活跃 马上就吸引来了很多人参与回答 其中 下面这位知友的回答
  • 最强自动化测试框架Playwright(35)-API测试

    playwright可以进行API测试 APIRequestContext可以通过网络发送各种HTTP S 请求 以下示例演示如何使用 Playwright 通过 GitHub API 测试问题创建 测试套件将执行以下操作 在运行测试之前创
  • Django图书商城系统实战开发 - 实现个人订单管理

    Django图书商城系统实战开发 实现个人订单管理 在实战开发Django图书商城系统中 实现个人订单管理是提供给用户的重要功能之一 以下是总结的要点 订单列表 创建一个订单列表页面 展示个人的订单历史 使用Django的模型和视图来获取和
  • Shopify商品列表页实现自动加载下一页产品功能Loading More

    找到你要编辑的主题 然后单击 Action gt Edit code 打开文件 theme liquid 或者在商品列表文件中 引用一个JS文件 在Assets中新增一个名为loadingmore的JS文件 添加如下代码 保存 loadin
  • Python 动态生成系统数据库设计到word文档

    背景 经常需要交付一些系统文档而且基本都是word的 其中又有系统数据库介绍模块 看着数据库里的几百张表于是我开始怀疑人生 所以咱手写一个 涉及知识 pymysql 操作数据库 tkinter GUI图形库 threading 线程 que
  • 飞控学习笔记-姿态角解算(MPU6050 加速度计加陀螺仪)

    本文持续更新 I2C通信 AHRS是自动航向基准系统 Automatic Heading Reference System 的简称 目前 使用四元数来进行AHRS姿态解算的算法被广泛采用于四轴飞行器上 IMU部分 IMU是惯性测量装置 In
  • 更便捷化的支付是时代发展的大趋势

    人脸识别是一种基于人的相貌特征信息进行身份认证的生物特征识别技术 技术的最大特征是能避免个人信息泄露 并采用非接触的方式进行识别 人脸识别与指纹识别 掌纹识别 视网膜识别 骨骼识别 心跳识别等都属于人体生物特征识别技术 都是随着光电技术 微
  • Vscode 绿色系清新主题

    炎炎夏日 上班上的心浮气躁 敲代码的时候 只觉昏昏沉沉 浑浑噩噩 给vscode换一个一个清新美好的绿色主题 充满活力和希望吧 朋友们 收藏起来 每个季节换一个主题 打工快乐 1 green theme 主打一个绿色温温柔柔的绿色画风 真的
  • Unity3D AssetBundles 动态加载游戏资源

    AssetBundles are files which you can export from Unity to contain assets of your choice These files use a proprietary co