在Unity游戏开发中,资源加载是一个至关重要的环节,它能将游戏所需的资源文件加载到内存中,供游戏运行时使用。Unity提供了多种资源加载方式,各有优缺点,开发者需要根据实际需求来选择最合适的方案。本文将详细介绍四种常见的Unity资源加载方式及其实现步骤。
1. 直接从Assets文件夹加载资源【编辑器模式】
这个方法实现从Assets 中加载任意一个文件,不管是模型、音频、贴图(Texture)、精灵(sprite)、视频、文件都可以,但是弊端就是他是编辑器(UnityEditor)的运行方法,而不是游戏运行时的方法。这个地方可能小伙伴不懂,可以百度查一下Unity编辑器运行和游戏运行的区别。
意思就是:AssetDatabase的这些方法只能在Unity编辑器环境下运行,不能在构建后的游戏中使用。在游戏运行时,你需要使用其他资源加载方法,如Resources.Load、AssetBundle加载或者Addressables等。
AssetDatabase方法是一种UnityEditor功能,在游戏未运行时的测试行为!便于开发人员利用Unity开发自己用的“小插件”,和游戏本身无关,但是可以帮助程序员快速的管理、优化、处理自己的资源!我准备单独写一篇博客讲解UnityEditor。
步骤:
1.1.获取Assets 文件夹下的某个物体的相对路径
(就是你当前项目下,Assets在你电脑上的文件路径)这个路径是长这样的,例如:
Assets/AnimControler/HPCharacter.prefab
需要带后缀名字。
1.2.在脚本中使用AssetDatabase.LoadAsset()方法加载这个物体资源。
我演示一下加载上图中这个选中的预制体
示例代码:
// 引入Unity编辑器的命名空间,用于编辑器相关的功能
using UnityEditor;
// 引入Unity引擎的命名空间,用于游戏对象、组件等的功能
using UnityEngine;
// 声明一个公共类,命名为ExampleClass
public class ExampleClass : MonoBehaviour
{
// 定义一个静态方法leoLoad,它有一个[MenuItem]属性,使得在Unity编辑器的菜单栏中可以找到这个菜单项
[MenuItem("Assets/leoLoadAssets")]
// leoLoad方法是静态的,不依赖于特定的实例来调用
static void leoLoad()
{
// 使用AssetDatabase.LoadAssetAtPath方法从指定的路径加载一个GameObject类型的资源
GameObject OneObj = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/AnimControler/HPCharacter.prefab");
// 使用Debug.Log输出日志信息,显示从Assets中加载的物体的名称
Debug.Log("从Assets 中加载一个物体"+"拿到的物体叫:"+ OneObj.name);
}
}
这个脚本的主要功能是在Unity编辑器的菜单栏中添加一个名为"Assets/leoLoadAssets"的菜单项。当这个菜单项被点击时,它会从"Assets/AnimControler/HPCharacter.prefab"路径加载一个预制体,并打印出加载的预制体的名称。
[MenuItem("Assets/leoLoadAssets")] 是创建一个菜单按钮。无需运行游戏,脚本保存后,你的Unity菜单栏就有这个按钮了。
者这句话下面的静态函数 static void leoLoad(){} 就是按钮点击后执行的函数
再比如我要加载一个图片
优点:
- 简单易用
- 可以加载任何类型的资源文件
缺点:
- 属于编辑器办法,游戏运行时无效
- 加载资源时需要遍历整个Assets文件夹,性能较差
注意事项: 直接从Assets文件夹加载资源属于编辑器办法,在游戏运行时无效。同时,这种方式加载资源时需要遍历整个Assets文件夹,性能较差。
但是使用AssetDatabase还可以做其他恨多事情,大家可以看我的AssetDatabase扩展部分博客:直通车:http://t.csdnimg.cn/7gxKRhttp://t.csdnimg.cn/7gxKR
2. 创建Resources文件夹加载资源
步骤:
- 在Assets文件夹中创建Resources文件夹。
- 将资源文件移动到Resources文件夹中。
- 在脚本中使用Resources.Load()方法加载资源。
示例代码: // 创建 Resources 文件夹 Resources.CreateFolder("Cube"); // 将资源文件移动到 Resources 文件夹 cube.name = "Cube1"; cube.transform.position = Vector3.zero; Resources.CopyAsset(cube, "Cube/Cube1"); // 加载资源 GameObject one = Resources.Load<GameObject>("Cube/Cube1");
优点:
- 可以提高资源加载性能
- 可以分组管理资源文件
缺点:
- 发布后资源会被自动加密
- 不能加载StreamingAssets中的资源
- 资源会被加载到内存中
注意事项: 创建Resources文件夹可以提高资源加载性能。将资源文件移动到Resources文件夹后,资源会被自动加密。此外,不能加载StreamingAssets中的资源,并且资源会被加载到内存中。
3. 创建StreamingAssets文件夹加载资源
步骤:
- 在Assets文件夹中创建StreamingAssets文件夹。
- 将资源文件移动到StreamingAssets文件夹中。
- 在脚本中使用AssetBundle.Load()方法加载资源。
示例代码:
// 创建 StreamingAssets 文件夹
AssetDatabase.CreateFolder("StreamingAssets", "Cube");
// 将资源文件移动到 StreamingAssets 文件夹
cube.name = "Cube1";
cube.transform.position = Vector3.zero; AssetDatabase.CopyAsset(cube,"StreamingAssets/Cube/Cube1");
// 加载资源
GameObject one = AssetBundle.Load("StreamingAssets/Cube/Cube1");
优点:
- 可以提高资源加载性能
- 资源不会被加密
缺点:
- 需要在本地计算机上存储资源文件
- 不能加载Resources中的资源
注意事项: 创建StreamingAssets文件夹可以提高资源加载性能。将资源文件移动到StreamingAssets文件夹后,资源不会被加密。但是需要注意的是,这种方式需要在本地计算机上存储资源文件,且不能加载Resources中的资源。
4. 创建并动态加载AssetBundle资源
步骤:
- 将资源文件打包成AssetBundle。
- 在脚本中使用AssetBundle.Load()方法加载AssetBundle。
示例代码:
// 创建
AssetBundle AssetBundle assetBundle = AssetBundle.Load("MyAssetBundle");
// 加载 AssetBundle 中的资源
Texture2D texture = AssetBundle.LoadAsset(assetBundle, "MyTexture");
优点:
- 可以提高资源加载性能
- 减少游戏包体大小
- 可以将资源文件分割成多个AssetBundle,以便根据需要动态加载
- 可以将资源文件加密,以防止被盗用
缺点:
- 加载AssetBundle会导致游戏性能的下降
- 加载AssetBundle会占用内存
注意事项: 将资源文件打包成AssetBundle可以提高资源加载性能,并减少游戏包体大小。同时,可以将资源文件分割成多个AssetBundle,以便根据需要动态加载。还可以对资源文件进行加密,以防止被盗用。
然而,加载AssetBundle会导致游戏性能的下降,因此需要根据实际情况进行合理使用。另外,加载AssetBundle会占用内存,因此需要注意内存的使用情况。
总结
Unity提供了多种资源加载方式,开发者可以根据实际情况选择最合适的方法。直接从Assets文件夹加载资源虽然简单易用,但只适用于编辑器环境下。创建Resources文件夹可以提高资源加载性能,但发布的资源会被自动加密。创建StreamingAssets文件夹同样可以提高资源加载性能,并且资源不会被加密,但需要在本地计算机上存储资源文件。
相比之下,创建并动态加载AssetBundle具有更高的灵活性和安全性,可以提高资源加载性能、减小游戏包体大小,并支持按需加载和加密功能。然而,这也带来了额外的游戏性能开销和内存占用问题。
因此,在选择资源加载方式时,应充分考虑资源类型、大小、游戏性能要求以及包体大小等因素,确保选取最符合项目需求的资源加载策略。
-
1.Resources文件夹
Resources文件夹是一个只读的文件夹,通过Resources.Load()来读取对象。因为这个文件夹下的所有资源都可以运行时来加载,所以Resources文件夹下的所有东西都会被无条件的打到发布包中。建议这个文件夹下只放Prefab或者一些Object对象,因为Prefab会自动过滤掉对象上不需要的资源。举个例子我把模型文件还有贴图文件都放在了Resources文件夹下,但是我有两张贴图是没有在模型上用的,那么此时这两张没用的贴图也会被打包到发布包中。假如这里我用Prefab,那么Prefab会自动过滤到这两张不被用的贴图,这样发布包就会小一些了。
此时,若prefab引用的贴图在resources文件夹下,则贴图仍然会被打进包中,因为resources文件夹对资源无条件打包。
若prefab引用的贴图在AB包中,则实例化prefab之前,必须手动去把AB加载出来。就算prefab不是在resources文件来而是在不同于它引用的贴图的AB包中,也一样要在实例化前把贴图所在的AB加载出来,但不用把贴图加载出来,prefab会自动去加载它。
2.StreamingAssets
StreamingAssets文件夹也是一个只读的文件夹,但是它和Resources有点区别,Resources文件夹下的资源会进行一次压缩,而且也会加密,不使用点特殊办法是拿不到原始资源的。但是StreamingAssets文件夹就不一样了,它下面的所有资源不会被加密,然后是原封不动的打包到发布包中,这样很容易就拿到里面的文件。所以StreamingAssets适合放一些二进制文件,而Resources更适合放一些GameObject和Object文件。 StreamingAssets 只能用过www类来读取!!
-
Unity中的大部分资源在发布时都被整合到工程中,我们不能访问。但有时我们需要通过路径名访问放在目标设备中的文件。这些文件被存储在目标设备的文件系统中。
在Unity工程中, 放在StreamingAssets文件夹中的任何资源都将被原样复制到目标设备上的一个特定文件夹中。在任何平台中总可以统一使用Application.streamingAssetsPath 属性来获得这一文件夹路径。.
这个文件夹是跟Application.dataPath相关联的
在 desktop computer (Mac OS or Windows) 中该文件夹为为:-
path = Application.dataPath + "/StreamingAssets";
在 iOS中, 该文件夹为:-path = Application.dataPath + "/Raw";
在 Android中, 该文件夹为:-path = "jar:file://" + Application.dataPath + "!/assets/";
虽然我们可以用上述三个文件夹,在各个平台中获取StreamingAssets的位置,但是最好还是统一使用Application.streamingAssetsPath.注意,在Android中,StreamingAssets中的文件包含在一个.jar压缩文件(基本上与标准的zip为统一格式)中,所以只能用WWW读取,否则要使用第三方软件来读取,不能用C#的文件读取方法。
[csharp] view
plaincopyif(Application.platform==RuntimePlatform.Android)
{
url=Application.streamingAssetsPath+"/brick.jpg";//在Android中实例化WWW不能在路径前面加"file://"
path=Application.streamingAssetsPath+"/1.txt";//1前面的“/”必须要有,否则会出错
// FileInfo fileinfo=new FileInfo(path); 不能在Android中使用
// StreamReader r=fileinfo.OpenText();
WWW wWA=new WWW(path);///WWW读取在各个平台上都可使用
yield return wWA;
line1=wWA.text;
}
else
{
url="file://"+Application.streamingAssetsPath+"/brick.jpg";//在Windows中实例化WWW必须要在路径前面加"file://"
path=Application.streamingAssetsPath+"/1.txt";//1前面的“/”必须要有,否则会出错
WWW wWA=new WWW("file://"+path);
yield return wWA;
line1=wWA.text;
//FileInfo fileinfo=new FileInfo(path);可以在Android以外的平台使用
//文件读取的路径中不要加“file://”。总结:只有在Windows中实例化WWW时,才需要加"file://",有时貌似要三个斜杠"///":Note: http://, https:// and file:// protocols are supported on iPhone. ftp:// protocol support is limited to anonymous downloads only. Other protocols are not supported.
//''Note:'' When using file protocol on Windows and Windows Store Apps for accessing local files, you have to specify file:///__ (with three slashes).
// StreamReader r=fileinfo.OpenText();
//
// while((line=r.ReadLine())!=null)
// {
// line1=line;
// Debug.Log(line);TextField
// }
}
下面就是对一个APK文件使用WINRAR解压后得到的StreamingAssets中的文件(1.txt和brick.jpg)就存储在assets文件夹下面,也就是说这个assets文件夹就对应于Unity编辑器中的StreamingAssets文件夹。