How to Develop a Game
Assets Import and Load
PublishDate: 2025-06-01 | CreateDate: 2025-06-01 | LastModify: 2025-06-01 | Creator:ljf12825

如何将外部资源导入到Unity中并在运行时使用

资源导入

资源导入是指Unity将外部资源文件(如.fbx、.png、.mp3等)转换为引擎可以使用的内部格式。导入过程不仅包括将资源放入Unity项目中,还涉及到Unity如何优化、压缩、管理这些资源

资源导入的关键步骤

常见的资源类型导入

资源加载

在游戏运行时,如何高效地加载和管理这些已经导入的资源至关重要,尤其是在需要加载大量资源时。Unity提供了多种加载资源的方式,以便优化性能和内存使用

class Resources

Resources类在Unity中提供了一种动态加载资产的方式,允许你访问存储在特定文件夹中的对象,如Texture,Prefab,Audio Clips等。这些文件必须存放在项目中名为“Resources”的文件夹内

存放资产到Resources文件夹

加载方式

构建优化问题

通常,Unity 会通过 Inspector 暴露对资产的引用,这样在构建时它可以自动计算出哪些资产是实际使用的,从而避免不必要的资源被包含在最终构建中。但如果使用 Resources 文件夹,Unity 无法做到这一点,因此所有资产都会被包含在构建中,即使你没有使用它们

不推荐过度使用路径加载

使用路径名来加载资产会导致代码不那么可复用,因为脚本会硬编码依赖于资产存放的位置。这不如通过Inspector暴露的引用直观和易于维护

使用场景

在一些情况下,直接通过代码加载资产会更方便,特别是在你需要在运行时生成对象时。例如,程序化生成一个游戏物体并为其赋予纹理,或者加载动态生成的资源时,使用 Resources.Load() 会非常方便

内存管理

使用 Resources.Load() 加载的资产,特别是纹理等资源,可能会占用内存,即使这些实例没有出现在场景中。为了释放内存,可以调用 Resources.UnloadUnusedAssets() 来卸载不再使用的资源。

Resources文件夹在创建项目时不会自动生成,需要手动创建这个文件夹才能使用

API

方法描述
FindObjectsOfTypeAll返回当前内存中所有指定类型 T 的对象列表。
InstanceIDIsValid如果给定的实例 ID 对应一个有效的对象,则返回 true。该对象可能已经被删除或尚未加载到内存中。
InstanceIDsToValidArray将实例 ID 数组转换为布尔数组,指示每个实例 ID 是否对应内存中的有效对象。对象可能已删除或未加载。
InstanceIDToObject将实例 ID 转换为对象引用。
InstanceIDToObjectList将实例 ID 数组转换为对象引用列表。
Load加载存储在 Resources 文件夹路径下的指定类型的资源。
LoadAll加载 Resources 文件夹路径下的文件夹或文件中的所有资源。
LoadAsync异步加载存储在 Resources 文件夹路径下的资源。
UnloadAsset从内存中卸载指定的资源。
UnloadUnusedAssets卸载未使用的资源,释放内存。

Unity Scripting Resources

Asset Bundles

Asset Bundles是Unity的一个资源打包系统,允许开发者将游戏中的资源(如模型、纹理、音频等)打包成一个或多个独立的文件(称为Asset Bundles),以便按需加载。

这种方式适用于大规模资源的管理,尤其是当资源文件较大或需要动态加载时,Asset Bundles提供了比Resources文件夹更灵活的资源加载和内存管理方式

Asset Bundles的核心概念

创建Asset Bundles

创建Asset Bundles的过程涉及将资源打包成独立的文件,这些文件可以在运行时动态加载

打包资源步骤:

  1. 设置资源为Asset Bundle: 在Unity编辑器中,选择资源(如纹理、模型、音频等),在Inspector面板中为资源分配一个Asset Bundles名称
  1. 构建Asset Bundles 使用BuildPipeline API构建 Asset Bundles
using UnityEditor;

public class AssetBundleBuilder
{
  [MenuItem("Assets/Build Asset Bundles")]
  static void BuildAllAssetBundles()
  {
    BuildPipeline.BuildAssetBundles("Assets/AssetBundles", BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
  }
}

这段代码会将所有标记为Asset Bundle的资源打包到Assets/Bundles目录中,并生成适用于Windows平台的Asset Bundle - BuildAssetBundleOptionjs.None:没有特殊选项,可以根据需要选择不同的选项(例如压缩、增量构建等) - BuildTarget.StandaloneWindows:指定构建目标平台,可以选择其他平台

