资产可以是Unity中的任何资源;这些资源可以是图像、音频、视频、脚本、文本等等。
当构建一个Unity项目到任何平台时,你的游戏中的所有资产将被 "打包 "在一个文件中(或更多,取决于你的平台),由此产生的构建大小将取决于你决定在游戏中打包的资产的大小。
用多个高清纹理而不是用地图图集来创建游戏,或者用240p的视频而不是用1080p,这都是不一样的。预计你的资产规模越大,你最终构建的规模就越大。
一般来说,保持你的构建尽可能的轻量级是一个很好的做法,这样玩家就不会因为你的尺寸而不愿意下载你的游戏,而且你的场景运行速度也会大大加快。
有多种技巧可以实现这一点,在这篇文章中我们将讨论其中的一些技巧,首先是流媒体资产。
什么是流媒体资产?
假设你的游戏中有一个很好的场景,所有的动作都发生在这里。玩家在敌人的基地里,在一个特定的房间里,你决定在电脑上播放一段视频作为复活节彩蛋。
这段视频非常大,超过300MB,玩家可能会进入那个特定的房间,也可能不会真正看到它。在你的场景中默认加载它可以吗?这可能会在你的伟大场景中造成不必要的缓慢。因此,当我们真正需要它的时候再加载它可能会很好。
流媒体资产就是这样:一个放置在特定文件夹中的资产,当需要的时候会被Unity Player加载。该资产将被放置在目标平台内一个容易找到的地址。
请注意,任何放置在流媒体资产文件夹(在Unity内名为StreamingAssets)上的资产将被复制到目标平台,如果用户在项目文件夹内搜索,就能看到它们。
一些游戏的MOD就是这样制作的。
改变一个角色的纹理?进入数据文件夹,找到使用的纹理,然后修改它。改变一个难缠的老板的声线?只需进入数据文件夹并找到音轨,然后用另一个同名的音轨替换它。
流动资产让游戏顺利运行,而不需要从内存中加载所有的资产,并将较大的资产放在一个容易到达的路径上。
让我们建立一个简单的流资产的例子
我们将用一个简单的例子来说明流媒体资产是如何工作的,在你的游戏中展示一个视频。
为了这个例子,我从iStockPhoto下载了一个视频的预览。
确保你想使用的视频有以下扩展名之一:.mov, .mpeg, .mp4, .avi, .asf。
对于我们最初的例子,我们将创建一个名为 "视频"的新文件夹,并将我们的视频放在该文件夹内:

然后,在我们的层次结构面板上,我们将设置我们的视频播放器。
右键点击你的层次结构,添加一个空的游戏对象。我把我的对象称为VideoObject。
在它里面,我创建了一个立方体,我们将在那里播放视频;它可以是任何你想要的形状,但为了方便,我选择了一个立方体。我把它叫做Video_Canvas。
在Video**_Canvas的同一层,在VideoObject里面,我通过右键单击VideoObject**,选择Video,然后选择VideoPlayer,添加了一个新的Video Player对象:

下面是我如何设置我们的视频播放器对象的:

我们将源设置为视频剪辑,然后从我们创建的视频文件夹中选择视频剪辑,然后我们选择循环,这样视频就会无限地播放下去。
然后,选择渲染模式为材质覆盖,拖放你想播放视频的对象--在我们的例子中,是Video_Canvas立方体。让材料属性为_MainTex。
如果你在Unity编辑器中点击播放,你会看到这样的画面:立方体的每一面都在播放视频:

如果你想要一个更平坦的表面,像屏幕一样,你也可以创建一个平面或将立方体的比例缩小到你想要的形状。
这个演示视频有3.5MB。
如果我们为一个独立的平台(Windows、Linux、MacOs)建立这个项目,我们会看到一个带有视频的空白项目是87.6MB。

现在,让我们看看使用同一视频作为流媒体资产的效果如何。
为此,我们将在Assets文件夹中创建一个名为StreamingAssets的新文件夹;这是一个特殊命名的文件夹,它将把我们的视频文件video_streamingAssets当作一个普通文件,在编辑器的属性窗口中没有任何选项:

然后在我们的视频播放器对象中,我们可以将视频播放器游戏组件的来源改为URL,而不需要实际的URL。我们将创建一个名为LoadVideo的新脚本,并将其附加到我们的视频播放器游戏对象上,如图所示。
这个脚本需要一个视频播放器作为参数,所以我们将拖放同一个视频播放器,并将其附加到这个脚本上。

