打开场景Assets/Samples/YooAsset/1.5.3-preview/Space Shooter/Boot
在场景中找到名为Boot的游戏物体,面上挂载着Boot脚本,脚本上有个PlayMode,这个就是上一篇提到的运行模式,我们将该模式选成Host Play Mode。打开此脚本,将Start方法中的代码初始掉,根据上篇的YooAsset逻辑来重写代码。
Wampserver资源服务器
在开始之前,如果选择的模式是Host,是需要一个服务器作为热更资源的下载,我们可以现在本机搭建一个资源服务器。我们要用到Wampserver,安装后在固定路径放置热更好的资源就可以访问到了。
下载Wampserver
Wampserver下载入口
下载完毕安装后,会在电脑右下角生成W的图标,点击这个图标找到www directory
点击后进入www文件夹内,新建CDN文件夹,在CDN文件夹里面再新建俩文件夹PC、Android。
此时访问http://127.0.0.1/CDN/
跳转到上面这个页面说明服务器安装运行成功!
修改Boot脚本
private class RemoteServices : IRemoteServices
{
private readonly string _defaultHostServer;
private readonly string _fallbackHostServer;
public RemoteServices(string defaultHostServer, string fallbackHostServer)
{
_defaultHostServer = defaultHostServer;
_fallbackHostServer = fallbackHostServer;
}
string IRemoteServices.GetRemoteMainURL(string fileName)
{
return $"{_defaultHostServer}/{fileName}";
}
string IRemoteServices.GetRemoteFallbackURL(string fileName)
{
return $"{_fallbackHostServer}/{fileName}";
}
}
YooAsset的热更逻辑:
- 1.初始化资源系统
- 2.获取资源版本
- 3.更新补丁清单
- 4.下载补丁包
- 5.加载资源(预制件、场景、文本、精灵)
新建一个名为TestLoad协程函数,再里面写入以下代码
1.初始化资源系统
// 1.初始化资源系统
YooAssets.Initialize();
string packageName = "DefaultPackage";
var package = YooAssets.TryGetPackage(packageName);
if (package == null)
{
package = YooAssets.CreatePackage(packageName);
YooAssets.SetDefaultPackage(package);
}
if (PlayMode == EPlayMode.EditorSimulateMode)
{
//编辑器模拟模式
var initParameters = new EditorSimulateModeParameters();
initParameters.SimulateManifestFilePath = EditorSimulateModeHelper.SimulateBuild("DefaultPackage");
yield return package.InitializeAsync(initParameters);
}
else if (PlayMode == EPlayMode.HostPlayMode)
{
//联机运行模式
string defaultHostServer = GetHostServerURL();
string fallbackHostServer = GetHostServerURL();
var initParameters = new HostPlayModeParameters();
initParameters.QueryServices = new GameQueryServices(); //太空战机DEMO的脚本类,详细见StreamingAssetsHelper
initParameters.DecryptionServices = new GameDecryptionServices();
initParameters.RemoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
var initOperation = package.InitializeAsync(initParameters);
yield return initOperation;
if (initOperation.Status == EOperationStatus.Succeed)
{
Debug.Log("资源包初始化成功!");
}
else
{
Debug.LogError($"资源包初始化失败:{initOperation.Error}");
}
}
else if(PlayMode == EPlayMode.OfflinePlayMode)
{
//单机模式
var initParameters = new OfflinePlayModeParameters();
yield return package.InitializeAsync(initParameters);
}
else
{
WebGL运行模式
string defaultHostServer = "http://127.0.0.1/CDN/WebGL/v1.0";
string fallbackHostServer = "http://127.0.0.1/CDN/WebGL/v1.0";
var initParameters = new WebPlayModeParameters();
initParameters.QueryServices = new GameQueryServices(); //太空战机DEMO的脚本类,详细见StreamingAssetsHelper
initParameters.RemoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
var initOperation = package.InitializeAsync(initParameters);
yield return initOperation;
if (initOperation.Status == EOperationStatus.Succeed)
{
Debug.Log("资源包初始化成功!");
}
else
{
Debug.LogError($"资源包初始化失败:{initOperation.Error}");
}
}
新建名为GetHostServerURL的方法,此方法用来规定访问下载资源的路径。
private string GetHostServerURL()
{
//string hostServerIP = "http://10.0.2.2"; //安卓模拟器地址
string hostServerIP = "http://127.0.0.1";//你的服务器地址
//string appVersion = "v1.5";
#if UNITY_EDITOR
if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.Android)
return $"{hostServerIP}/CDN/Android/{appVersion}";
else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.iOS)
return $"{hostServerIP}/CDN/IPhone/{appVersion}";
else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.WebGL)
return $"{hostServerIP}/CDN/WebGL/{appVersion}";
else
return $"{hostServerIP}/CDN/PC/{appVersion}";
#else
if (Application.platform == RuntimePlatform.Android)
return $"{hostServerIP}/CDN/Android/{appVersion}";
else if (Application.platform == RuntimePlatform.IPhonePlayer)
return $"{hostServerIP}/CDN/IPhone/{appVersion}";
else if (Application.platform == RuntimePlatform.WebGLPlayer)
return $"{hostServerIP}/CDN/WebGL/{appVersion}";
else
return $"{hostServerIP}/CDN/PC/{appVersion}";
#endif
2.获取资源版本
在TestLoad方法中,添加
var operation = package.UpdatePackageVersionAsync();
yield return operation;
if (operation.Status != EOperationStatus.Succeed)
{
//更新失败
Debug.LogError(operation.Error);
yield break;
}
string packageVersion = operation.PackageVersion;
Debug.Log($"Updated package Version : {packageVersion}");
3.更新补丁清单
在TestLoad方法中,添加
//3.更新补丁清单
// 更新成功后自动保存版本号,作为下次初始化的版本。
// 也可以通过operation.SavePackageVersion()方法保存。
bool savePackageVersion = true;
var operation2 = package.UpdatePackageManifestAsync(packageVersion, savePackageVersion);
yield return operation2;
if (operation2.Status != EOperationStatus.Succeed)
{
//更新失败
Debug.LogError(operation2.Error);
yield break;
}
4.下载补丁包
新建名为Download协程方法
IEnumerator Download()
{
int downloadingMaxNum = 10;
int failedTryAgain = 3;
var package = YooAssets.GetPackage("DefaultPackage");
var downloader = package.CreateResourceDownloader(downloadingMaxNum, failedTryAgain);
//没有需要下载的资源
if (downloader.TotalDownloadCount == 0)
{
yield break;
}
//需要下载的文件总数和总大小
int totalDownloadCount = downloader.TotalDownloadCount;
long totalDownloadBytes = downloader.TotalDownloadBytes;
//注册回调方法
downloader.OnDownloadErrorCallback = OnDownloadErrorFunction;
downloader.OnDownloadProgressCallback = OnDownloadProgressUpdateFunction;
downloader.OnDownloadOverCallback = OnDownloadOverFunction;
downloader.OnStartDownloadFileCallback = OnStartDownloadFileFunction;
//开启下载
downloader.BeginDownload();
yield return downloader;
//检测下载结果
if (downloader.Status == EOperationStatus.Succeed)
{
//下载成功
Debug.Log("更新完成");
}
else
{
//下载失败
Debug.Log("更新失败");
}
}
然后在TestLoad方法中添加调用
//4.下载补丁包
yield return Download();
5.加载资源
资源有好多种,场景、预制体、文本、声音、精灵等等,每一种都有对应的加载写法,在加载资源的代码之前,应当先设置好资源的路径,对应起来才能程序找到。
资源的设置界面
在unityProject面板下新建MyAsset文件夹,然后在该文件夹下新建Prefabs、Scenes、Configs文件夹。
然后步骤如图所示,新建三个分别对应Prefabs、Scenes、Configs。
注意:对应文本文件时,选择PackRawFile。
此时,我们新建一个名为MyScene的场景,放在Assets/MyAssets/Scenes下。
如果该文件夹之前已经拖到对应的Collector下,则不用再重复拖动,这个文件夹下添加新的东西都可以被加载出来,开始码代码。
//加载场景
string location = "MyScene";
var sceneMode = UnityEngine.SceneManagement.LoadSceneMode.Single;
bool suspendLoad = false;
SceneOperationHandle handle = package.LoadSceneAsync(location, sceneMode, suspendLoad);
yield return handle;
Debug.Log($"Scene name is {handle.SceneObject.name}");
然后再建一个预制体Cube,放在Assets/MyAssets/Prefabs下。
//加载prefab
AssetOperationHandle handle2 = package.LoadAssetAsync<GameObject>("Cube");
yield return handle2;
GameObject go= handle2.InstantiateSync();
//你可以设置他的位置大小一切操作
go.transform.position = Vector3.zero;
Debug.Log($"Prefab name is {go.name}");
这个只是举例子,你还可以进行更多的操作,上一篇讲到的。
最后记得再Start方法中调用这个TestLoad函数。
然后将前面提到的ConsoleToScreen脚本拖到空物体上,之后先再unity上生成一个exe文件用于测试。
然后回到unity界面,点击YooAsset/AssetBundle Builder,选择构建。
注意首次构建资源文件时,Buid Mode 要选择Force Rebuild(强制包),二次以后构建可以选择Incremental Buid(增量包)。
构建完成后会进入资源文件目录,将所有文件拷贝到资源服务器的目录中就是www/PC的文件夹下。
然后打开exe文件,就可以看到更新的内容啦!