  1. 输出: 构建后,Unity会在指定的目录中生成Asset Bundle文件

加载Asset Bundles

在游戏运行时,可以通过以下方式加载和使用Asset Bundles

加载Asset Bundle: 加载Asset Bundle通常是异步的,避免阻塞主线程,保证游戏运行流畅

卸载Asset Bundle

加载后的Asset Bundle和资源可以通过Unload()方法释放,以防止内存泄露

myLoadAssetBundle.Unload(false);

false参数意味着只卸载Asset Bundle,不会卸载已经加载的资源。如果设置为true,则会卸载资源和Asset Bundle

Asset Bundle的优点和缺点

优点:

  1. 按需加载:Asset Bundles 允许你将资源分离成不同的包,并且按需加载,这减少了内存的占用,并提高了加载速度。
  2. 资源分组和优化:你可以将资源按类型或加载频率进行分组(例如,UI 资源、场景资源、远程资源),并根据需要加载,提高游戏性能。
  3. 远程资源加载:Asset Bundles 支持从远程服务器加载资源,非常适合动态内容更新、DLC(可下载内容)和游戏数据包的分发。
  4. 平台兼容性:你可以为不同的平台(Windows、Android、iOS)构建不同的 Asset Bundle,确保在不同平台上使用合适的资源格式。

缺点:

  1. 管理复杂:随着游戏项目变得越来越大,Asset Bundles 的管理和维护可能变得更加复杂。你需要合理分配资源、管理多个 Asset Bundle、确保版本一致性等。
  2. 版本控制:由于 Asset Bundles 是外部资源包,Unity 并不直接将它们与项目文件一起进行版本控制。你需要单独管理 Asset Bundles 的版本和依赖关系。
  3. 构建时间:Asset Bundles 构建过程可能需要一些时间,尤其是当项目包含大量资源时。
  4. 缓存管理:在远程加载资源时,可能会遇到缓存问题,需要合理设置 CDN 或服务器端的缓存策略,确保资源的最新版本被加载。

API

Static Properties

PropertyDescription
memoryBudgetKB控制共享的 AssetBundle 加载缓存的大小,默认值为 1MB。

Properties

PropertyDescription
isStreamedSceneAssetBundle如果 AssetBundle 包含 Unity 场景文件,则返回 true

Public Methods

MethodDescription
Contains检查 AssetBundle 是否包含特定的对象。
GetAllAssetNames返回 AssetBundle 中所有资源的名称。
GetAllScenePaths返回 AssetBundle 中所有场景的路径。
LoadAllAssets同步加载 AssetBundle 中包含的所有资源。
LoadAllAssetsAsync异步加载 AssetBundle 中包含的所有资源。
LoadAsset同步加载 AssetBundle 中的某个资源。
LoadAssetAsync异步加载 AssetBundle 中的某个资源。
LoadAssetWithSubAssets同步加载 AssetBundle 中的资源及其子资源。
LoadAssetWithSubAssetsAsync异步加载 AssetBundle 中的资源及其子资源。
Unload卸载 AssetBundle,释放其占用的数据。
UnloadAsync异步卸载 AssetBundle 中的资源。

Static Methods

MethodDescription
GetAllLoadedAssetBundles获取当前所有已加载的 AssetBundle 的枚举。
LoadFromFile从磁盘文件同步加载 AssetBundle。
LoadFromFileAsync从磁盘文件异步加载 AssetBundle。
LoadFromMemory从内存区域同步加载 AssetBundle。
LoadFromMemoryAsync从内存区域异步加载 AssetBundle。
LoadFromStream从托管流同步加载 AssetBundle。
LoadFromStreamAsync从托管流异步加载 AssetBundle。
RecompressAssetBundleAsync异步将下载或存储的 AssetBundle 从一个构建压缩格式重新压缩到另一个。
UnloadAllAssetBundles卸载所有当前加载的 AssetBundle。

Unity Scripting AssetBundle

Addressable Assets System

这是Unity推荐的现代资源加载方式,通过Addressable Asset System,开发者可以将资源分组并动态加载,支持远程加载资源包,极大地提升了资源管理的灵活性和性能

简介

Addressable Asset System允许开发者通过地址使用资产,一旦一个资产被标记为“addressable”,它便生成一个地址,可以在任何地方被调用;无论这个资产是在本地或远程,系统都会定位它和它的依赖,然后返回它

通过Windows->Asset Management->Addressables使用地址资源系统

Addressables使用异步加载技术,支持从任意位置加载任意依赖项集合。无论是使用直接引用、传统Asset Bundle还是Resources文件夹,Addressables都可以提供一种更简便的方法

Addressables

资源卸载

资源加载后,不及时释放也可能导致内存泄露

资源优化

为了优化资源的加载与使用,Unity有多种工具和策略