这里是LoadVideo的脚本:
using UnityEngine;
using UnityEngine.Video;
public class LoadVideo : MonoBehaviour
{
public VideoPlayer myVideoPlayer;
void Start()
{
string videoUrl= Application.streamingAssetsPath +"/"+ "video_streamingAssets" + ".mp4";
myVideoPlayer.url = videoUrl;
}
}
基本上,在应用程序的开始,它将使用Application.streamingAssetsPath来获取任何目标平台中的StreamingAssets文件夹的路径。然后它将引用该文件夹中我们的视频名称及其扩展名。
然后,它将采取myVideoPlayer(已经有我们的场景视频播放器的引用),它将用我们的视频的路径写入其url属性。
这将导致在同一个立方体中播放视频:

现在,如果我们建立这个项目,我们会看到它的大小与我们之前的例子相同,但有一个主要的区别:

如果我们看到这个构建的包的内容,我们可以看到在内容/资源/数据中,有我们的StreamingAssets文件夹和我们的视频。

如果我们把StreamingAssets文件夹中的视频替换成 另一个同名的视频,我们就不需要再次构建我们的项目,就能看到反映在我们游戏中的变化。

现在我们知道了如何将我们的资产/内容从我们的构建中分离出来。我们也可以从我们的视频播放器上的URL调用远程文件。为了做到这一点,我们将使用这个视频作为例子。它几乎有10分钟长,大约有151MB。
如果我们把我们的代码改为:
using UnityEngine;
using UnityEngine.Video;
public class LoadVideo : MonoBehaviour
{
public VideoPlayer myVideoPlayer;
void Start()
{
string videoUrl= "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4";
myVideoPlayer.url = videoUrl;
}
}
...并删除StreamingAssets文件夹中的原始视频,我们的结果是这样的:

同样的功能,但现在的视频资产来自外部来源。
现在,如果我们在StreamingAssets文件夹中没有本地视频的情况下构建我们的项目,我们会看到构建的大小有所减少。

请记住,这也可以通过异步调用或UnityWebRequest 调用和coroutine来完成,但为了简单起见,我们只是添加一个视频的确切URL来演示流资产的力量。
使用一个coroutine从外部来源获取视频
我们可以像这样修改我们的LoadingScript ,以便使用一个coroutine,而不是将直接链接传递给我们的视频播放器:
using UnityEngine;
using UnityEngine.Video;
using UnityEngine.Networking;
using System.Collections;
public class LoadVideo : MonoBehaviour
{
public VideoPlayer myVideoPlayer;
void Start()
{
StartCoroutine(LoadExternalVideo("http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4"));
}
IEnumerator LoadExternalVideo(string url){
using (UnityWebRequest request = UnityWebRequest.Get(url))
{
//Fetches a page and displays the number of characters of the response.
yield return request.SendWebRequest();
myVideoPlayer.url = request.url;
}
}
}
在这个例子中,我们可以使用一个coroutine来消耗一个API端点并检索视频的URL,但为了简单起见,这是一个关于如何使用外部链接的简单例子。
结果将是非常相似的;我们只需要确保我们的UnityWebRequest 结果是从被消耗的端点检索出来的,并确保视频的URL在设置到视频播放器的URL属性之前是存在的。
最后的想法
流媒体资产只是Unity为你的游戏处理资产的不同方式之一。当你试图让你的玩家群参与进来,允许他们修改你的游戏时,或者你想有一个轻量级的游戏最终构建,然后在第一次启动时,在玩家注意到之前下载你的游戏的其他资产时,它的效果非常好。
有很多网络游戏都是这样做的:他们的游戏非常轻,你可以完成第一关的小教程,然后你会得到一个下载其余资产的加载屏幕。
你必须牢记对你的游戏来说是最好的方法。你不能把所有的资产都放在一个远程服务器上,因为如果玩家第一次玩你的游戏时,他们的设备没有良好的网络连接,那会发生什么?没有资产,你的游戏会是什么样子?
最好的方法之一是将你的资产的一个非常轻的版本作为默认值(如材料、纹理、图像),作为一个占位符,当你确定你的玩家会喜欢这些内容,而且设备已经准备好下载这些信息时,尽可能无缝地下载。
我希望你喜欢这篇文章,并觉得它很有用!祝你游戏开发愉快!