mirror of
https://gitee.com/jisol/jisol-game/
synced 2025-09-26 18:26:23 +00:00
提交热更新
This commit is contained in:
@@ -29,8 +29,8 @@ MonoBehaviour:
|
||||
AssetTags:
|
||||
ActiveRuleName: EnableGroup
|
||||
Collectors:
|
||||
- CollectPath: Assets/HotAssets/Resource
|
||||
CollectorGUID: 73d51e542e260624aad32232794a401c
|
||||
- CollectPath: Assets/HotResources
|
||||
CollectorGUID: 9cf7250c4c4b62c4ea6c677e2007ec5a
|
||||
CollectorType: 0
|
||||
AddressRuleName: AddressByFileName
|
||||
PackRuleName: PackSeparately
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -147,7 +147,6 @@ Transform:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 67180524}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
@@ -155,6 +154,7 @@ Transform:
|
||||
m_Children:
|
||||
- {fileID: 1371077986}
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &67180526
|
||||
MonoBehaviour:
|
||||
@@ -254,13 +254,13 @@ Transform:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 790008994}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
|
||||
m_LocalPosition: {x: 0, y: 3, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
|
||||
--- !u!1 &1371077985
|
||||
GameObject:
|
||||
@@ -286,13 +286,13 @@ Transform:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1371077985}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 67180525}
|
||||
m_RootOrder: -2
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!114 &1371077987
|
||||
MonoBehaviour:
|
||||
@@ -307,11 +307,13 @@ MonoBehaviour:
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_AvailableProcedureTypeNames:
|
||||
- HotMain.SHGame.Procedure.ProcedureInitializePackage
|
||||
- HotMain.SHGame.Procedure.ProcedureLoadHot
|
||||
- HotMain.SHGame.Procedure.ProcedureLoadLauncher
|
||||
- Plugins.SHFrame.SHGame.Procedure.ProcedureInitializePackage
|
||||
- Plugins.SHFrame.SHGame.Procedure.ProcedureUpdatePackageManifest
|
||||
- Plugins.SHFrame.SHGame.Procedure.ProcedureUpdatePackageVersion
|
||||
m_EntranceProcedureTypeName: Plugins.SHFrame.SHGame.Procedure.ProcedureInitializePackage
|
||||
- HotMain.SHGame.Procedure.ProcedurePackageDownloader
|
||||
- HotMain.SHGame.Procedure.ProcedureUpdatePackageManifest
|
||||
- HotMain.SHGame.Procedure.ProcedureUpdatePackageVersion
|
||||
m_EntranceProcedureTypeName: HotMain.SHGame.Procedure.ProcedureInitializePackage
|
||||
--- !u!1 &1371947665
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -396,18 +398,11 @@ Transform:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 1371947665}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 1, z: -10}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 0}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1660057539 &9223372036854775807
|
||||
SceneRoots:
|
||||
m_ObjectHideFlags: 0
|
||||
m_Roots:
|
||||
- {fileID: 1371947668}
|
||||
- {fileID: 790008996}
|
||||
- {fileID: 67180525}
|
||||
|
@@ -1,13 +1,11 @@
|
||||
using System.IO;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Plugins.SHFrame.SHGame.YooAsset;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using HotMain.SHGame.YooAsset;
|
||||
using HotMain.SHGame.YooAsset.StreamingAssetsHelper;
|
||||
using SHFrame;
|
||||
using SHFrame.FSM;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
namespace Plugins.SHFrame.SHGame.Procedure
|
||||
namespace HotMain.SHGame.Procedure
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化资源包
|
||||
@@ -15,7 +13,7 @@ namespace Plugins.SHFrame.SHGame.Procedure
|
||||
public class ProcedureInitializePackage : ProcedureBase
|
||||
{
|
||||
|
||||
public static EPlayMode PlayMode = EPlayMode.OfflinePlayMode;
|
||||
public static EPlayMode PlayMode = EPlayMode.HostPlayMode;
|
||||
public static string RawFilePackageName = "RawFilePackage";
|
||||
public static string DefaultPackageName = "DefaultPackage";
|
||||
|
||||
@@ -23,6 +21,7 @@ namespace Plugins.SHFrame.SHGame.Procedure
|
||||
//热更新的dll名称
|
||||
public static readonly string[] HotDllName =
|
||||
{
|
||||
"HotSamples.dll"
|
||||
};
|
||||
|
||||
public static readonly string[] AotMetaAssemblyFiles =
|
||||
@@ -85,13 +84,14 @@ namespace Plugins.SHFrame.SHGame.Procedure
|
||||
initOperation = package.InitializeAsync(initParametersOfflinePlayMode);
|
||||
break;
|
||||
case EPlayMode.HostPlayMode:
|
||||
// //联机运行模式
|
||||
// var initParametersHostPlayMode = new HostPlayModeParameters
|
||||
// {
|
||||
// BuildinQueryServices = new GameQueryServices(),
|
||||
// RemoteServices = new RemoteServices(GetHostServerURL(packageName), GetHostServerURL(packageName))
|
||||
// };
|
||||
// initOperation = package.InitializeAsync(initParametersHostPlayMode);
|
||||
//联机运行模式
|
||||
// 注意:GameQueryServices.cs 太空战机的脚本类,详细见StreamingAssetsHelper.cs
|
||||
string HostServer = $"http://ngame.jisol.cn/JNGame2/{packageName}";
|
||||
var createParameters = new HostPlayModeParameters();
|
||||
createParameters.DecryptionServices = new FileStreamDecryption();
|
||||
createParameters.BuildinQueryServices = new GameQueryServices();
|
||||
createParameters.RemoteServices = new RemoteServices(HostServer, HostServer);
|
||||
initOperation = package.InitializeAsync(createParameters);
|
||||
break;
|
||||
}
|
||||
|
||||
|
59
JNFrame2/Assets/HotMain/SHGame/Procedure/ProcedureLoadHot.cs
Normal file
59
JNFrame2/Assets/HotMain/SHGame/Procedure/ProcedureLoadHot.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System.Reflection;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using SHFrame;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
namespace HotMain.SHGame.Procedure
|
||||
{
|
||||
public class ProcedureLoadHot : ProcedureBase
|
||||
{
|
||||
|
||||
protected override void OnEnter(SHFrame.FSM.IFsm<IProcedureManager> procedureOwner)
|
||||
{
|
||||
base.OnEnter(procedureOwner);
|
||||
MainLoad(procedureOwner).Forget();
|
||||
}
|
||||
|
||||
private async UniTask MainLoad(SHFrame.FSM.IFsm<IProcedureManager> procedureOwner)
|
||||
{
|
||||
// 加载热更dll
|
||||
foreach (var name in ProcedureInitializePackage.HotDllName)
|
||||
{
|
||||
await LoadHotfixDll(ProcedureInitializePackage.RawFilePackageName, name);
|
||||
}
|
||||
|
||||
// 实例化热更新入口 执行游戏初始化(配置表初始化、UI模块初始化、获取玩家数据之类的操作)
|
||||
ResourcePackage package = YooAssets.GetPackage(ProcedureInitializePackage.DefaultPackageName);
|
||||
var go = await LoadGameObject(package, "HotPrefab");
|
||||
go.name = $"Resource_{package.GetPackageVersion()}_{YooAssets.GetPackage(ProcedureInitializePackage.RawFilePackageName).GetPackageVersion()}";
|
||||
Log.Warning($"Prefab name is {go.name}");
|
||||
}
|
||||
|
||||
public static async UniTask<Assembly> LoadHotfixDll(string packageName, string name)
|
||||
{
|
||||
Log.Warning($"加载热更dll:{name}");
|
||||
var package = YooAssets.GetPackage(packageName);
|
||||
var handle = package.LoadRawFileAsync(name);
|
||||
await handle.ToUniTask();
|
||||
var dllBytes = handle.GetRawFileData();
|
||||
var assembly = Assembly.Load(dllBytes);
|
||||
Log.Warning($"加载热更dll完成:{name}");
|
||||
return assembly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步加载GameObject
|
||||
/// </summary>
|
||||
/// <param name="package"></param>
|
||||
/// <param name="assetNames">YooAsset中打包的资源名称</param>
|
||||
/// <returns>返回GameObject</returns>
|
||||
public static async UniTask<GameObject> LoadGameObject(ResourcePackage package, string assetNames)
|
||||
{
|
||||
var handle = package.LoadAssetAsync<GameObject>(assetNames);
|
||||
await handle.ToUniTask();
|
||||
return handle.InstantiateSync();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4dc4cea51e784614969d04772ebdfc68
|
||||
timeCreated: 1728975475
|
@@ -3,7 +3,6 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using HybridCLR;
|
||||
using Plugins.SHFrame.SHGame.Procedure;
|
||||
using SHFrame;
|
||||
using SHFrame.FSM;
|
||||
using YooAsset;
|
||||
@@ -25,6 +24,8 @@ namespace HotMain.SHGame.Procedure
|
||||
// 打包时内置在包体内的资源 直接先使用包体资源,实例化 登录加载界面后,再去检查是否需要下载更新
|
||||
//加载AOT
|
||||
await LoadMetadataForAOTAssemblies();
|
||||
//切换到更新资源版本
|
||||
ChangeState<ProcedurePackageDownloader>(procedureOwner);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -0,0 +1,194 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using SHFrame;
|
||||
using SHFrame.FSM;
|
||||
using YooAsset;
|
||||
|
||||
namespace HotMain.SHGame.Procedure
|
||||
{
|
||||
public class ProcedurePackageDownloader : ProcedureBase
|
||||
{
|
||||
|
||||
private int launcherPatchCount = 0;
|
||||
|
||||
private int totalDownloadCount = 0;
|
||||
private long totalDownloadBytes = 0;
|
||||
|
||||
protected override void OnEnter(IFsm<IProcedureManager> procedureOwner)
|
||||
{
|
||||
base.OnEnter(procedureOwner);
|
||||
launcherPatchCount = 0;
|
||||
totalDownloadCount = 0;
|
||||
totalDownloadBytes = 0;
|
||||
Download(procedureOwner);
|
||||
}
|
||||
|
||||
private async void Download(IFsm<IProcedureManager> procedureOwner)
|
||||
{
|
||||
// //检查launcher标签的资源
|
||||
// launcherPatchCount += TryGetTagPatchCount(ProcedureInitializePackage.RawFilePackageName, YooTag.LAUNCHER);
|
||||
// launcherPatchCount += TryGetTagPatchCount(ProcedureInitializePackage.DefaultPackageName, YooTag.LAUNCHER);
|
||||
//
|
||||
// if (launcherPatchCount > 0)
|
||||
// {
|
||||
// Log.Warning("launcher资源需要更新,下载完成后需要重启游戏");
|
||||
// totalDownloadCount += launcherPatchCount;
|
||||
// }
|
||||
|
||||
// 完全通过远端获取的资源,每次启动游戏都检查是否需要更新
|
||||
//TODO 把这个玩意拆分成 1、获取下载文件大小,2、提示总的下载大小,提示确认,3、开始下载
|
||||
ResourcePackage rawFilePackage = YooAssets.GetPackage(ProcedureInitializePackage.RawFilePackageName);
|
||||
totalDownloadBytes += TryDownloadPatch(rawFilePackage);
|
||||
ResourcePackage defaultPackage = YooAssets.GetPackage(ProcedureInitializePackage.DefaultPackageName);
|
||||
totalDownloadBytes += TryDownloadPatch(defaultPackage);
|
||||
|
||||
if (totalDownloadCount > 0 || totalDownloadBytes > 0)
|
||||
{
|
||||
|
||||
Log.Warning("开始下载资源");
|
||||
|
||||
//进行下载
|
||||
var result = await GetDownload(rawFilePackage);
|
||||
if (!result) return;
|
||||
|
||||
//进行下载
|
||||
result = await GetDownload(defaultPackage);
|
||||
if (!result) return;
|
||||
|
||||
//判断launcher资源是否有更新,有就弹窗重启游戏
|
||||
if (launcherPatchCount > 0)
|
||||
{
|
||||
Log.Warning("launcher资源有更新,需要重启游戏");
|
||||
return;
|
||||
}
|
||||
|
||||
// 资源下载完毕
|
||||
Log.Warning("资源下载完毕");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning("没有资源需要更新");
|
||||
|
||||
}
|
||||
|
||||
//切换到加载热更包入口
|
||||
ChangeState<ProcedureLoadHot>(procedureOwner);
|
||||
}
|
||||
|
||||
private int TryGetTagPatchCount(string packageName, string tag)
|
||||
{
|
||||
ResourcePackage package = YooAssets.GetPackage(packageName);
|
||||
//4.下载补丁包信息,反馈到弹窗
|
||||
var downloader = package.CreateResourceDownloader(tag, 10, 3, 60);
|
||||
//没有需要下载的资源
|
||||
if (downloader.TotalDownloadCount == 0)
|
||||
{
|
||||
Log.Warning($"{package.PackageName} tag {tag} 没有资源更新");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//需要下载的文件总数和总大小
|
||||
Log.Warning($"{package.PackageName} tag {tag} 文件总数:{downloader.TotalDownloadCount}:::总大小:{downloader.TotalDownloadBytes}");
|
||||
return totalDownloadCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="package"></param>
|
||||
private long TryDownloadPatch(ResourcePackage package)
|
||||
{
|
||||
//4.下载补丁包信息,反馈到弹窗
|
||||
var downloader = package.CreateResourceDownloader(10, 3, 60);
|
||||
//没有需要下载的资源
|
||||
if (downloader.TotalDownloadCount == 0)
|
||||
{
|
||||
Log.Warning($"{package.PackageName} all 没有资源更新");
|
||||
return 0;
|
||||
}
|
||||
|
||||
totalDownloadCount++;
|
||||
//需要下载的文件总数和总大小
|
||||
Log.Warning($"{package.PackageName} 文件总数:{downloader.TotalDownloadCount}:::总大小:{downloader.TotalDownloadBytes}");
|
||||
return downloader.TotalDownloadBytes;
|
||||
}
|
||||
|
||||
private async UniTask<bool> GetDownload(ResourcePackage package)
|
||||
{
|
||||
var downloader = package.CreateResourceDownloader(10, 3, 60);
|
||||
|
||||
//注册回调方法
|
||||
downloader.OnDownloadErrorCallback = OnDownloadErrorFunction;
|
||||
downloader.OnDownloadProgressCallback = OnDownloadProgressUpdateFunction;
|
||||
downloader.OnDownloadOverCallback = OnDownloadOverFunction;
|
||||
downloader.OnStartDownloadFileCallback = OnStartDownloadFileFunction;
|
||||
|
||||
//开启下载
|
||||
downloader.BeginDownload();
|
||||
await downloader.ToUniTask();
|
||||
//检测下载结果
|
||||
if (downloader.Status == EOperationStatus.Succeed)
|
||||
{
|
||||
Log.Debug("更新完成!");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//下载失败
|
||||
Log.Error("更新失败!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region yooasset下载回调函数
|
||||
|
||||
/// <summary>
|
||||
/// 下载数据大小
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="sizeBytes"></param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private void OnStartDownloadFileFunction(string fileName, long sizeBytes)
|
||||
{
|
||||
Log.Debug($"开始下载:文件名:{fileName}, 文件大小:{sizeBytes}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载完成与否
|
||||
/// </summary>
|
||||
/// <param name="isSucceed"></param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private void OnDownloadOverFunction(bool isSucceed)
|
||||
{
|
||||
Log.Debug("下载" + (isSucceed ? "成功" : "失败"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新中
|
||||
/// </summary>
|
||||
/// <param name="totalCount"></param>
|
||||
/// <param name="currentCount"></param>
|
||||
/// <param name="totalBytes"></param>
|
||||
/// <param name="currentBytes"></param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private void OnDownloadProgressUpdateFunction(int totalCount, int currentCount, long totalBytes, long currentBytes)
|
||||
{
|
||||
Log.Debug($"文件总数:{totalCount}, 已下载文件数:{currentCount}, 下载总大小:{totalBytes}, 已下载大小:{currentBytes}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载出错
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="error"></param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
private void OnDownloadErrorFunction(string fileName, string error)
|
||||
{
|
||||
Log.Error($"下载出错:文件名:{fileName}, 错误信息:{error}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 883e7ebff2f7432f94ecd48ae94a925a
|
||||
timeCreated: 1728963960
|
@@ -3,7 +3,7 @@ using SHFrame;
|
||||
using SHFrame.FSM;
|
||||
using YooAsset;
|
||||
|
||||
namespace Plugins.SHFrame.SHGame.Procedure
|
||||
namespace HotMain.SHGame.Procedure
|
||||
{
|
||||
/// <summary>
|
||||
/// 更新资源清单
|
||||
|
@@ -1,10 +1,9 @@
|
||||
using Cysharp.Threading.Tasks;
|
||||
using HotMain.SHGame.Procedure;
|
||||
using SHFrame;
|
||||
using SHFrame.FSM;
|
||||
using YooAsset;
|
||||
|
||||
namespace Plugins.SHFrame.SHGame.Procedure
|
||||
namespace HotMain.SHGame.Procedure
|
||||
{
|
||||
/// <summary>
|
||||
/// 更新资源版本号
|
||||
|
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d11821e0e1c8454f95b48b4de4f9d509
|
||||
timeCreated: 1728983038
|
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HotMain.SHGame.YooAsset.StreamingAssetsHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 内置资源清单
|
||||
/// </summary>
|
||||
public class BuildinFileManifest : ScriptableObject
|
||||
{
|
||||
[Serializable]
|
||||
public class Element
|
||||
{
|
||||
public string PackageName;
|
||||
public string FileName;
|
||||
public string FileCRC32;
|
||||
}
|
||||
|
||||
public List<Element> BuildinFiles = new List<Element>();
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71b02dfa7aa9d4545b3417a18477fbee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,11 @@
|
||||
|
||||
namespace HotMain.SHGame.YooAsset.StreamingAssetsHelper
|
||||
{
|
||||
public class StreamingAssetsDefine
|
||||
{
|
||||
/// <summary>
|
||||
/// 根目录名称(保持和YooAssets资源系统一致)
|
||||
/// </summary>
|
||||
public const string RootFolderName = "yoo";
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e44d691f47abe34e9deb9cb309074f4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -0,0 +1,165 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
namespace HotMain.SHGame.YooAsset.StreamingAssetsHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 资源文件查询服务类
|
||||
/// </summary>
|
||||
public class GameQueryServices : IBuildinQueryServices
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询内置文件的时候,是否比对文件哈希值
|
||||
/// </summary>
|
||||
public static bool CompareFileCRC = false;
|
||||
|
||||
public bool Query(string packageName, string fileName, string fileCRC)
|
||||
{
|
||||
// 注意:fileName包含文件格式
|
||||
return StreamingAssetsHelper.FileExists(packageName, fileName, fileCRC);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public sealed class StreamingAssetsHelper
|
||||
{
|
||||
public static void Init() { }
|
||||
public static bool FileExists(string packageName, string fileName, string fileCRC)
|
||||
{
|
||||
string filePath = Path.Combine(Application.streamingAssetsPath, StreamingAssetsDefine.RootFolderName, packageName, fileName);
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
if (GameQueryServices.CompareFileCRC)
|
||||
{
|
||||
string crc32 = HashUtility.FileCRC32(filePath);
|
||||
return crc32 == fileCRC;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
public sealed class StreamingAssetsHelper
|
||||
{
|
||||
private class PackageQuery
|
||||
{
|
||||
public readonly Dictionary<string, BuildinFileManifest.Element> Elements = new Dictionary<string, BuildinFileManifest.Element>(1000);
|
||||
}
|
||||
|
||||
private static bool _isInit = false;
|
||||
private static readonly Dictionary<string, PackageQuery> _packages = new Dictionary<string, PackageQuery>(10);
|
||||
|
||||
/// <summary>
|
||||
/// 初始化
|
||||
/// </summary>
|
||||
public static void Init()
|
||||
{
|
||||
if (_isInit == false)
|
||||
{
|
||||
_isInit = true;
|
||||
|
||||
var manifest = Resources.Load<BuildinFileManifest>("BuildinFileManifest");
|
||||
if (manifest != null)
|
||||
{
|
||||
foreach (var element in manifest.BuildinFiles)
|
||||
{
|
||||
if (_packages.TryGetValue(element.PackageName, out PackageQuery package) == false)
|
||||
{
|
||||
package = new PackageQuery();
|
||||
_packages.Add(element.PackageName, package);
|
||||
}
|
||||
package.Elements.Add(element.FileName, element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 内置文件查询方法
|
||||
/// </summary>
|
||||
public static bool FileExists(string packageName, string fileName, string fileCRC32)
|
||||
{
|
||||
if (_isInit == false)
|
||||
Init();
|
||||
|
||||
if (_packages.TryGetValue(packageName, out PackageQuery package) == false)
|
||||
return false;
|
||||
|
||||
if (package.Elements.TryGetValue(fileName, out var element) == false)
|
||||
return false;
|
||||
|
||||
if (GameQueryServices.CompareFileCRC)
|
||||
{
|
||||
return element.FileCRC32 == fileCRC32;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
internal class PreprocessBuild : UnityEditor.Build.IPreprocessBuildWithReport
|
||||
{
|
||||
public int callbackOrder { get { return 0; } }
|
||||
|
||||
/// <summary>
|
||||
/// 在构建应用程序前处理
|
||||
/// 原理:在构建APP之前,搜索StreamingAssets目录下的所有资源文件,然后将这些文件信息写入内置清单,内置清单存储在Resources文件夹下。
|
||||
/// </summary>
|
||||
public void OnPreprocessBuild(UnityEditor.Build.Reporting.BuildReport report)
|
||||
{
|
||||
string saveFilePath = "Assets/Resources/BuildinFileManifest.asset";
|
||||
if (File.Exists(saveFilePath))
|
||||
{
|
||||
File.Delete(saveFilePath);
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
UnityEditor.AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
string folderPath = $"{Application.dataPath}/StreamingAssets/{StreamingAssetsDefine.RootFolderName}";
|
||||
DirectoryInfo root = new DirectoryInfo(folderPath);
|
||||
if (root.Exists == false)
|
||||
{
|
||||
Debug.LogWarning($"没有发现YooAsset内置目录 : {folderPath}");
|
||||
return;
|
||||
}
|
||||
|
||||
var manifest = ScriptableObject.CreateInstance<BuildinFileManifest>();
|
||||
FileInfo[] files = root.GetFiles("*", SearchOption.AllDirectories);
|
||||
foreach (var fileInfo in files)
|
||||
{
|
||||
if (fileInfo.Extension == ".meta")
|
||||
continue;
|
||||
if (fileInfo.Name.StartsWith("PackageManifest_"))
|
||||
continue;
|
||||
|
||||
BuildinFileManifest.Element element = new BuildinFileManifest.Element();
|
||||
element.PackageName = fileInfo.Directory.Name;
|
||||
element.FileCRC32 = HashUtility.FileCRC32(fileInfo.FullName);
|
||||
element.FileName = fileInfo.Name;
|
||||
manifest.BuildinFiles.Add(element);
|
||||
}
|
||||
|
||||
if (Directory.Exists("Assets/Resources") == false)
|
||||
Directory.CreateDirectory("Assets/Resources");
|
||||
UnityEditor.AssetDatabase.CreateAsset(manifest, saveFilePath);
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
UnityEditor.AssetDatabase.Refresh();
|
||||
Debug.Log($"一共{manifest.BuildinFiles.Count}个内置文件,内置资源清单保存成功 : {saveFilePath}");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca0617f5ec2b4504b923e3205dc77f54
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -2,7 +2,7 @@
|
||||
using UnityEngine;
|
||||
using YooAsset;
|
||||
|
||||
namespace Plugins.SHFrame.SHGame.YooAsset
|
||||
namespace HotMain.SHGame.YooAsset
|
||||
{
|
||||
public class RemoteServices : IRemoteServices
|
||||
{
|
||||
@@ -17,12 +17,12 @@ namespace Plugins.SHFrame.SHGame.YooAsset
|
||||
|
||||
public string GetRemoteMainURL(string fileName)
|
||||
{
|
||||
return defaultHostServer;
|
||||
return $"{defaultHostServer}/{fileName}";
|
||||
}
|
||||
|
||||
public string GetRemoteFallbackURL(string fileName)
|
||||
{
|
||||
return fallbackHostServer;
|
||||
return $"{fallbackHostServer}/{fileName}";
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73d51e542e260624aad32232794a401c
|
||||
guid: 9cf7250c4c4b62c4ea6c677e2007ec5a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
@@ -1,5 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1bc927fe3c11b0e4db2d275b2c6eda4d
|
||||
guid: 35d982e86da74af4e95e0c2607885eb0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
@@ -4,6 +4,6 @@ public class InstantiateByAsset : MonoBehaviour
|
||||
{
|
||||
void Start()
|
||||
{
|
||||
Debug.Log("原始代码");
|
||||
Debug.Log("原始代码3333");
|
||||
}
|
||||
}
|
33
JNFrame2/Assets/Resources/BuildinFileManifest.asset
Normal file
33
JNFrame2/Assets/Resources/BuildinFileManifest.asset
Normal file
@@ -0,0 +1,33 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 71b02dfa7aa9d4545b3417a18477fbee, type: 3}
|
||||
m_Name: BuildinFileManifest
|
||||
m_EditorClassIdentifier:
|
||||
BuildinFiles:
|
||||
- PackageName: DefaultPackage
|
||||
FileName: 6e7621677213f3254dc11b107c126e0a.bundle
|
||||
FileCRC32: 3d3f3578
|
||||
- PackageName: DefaultPackage
|
||||
FileName: f0f60c08cc10dcb0e6c45442757414a3.bundle
|
||||
FileCRC32: 56c2192b
|
||||
- PackageName: RawFilePackage
|
||||
FileName: 3323855830799371855418d404b9d19f.rawfile
|
||||
FileCRC32: 5b90ef0a
|
||||
- PackageName: RawFilePackage
|
||||
FileName: 3f402809b2ac18568ce38504dca9b93e.rawfile
|
||||
FileCRC32: c9fffdca
|
||||
- PackageName: RawFilePackage
|
||||
FileName: 570a7c285a3c681be978ebe1bef253e6.rawfile
|
||||
FileCRC32: d8b11dcf
|
||||
- PackageName: RawFilePackage
|
||||
FileName: 7f16fde6c75d6666fe6c473bc200574a.rawfile
|
||||
FileCRC32: 8fdcce3d
|
@@ -1,7 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 253946b296feb0943a18d893c2ed3e16
|
||||
DefaultImporter:
|
||||
guid: f158672a438d7024c82155e424606457
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd16eaf198793c848b9a014724c43280
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1 +1 @@
|
||||
2024-10-15-131
|
||||
2024-10-15-1037
|
Binary file not shown.
@@ -1 +0,0 @@
|
||||
c918b2f39c28747c068427f6499fcc11
|
Binary file not shown.
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 465ede1251ba0bd47aac80dd35883eec
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d8da02feee275e44b1830c325be6c92
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 452e5bfcc5b1540499a40f24643eae55
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5992a68cbdfc984c9bdc6f48639d1bc
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1 +1 @@
|
||||
2024-10-15-131
|
||||
2024-10-15-1087
|
Binary file not shown.
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 87a1fb271c7f63a46ac4c113f9225de5
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1 +0,0 @@
|
||||
bb2a6addb83bf0abb192d135cd9953a6
|
@@ -1,7 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9674dff3d6102349a3c38405d57135f
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user