Build skills in Unity with guided learning pathways designed to help anyone interested in pursuing a career in gaming and the Real Time 3D Industry. 通过设计的学习路径,培养 Unity 技能,帮助任何对游戏和实时 3D 行业感兴趣的人。
An AssetBundle is content that is stored separately from a main game or application and loaded (or downloaded, in the case of mobile and online apps) at runtime. This helps minimize the impact on network and system resources by allowing customers to download and install only the parts they need. AssetBundles can also be used to update or add to content post-release. In this tutorial, we’ll explore AssetBundles and how they may best serve your project. 资源包(AssetBundle)是存储在游戏或应用程序主体之外的内容,并在运行时加载(或在移动和在线应用程序的情况下下载)。这有助于最小化对网络和系统资源的影响,允许客户仅下载和安装他们需要的部分。资源包还可以用于在发布后更新或添加内容。在本教程中,我们将探讨资源包以及它们如何最好地为您的项目服务。
If you are using Unity 2019.3 or above, click here. 如果您使用的是 Unity 2019.3 或更高版本,请点击此处。
An AssetBundle is content that is stored separately from a main game or application and loaded (or downloaded, in the case of mobile and online apps) at runtime. This helps minimize the impact on network and system resources by allowing customers to download and install only the parts they need. For example, an automobile manufacturer with a VR app that allows customers to “test drive” a vehicle wouldn’t want to include every vehicle in an app — that would make it prohibitively large to download and install. An Asset Bundle allows the customer to download only the vehicle he wants to test drive and at a quality level his platform can handle. 资源包(AssetBundle)是与主游戏或应用程序分开存储的内容,并在运行时加载(或在移动和在线应用程序的情况下下载)。这有助于最小化对网络和系统资源的影响,允许客户仅下载和安装他们需要的部分。例如,一家汽车制造商有一个 VR 应用程序,允许客户“试驾”车辆,他们不希望将每辆车都包含在应用程序中——这会使应用程序变得过大,难以下载和安装。资源包允许客户仅下载他们想要试驾的车辆,并以其平台能够处理的质量级别进行下载。
AssetBundles can also be used to update or add to content post-release. This could include downloadable content, limited-time promotional events, or themed content such as holiday related models. AssetBundles also allow automatic updates and for content to be reused from project to project. For example, for connected apps, you might store your branding — such as logos or introductory videos — as an online AssetBundle. When your branding changes, you only need to update the relevant AssetBundle on your server. Apps that load those assets via a remote AssetBundle would automatically show the updated content rather than needing an update. Apps that download those graphics could be pre-programmed to check for changes in the online AssetBundle and update the locally stored bundle as needed. AssetBundles 也可以用于在发布后更新或添加内容。这可能包括可下载内容、限时促销活动或主题内容,例如与节日相关的模型。AssetBundles 还允许自动更新,并且可以在项目之间重复使用内容。例如,对于连接的应用程序,您可以将品牌标识(如徽标或介绍视频)存储为在线 AssetBundle。当您的品牌标识发生变化时,您只需要在服务器上更新相关的 AssetBundle。通过远程 AssetBundle 加载这些资源的应用程序将自动显示更新后的内容,而无需更新。下载这些图形的应用程序可以预先编程为检查在线 AssetBundle 的变化,并根据需要更新本地存储的包。
An AssetBundle can be further divided into variants. A variant is an option or subclass of an AssetBundle that’s stored with it. If you have an AssetBundle named Vehicles, you might have one variant for cars and one for trucks. If you assign a bundled asset to a variant, you must assign all assets in that bundle to a variant. You cannot have an asset in bundlename.variant and another asset in bundlename (with no variant), where bundlename is the same for both. 一个 AssetBundle 可以进一步分为变体。变体是存储在 AssetBundle 中的一个选项或子类。如果你有一个名为 Vehicles 的 AssetBundle,你可能有一个用于汽车的变体和一个用于卡车的变体。如果你将一个捆绑资源分配给一个变体,你必须将该捆绑包中的所有资源都分配给一个变体。你不能在 bundlename.variant 中有一个资源,而在 bundlename(没有变体)中有另一个资源,其中 bundlename 对两者都是相同的。
To illustrate one use of variants to aid AssetBundle organization, let’s say we’re creating a tutorial level for a multi-console video game. The following table lists some of the graphics that might be used in the instructions to show the player which buttons to press. The Controller layout is common to modern consoles, but the labeling on the action buttons varies by platform. In this example, the top action button performs the same action on both versions of the game, despite the labels being different. In our code, we’d load the Universal Variant for directional graphics, but load the variant containing the button or keyboard graphics for our specific system at runtime. 为了说明变体在帮助 AssetBundle 组织中的一个用途,假设我们正在为一个多平台视频游戏创建一个教程关卡。下表列出了一些可能在指令中使用的图形,以向玩家展示需要按下的按钮。控制器布局在现代游戏机中是通用的,但动作按钮上的标签因平台而异。在这个例子中,顶部动作按钮在两个版本的游戏中都执行相同的操作,尽管标签不同。在我们的代码中,我们会加载通用变体用于方向图形,但在运行时加载包含我们特定系统按钮或键盘图形的变体。
Contents of Asset Bundle ControlImages Asset Bundle 控制图像的内容
Select image to expand 选择图片以展开
Type caption for image (optional)
Or, let’s say we’re bundling images of keys to be used to train users on a cross-platform desktop application. ConsoleA and ConsoleB could become Windows and macOS, respectively, and TopActionButton might be something like CmdCtrl. 或者,假设我们正在打包钥匙的图片,用于在跨平台桌面应用程序中训练用户。ConsoleA 和 ConsoleB 可能分别变为 Windows 和 macOS,而 TopActionButton 可能类似于 CmdCtrl。
Currently, the only way to build AssetBundles is via scripting. The following script adds this functionality to the Unity Editor. There are three parameters for BuildAssetBundles: the directory the AssetBundles should be created in, BuildAssetBundleOption (optional) for nonstandard build modes, and the build target of the AssetBundle. 目前,构建 AssetBundles 的唯一方法是通过脚本。以下脚本将此功能添加到 Unity 编辑器中。BuildAssetBundles 有三个参数:AssetBundles 应创建的目录、用于非标准构建模式的 BuildAssetBundleOption(可选)以及 AssetBundle 的构建目标。
Create a folder named Editor inside your Assets folder. 在 Assets 文件夹内创建一个名为 Editor 的文件夹。
Inside Editor, create a new C# script named CreateAssetBundles. 在 Editor 文件夹内,创建一个新的 C#脚本,命名为 CreateAssetBundles。
Double click CreateAssetBundles to open it in Visual Studio, and delete all contents. 双击 CreateAssetBundles 在 Visual Studio 中打开它,并删除所有内容。
Type the following: 输入以下内容:
using UnityEditor;
using System.IO;
publicclassCreateAssetBundles
{
[MenuItem("Assets/Build AssetBundles")]
staticvoidBuildAllAssetBundles()
{
string assetBundleDirectory = "Assets/StreamingAssets";
if (!Directory.Exists(Application.streamingAssetsPath))
{
Directory.CreateDirectory(assetBundleDirectory);
}
BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, EditorUserBuildSettings.activeBuildTarget);
}
}
CreateAssetBundles is complete. Save changes and close Visual Studio. CreateAssetBundles 已完成。保存更改并关闭 Visual Studio。
In the Unity Editor, you’ll find a new option at the bottom of the Asset dropdown: Build AssetBundles. 在 Unity 编辑器中,你会在 Asset 下拉菜单的底部找到一个新选项:Build AssetBundles。
The specified AssetBundle directory must exist before the AssetBundle is built. The BuildAssetBundleOptions parameter is optional and defaults to None if nothing is specified. Some key options are: 指定的 AssetBundle 目录在构建 AssetBundle 之前必须存在。BuildAssetBundleOptions 参数是可选的,如果未指定,则默认为 None。一些关键选项包括:
Because the required format and handling of AssetBundles varies by platform, you must specify the target platform using one of the following options: 由于 AssetBundles 所需的格式和处理方式因平台而异,您必须使用以下选项之一指定目标平台:
Select image to expand 选择图片以展开
Type caption for image (optional)
7.Creating a Simple AssetBundle 7.创建一个简单的 AssetBundle
In order to test loading an AssetBundle, we’ll create an AssetBundle with a single GameObject. This workflow assumes you’ve completed the CreateAssetBundles script from earlier. Mirroring your AssetBundle organization in your project’s folder structure makes it easier to find and update your bundled assets as needed. 为了测试加载 AssetBundle,我们将创建一个包含单个 GameObject 的 AssetBundle。此工作流程假设您已完成之前创建的 CreateAssetBundles 脚本。在项目的文件夹结构中镜像您的 AssetBundle 组织,可以更轻松地根据需要查找和更新捆绑的资源。
Drag a Sprite into your Assets folder. 将 Sprite 拖入你的 Assets 文件夹。
In a new scene, create a GameObject called BundledSpriteObject. 在新场景中,创建一个名为 BundledSpriteObject 的 GameObject。
Attach a Sprite Renderer component and assign your Sprite from step 1. 附加一个 Sprite Renderer 组件并分配你在步骤 1 中的 Sprite。
Create a folder called BundledAssets inside Assets. 在 Assets 文件夹内创建一个名为 BundledAssets 的文件夹。
Inside BundledAssets, create a folder called testbundle. 在 BundledAssets 文件夹内,创建一个名为 testbundle 的文件夹。
Drag BundledSpriteObject into testbundle and delete it from the Hierarchy. 将 BundledSpriteObject 拖入 testbundle,并从层级视图中删除它。
Click BundledSpriteObject in the Project view to open its Inspector. Pay special attention to the bottom section of the Inspector. 在项目视图中点击 BundledSpriteObject 以打开其检查器。特别注意检查器的底部部分。
Click None next to AssetBundle to assign BundledSpriteObject to an AssetBundle. (Figure 01) 点击 AssetBundle 旁边的 None,将 BundledSpriteObject 分配到一个 AssetBundle。(图 01)
Select image to expand 选择图片以展开
Figure 01: Click here to assign BundledSpriteObject to an AssetBundle. The other dropdown currently marked None is for variants. 图 01:点击此处将 BundledSpriteObject 分配给 AssetBundle。另一个当前标记为 None 的下拉菜单用于变体。
Click New (Figure 02), type testbundle, and Press [Enter]. 点击 New(图 02),输入 testbundle,然后按下[Enter]。
Select image to expand 选择图片以展开
Figure 02: Click an existing AssetBundle name to select it, New to create a new one, or Remove Unused Names to remove all currently unassigned AssetBundle and variant names. 图 02:点击现有的 AssetBundle 名称以选择它,点击 New 以创建一个新的,或点击 Remove Unused Names 以移除所有当前未分配的 AssetBundle 和变体名称。
From the Assets dropdown, select Build AssetBundles. 从“资源”下拉菜单中选择“构建资源包”。
To assign an asset to a Variant, follow steps 1-9, but click on None in the lower right corner rather than the bottom center. 要将资源分配给变体,请按照步骤 1-9 操作,但在右下角点击“无”而不是底部中心。
8.Loading a locally stored AssetBundle 8.加载本地存储的 AssetBundle
Assuming no errors occurred, we are ready to load our AssetBundle from local storage. We are loading our bundle in Start for ease of demonstration. In production, you’d load an AssetBundle only when necessary. 假设没有发生错误,我们已经准备好从本地存储加载我们的 AssetBundle。为了演示方便,我们在 Start 中加载我们的包。在生产环境中,您只会在需要时加载 AssetBundle。
Set the Main Camera’s transform position to 0 in X and Y. 将主摄像机的变换位置在 X 和 Y 轴上设置为 0。
Create a new GameObject called Loader. 创建一个名为 Loader 的新 GameObject。
Create a new C# script called BundledObjectLoader and attach it to Loader. 创建一个名为 BundledObjectLoader 的新 C#脚本并将其附加到 Loader 上。
Double click BundledObjectLoader to open it in Visual Studio. 双击 BundledObjectLoader 以在 Visual Studio 中打开它。
Save changes and return to the Unity Editor. 保存更改并返回 Unity Editor。
Press Play. 按下播放键。
The object you created earlier should load instantly. (Figure 03) 你之前创建的对象应该会立即加载。(图 03)
Select image to expand 选择图片以展开
Figure 03: The final result, a resounding success! 图 03:最终结果,大获成功!
Exit Play Mode. 退出播放模式。
Remove the BundledObjectLoader component from Loader. 从 Loader 中移除 BundledObjectLoader 组件。
The command used to load the AssetBundle, AssetBundle.LoadFromFile, is synchronous. That means it doesn’t return until the command has completed its task (the AssetBundle is fully loaded). This is fine for a small bundle like our example, but for something larger, as we might see in an automotive or architectural previsualization program or AAA video game, this would likely cause an unacceptable drop in frame rate or responsiveness. A better option is LoadFromFileAsync, which runs as a coroutine to allow a project to continue to run while the AssetBundle is loaded. 用于加载 AssetBundle 的命令`AssetBundle.LoadFromFile`是同步的。这意味着它不会返回,直到命令完成其任务(AssetBundle 完全加载)。对于像我们示例中的小包来说,这是可以的,但对于更大的包,比如我们可能在汽车或建筑预可视化程序或 AAA 级视频游戏中看到的包,这可能会导致帧率或响应性出现不可接受的下降。更好的选择是`LoadFromFileAsync`,它作为协程运行,允许项目在加载 AssetBundle 时继续运行。
Create and attach a new C# script called BundleLoaderAsync to Loader. 创建并附加一个新的 C#脚本,名为`BundleLoaderAsync`,到`Loader`上。
Double click BundleLoaderAsync to open in Visual Studio. 双击 BundleLoaderAsync 以在 Visual Studio 中打开。
Delete the Update method and change Start’s return type from void to IEnumerator. 删除 Update 方法并将 Start 的返回类型从 void 更改为 IEnumerator。
On line 4, type: 在第 4 行,输入:
usingSystem.IO;
The following variables should be populated with the bundle and asset name respectively. Inside the class definition, type: 以下变量应分别填充为 bundle 和 asset 的名称。在类定义中,输入:
BundleLoaderAsync is complete. Save changes and return to the Unity Editor. BundleLoaderAsync 已完成。保存更改并返回 Unity Editor。
Press Play. 按下播放键。
Just as before, the bundled object should load. 和之前一样,捆绑的对象应该会加载。
Exit Play Mode and remove BundleLoaderAsync from Loader. 退出播放模式并从 Loader 中移除 BundleLoaderAsync。
Downloading an AssetBundle from the web is very similar to loading it from local storage. For our purposes, the file is hosted on a local web server, inside a directory named assetbundles. 从网络下载 AssetBundle 与从本地存储加载非常相似。在我们的例子中,文件托管在本地 Web 服务器上,位于名为 assetbundles 的目录中。
Create a C# script called BundleWebLoader and attach it to Loader. 创建一个名为 BundleWebLoader 的 C#脚本,并将其附加到 Loader 上。
Double click BundleWebLoader to open in Visual Studio. 双击 BundleWebLoader 在 Visual Studio 中打开。
AssetBundles offer myriad possibilities for developers, users, and players. You’re sure to come up with new ways to make them work for you and mastering them will allow you to offer a more efficient, versatile, and personal experience to your users. AssetBundles 为开发者、用户和玩家提供了无数可能性。你一定会想出新的方法来让它们为你工作,掌握它们将使你能够为用户提供更高效、多功能和个性化的体验。