【m】更新后台

This commit is contained in:
2025-05-30 14:50:46 +08:00
parent cbd48e8411
commit 078f080fcc
68 changed files with 764 additions and 342 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a15f3bb70d00bcd4b8c01eb4ace17c3b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
using System;
using UnityEngine;
namespace Stary.Evo
{
public class AppConfig
{
/// <summary>
/// package name
/// </summary>
public static string PackageDomainName { get; set; }
public static string IpConfig { get; set; }
public static string UserName { get; set; }
public static string PassWord { get; set; }
public static string ProductName { get; set; }
public static string Platform { get; set; }
public static string MainDomainVersion { get; set; }
/// <summary>
/// 主场景main实例物体
/// </summary>
private static GameObject _MainBaseModel;
/// <summary>
/// 赋值默认的实例
/// </summary>
public static void SetDefaultMainInstance(GameObject mainbase)
{
_MainBaseModel = mainbase;
}
/// <summary>
/// 赋值默认的实例
/// </summary>
public static GameObject GetDefaultMainInstance()
{
return _MainBaseModel;
}
}
public class GlobalConfig
{
public const string RikidHandLeft = "LeftHandRender/RKHandVisual/Hand_L/left_wrist/left_palm";
public const string RikidHandRight = "RightHandRender/RKHandVisual/Hand_R/right_wrist/right_palm";
public const string RikidHandRightIndexTip = "RightHandRender/RKHandVisual/Hand_R/right_wrist/right_index_metacarpal/right_index_proximal/right_index_intermediate/right_index_distal/right_index_tip";
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 43c9d32ba5934c65bf80d76e35074a1a
timeCreated: 1741162242

View File

@@ -0,0 +1,88 @@
using System;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using Main;
using Stary.Evo.AudioCore;
using UnityEngine;
using UnityEngine.Events;
using YooAsset;
namespace Stary.Evo
{
/// <summary>
/// 热更基类,应该继承的基类
/// </summary>
public class DomainBase : MonoBehaviour
{
public string DomainName { protected get; set; }
public Transform TransformInfo;
protected bool isExit { private get; set; }
/// <summary>
/// 触发Domain时调用该方法
/// </summary>
/// <param name="param"></param>
public virtual void OnEnter(string param)
{
TransformInfo = transform.Find("TransformInfo");
}
/// <summary>
/// Domain被关闭时会调该方法
/// </summary>
/// <param name="param"></param>
public virtual void OnExit()
{
isExit = true;
AudioCoreManager.StopMusic();
MainArchitecture.Interface.GetSystem<IVideoSystem>().StopVideo();
MainArchitecture.Interface.GetSystem<IDigitalHuman>().KillTalkState();
}
public virtual async Task OnEnterAsync(string param)
{
isExit = true;
}
public virtual async Task OnExitAsync()
{
await ForceUnloadAllAssets();
}
private async void OnDestroy()
{
// if (!isExit)
// {
// OnExit();
// await OnExitAsync();
// }
}
// 强制卸载所有资源包,该方法请在合适的时机调用。
// 注意Package在销毁的时候也会自动调用该方法。
private async UniTask ForceUnloadAllAssets()
{
var package = YooAssets.TryGetPackage(DomainName);
if (package != null)
{
var operation = package.UnloadAllAssetsAsync();
await operation;
await package.DestroyAsync();
YooAssets.RemovePackage(DomainName);
Resources.UnloadUnusedAssets();
GC.Collect();
GC.WaitForPendingFinalizers();
Debug.Log($"UnityEvo:{DomainName} 资源包已卸载...");
}
else
{
Debug.LogWarning($"UnityEvo:{DomainName} 资源包不存在,请检查是否已经卸载还是卸载异常...");
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8923efe3eb184e7f9283f71e2dc4ea10
timeCreated: 1742540500

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 555a223b39dcb90489791ddba86221e6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,136 @@
using System.Collections.Generic;
using UnityEngine;
using YooAsset;
namespace Main
{
/// <summary>
/// 类对象池
/// </summary>
public interface IClassPool
{
/// <summary>
/// 将类对象存进池里
/// </summary>
/// <param name="obj"></param>
void Creation(GameObject obj);
/// <summary>
/// 从未激活池里面取类对象,并放入激活池
/// </summary>
/// <returns></returns>
GameObject Spawn(Transform parent);
/// <summary>
/// 从激活池中释放类对象到未激活池中
/// </summary>
GameObject RecycleSpawn(GameObject obj);
/// <summary>
/// 回收类对象
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
/// <summary>
/// 清空类对象池
/// </summary>
void RecycleAll();
int GetPolLength();
}
public class ClassObjectPool:IClassPool
{
private AssetHandle poolObject;
/// <summary>
/// 回收对象的父物体
/// </summary>
private Transform recycle;
protected List<GameObject> activepool = new List<GameObject>();
protected Stack<GameObject> inactivepool = new Stack<GameObject>();
//没有回收的个数
protected int noRecycleCount;
public ClassObjectPool(AssetHandle poolObject,Transform recycle)
{
this.poolObject = poolObject;
this.recycle = recycle;
}
/// <summary>
/// 将类对象存进池里
/// </summary>
/// <param name="obj"></param>
public void Creation(GameObject obj)
{
inactivepool.Push(obj);
noRecycleCount++;
}
/// <summary>
/// 从未激活池里面取类对象,并放入激活池
/// </summary>
/// <param name="createIfPoolEmpty">如果为空是否new出来</param>
public GameObject Spawn(Transform parent)
{
GameObject obj = null;
if(noRecycleCount>0)
{
obj = inactivepool.Pop();
obj.transform.SetParent(parent);
noRecycleCount--;
if(obj==null)
Debug.LogErrorFormat("对象池中不存在此对象【{0}】请排查代码", obj);
}
else
{
obj= poolObject.InstantiateSync(parent);
}
obj.transform.localPosition = Vector3.zero;
obj.transform.localRotation = Quaternion.identity;
obj.transform.localScale = Vector3.one;
obj.SetActive(true);
activepool.Add(obj);
return obj;
}
/// <summary>
/// 从激活池中释放类对象到未激活池中
/// </summary>
public GameObject RecycleSpawn(GameObject obj)
{
if(obj!=null&&activepool.Contains(obj))
{
activepool.Remove(obj);
inactivepool.Push(obj);
obj.transform.parent = recycle;
obj.gameObject.SetActive(false);
noRecycleCount++;
}
return null;
}
/// <summary>
/// 清空类对象池
/// </summary>
public void RecycleAll()
{
noRecycleCount=0;
foreach (var pool in inactivepool)
{
GameObject.Destroy(pool);
}
inactivepool.Clear();
foreach (var pool in activepool)
{
GameObject.Destroy(pool);
}
activepool.Clear();
}
public int GetPolLength()
{
return inactivepool.Count;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a4fc6b70fe91726439cc0d19d7e92edc
timeCreated: 1626164240

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0346f4dcafef4fe7b87b5db6881b56e1
timeCreated: 1741164620

View File

@@ -0,0 +1,17 @@
namespace Stary.Evo
{
public class FsmLoadSystem : FsmSystem , IFsmSystem
{
private OpenDomainType OpenDomainType { get; set; }
public void SetOpenDomainType(OpenDomainType type)
{
this.OpenDomainType = type;
}
public OpenDomainType GetOpenDomainType()
{
return this.OpenDomainType;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1f012ae5832b467a802b8d775b1dae1e
timeCreated: 1744710396

View File

@@ -0,0 +1,257 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Cysharp.Threading.Tasks;
using HybridCLR;
using UnityEngine;
using YooAsset;
namespace Stary.Evo
{
public class HotFixState : AbstractFSMIState
{
public string[] PatchedAOTAssemblyList = new string[]
{
"System.Core.dll",
"UnityEngine.CoreModule.dll",
"mscorlib.dll",
"DOTween.dll",
"InformationSave.RunTime.dll",
"UIFarme.RunTime.dll",
"UniTask.dll",
"YooAsset.dll",
"com.stary.evo.runtime.dll"
};
public HotFixState(IFsmSystem system) : base(system)
{
}
public override async UniTask OnEnterAsync<T>(T param)
{
DomainConfig domainConfig = param as DomainConfig;
Debug.Log("UnityEvo:热更脚本...");
var package = YooAssets.GetPackage(AppConfig.PackageDomainName);
// Editor环境下HotUpdate.dll.bytes已经被自动加载不需要加载重复加载反而会出问题。
// 添加类型存在性检查
string fullClassName = $"{domainConfig.@namespace}.{domainConfig.className}";
#if EDITOR_SIMULATEMODE
// Editor下无需加载直接查找获得HotUpdate程序集
Assembly hotUpdateAss = System.AppDomain.CurrentDomain.GetAssemblies()
.First(a => a.GetName().Name == $"HotUpdate_{AppConfig.ASSETPACKGENAME}");
#else
string hotUpdateAssemblyName = $"HotUpdate_{AppConfig.PackageDomainName}";
Type assemblyType = IsAssetLoaded(fullClassName);
if (assemblyType!=null)
{
Debug.Log($"UnityEvo:热更程序集:{hotUpdateAssemblyName} 已经加载过了");
FsmSystem.SetCurState(nameof(LoadResState), domainConfig, assemblyType);
return;
}
//判断DLL是否下载成功
foreach (var aot in PatchedAOTAssemblyList)
{
var aotName = $"Android_{aot}";
var handle = package.LoadAssetAsync<TextAsset>(aotName);
await handle;
if (handle.Status == EOperationStatus.Succeed)
{
var assetObj = handle.AssetObject as TextAsset;
_sAssetDatas.Add(assetObj);
Debug.Log($"UnityEvo:dll:{aotName} ,下载成功");
}
else
{
Debug.Log($"UnityEvo:dll:{aotName} ,下载失败");
}
}
//先补元数据
LoadMetadataForAOTAssemblies();
// 加载热更dll
var hotfixDll = package.LoadAssetAsync<TextAsset>($"Android_HotUpdate_{AppConfig.PackageDomainName}.dll");
await hotfixDll;
var hotfixPdb = package.LoadAssetAsync<TextAsset>($"Android_HotUpdate_{AppConfig.PackageDomainName}.pdb");
await hotfixPdb;
Assembly hotUpdateAss = null;
if (hotfixDll.Status == EOperationStatus.Succeed)
{
var hotfixDllAsset = hotfixDll.AssetObject as TextAsset;
if (hotfixPdb.Status == EOperationStatus.Succeed)
{
Debug.Log($"UnityEvo:dll:加载成功!!");
var hotfixPdbAsset = hotfixPdb.AssetObject as TextAsset;
hotUpdateAss = Assembly.Load(hotfixDllAsset.bytes, hotfixPdbAsset.bytes);
}
else
{
if (hotfixDllAsset != null)
hotUpdateAss = Assembly.Load(hotfixDllAsset.bytes);
}
}
else
{
Debug.LogError($"UnityEvo:Android_HotUpdate_{AppConfig.PackageDomainName}.dll加载失败");
}
#endif
if (hotUpdateAss != null)
{
Type type = hotUpdateAss.GetType(fullClassName);
if (type == null)
{
Debug.LogError($"UnityEvo:热更类不存在!程序集: {hotUpdateAss.FullName}\n" +
$"期望类名: {fullClassName}\n" +
$"可用类型列表:{string.Join("\n", hotUpdateAss.GetTypes().Select(t => t.FullName))}");
return;
}
// 添加方法存在性检查
MethodInfo onEnterMethod = type.GetMethod("OnEnter");
MethodInfo onEnterAsyncMethod = type.GetMethod("OnEnterAsync");
if (onEnterMethod == null || onEnterAsyncMethod == null)
{
Debug.LogError($"UnityEvo:热更类进入方法缺失!\n" +
$"存在方法:{string.Join(", ", type.GetMethods().Select(m => m.Name))}");
return;
}
MethodInfo onExitMethod = type.GetMethod("OnExit");
MethodInfo onExitAsyncMethod = type.GetMethod("OnExitAsync");
if (onExitMethod == null || onExitAsyncMethod == null)
{
Debug.LogError($"UnityEvo:热更类退出方法缺失!\n" +
$"存在方法:{string.Join(", ", type.GetMethods().Select(m => m.Name))}");
return;
}
Debug.Log($"UnityEvo:dll:Type检查成功");
// AppConfig.SetDefaultHotfixType(type);
FsmSystem.SetCurState(nameof(LoadResState), domainConfig, type);
// // 创建热更类实例
// DomainBase hotfixInstance = AppConfig.HOTFIXBASE.AddComponent(type) as DomainBase;
//
// if (hotfixInstance == null)
// {
// Debug.LogError($"热更类{fullClassName}实例创建失败必须继承MonoBehaviour");
// return;
// }
//
//
// // 原有调用逻辑修改为使用实例
// onEnterMethod.Invoke(hotfixInstance, new object[] { "" }); // 第一个参数改为实例对象
// onEnterAsyncMethod.Invoke(hotfixInstance, new object[] { "" });
}
else
{
Debug.LogError($"UnityEvo:热更类不存在!程序集: hotUpdateAss 不存在\n" +
$"期望类名: {fullClassName}\n" +
$"可用类型列表:{string.Join("\n", hotUpdateAss.GetTypes().Select(t => t.FullName))}");
}
}
public override UniTask OnEnterAsync()
{
return UniTask.CompletedTask;
}
public override UniTask OnEnterAsync<T1, T2>(T1 param1, T2 param2)
{
return UniTask.CompletedTask;
}
#region
// //补充元数据dll的列表
// //通过RuntimeApi.LoadMetadataForAOTAssembly()函数来补充AOT泛型的原始元数据
// private List<string> AOTMetaAssemblyFiles { get; } =new()
// {
// "Android_mscorlib.dll", "Android_System.dll", "Android_System.Core.dll",
// };
private readonly List<TextAsset> _sAssetDatas = new List<TextAsset>();
// public byte[] ReadBytesFromStreamingAssets(string dllName)
// {
// if (_sAssetDatas.ContainsKey(dllName))
// {
// return _sAssetDatas[dllName].bytes;
// }
//
// return Array.Empty<byte>();
// }
/// <summary>
/// 为aot assembly加载原始metadata 这个代码放aot或者热更新都行。
/// 一旦加载后如果AOT泛型函数对应native实现不存在则自动替换为解释模式执行
/// </summary>
private void LoadMetadataForAOTAssemblies()
{
HomologousImageMode mode = HomologousImageMode.SuperSet;
// foreach (var aotDllName in AOTGenericReferences.PatchedAOTAssemblyList)
foreach (var aotDll in _sAssetDatas)
{
// var aotName = $"Android_{aotDllName}";
//
// byte[] dllBytes = ReadBytesFromStreamingAssets(aotName);
if (aotDll != null)
{
byte[] dllBytes = aotDll.bytes;
// 添加元数据加载校验
if (dllBytes == null || dllBytes.Length == 0)
{
Debug.LogError($"AOT元数据加载失败{aotDll.name}");
continue;
}
LoadImageErrorCode err = HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly(dllBytes, mode);
Debug.Log($"UnityEvo:【补元】{aotDll.name} 加载结果: {err} 字节数: {dllBytes.Length}");
}
}
}
#endregion
private Type IsAssetLoaded(string assemblyName)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var assembly in assemblies)
{
Type assemblyType = assembly.GetType(assemblyName);
if (assemblyType!=null)
{
Debug.Log("type:" + assemblyType);
return assemblyType;
}
}
return null;
}
public override void OnUpdate()
{
base.OnUpdate();
}
public override UniTask OnExitAsync()
{
_sAssetDatas.Clear();
return UniTask.CompletedTask;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 693e2ecffc1b43caa7c7818e3aba708c
timeCreated: 1741165298

View File

@@ -0,0 +1,88 @@
using Cysharp.Threading.Tasks;
using Main;
using UnityEngine;
using YooAsset;
namespace Stary.Evo
{
public class LoadResMainState : AbstractFSMIState
{
private string _doMain = "Main";
public LoadResMainState(IFsmSystem system) : base(system)
{
}
public override async UniTask OnEnterAsync()
{
Debug.Log("加载资源...");
var package = YooAssets.GetPackage(_doMain);
DomainConfig config = null;
//加载热更配置文件
var loadHotfixSettingsOp = package.LoadAssetAsync<DomainConfig>("Config_DomainConfig");
await loadHotfixSettingsOp;
if (loadHotfixSettingsOp.Status == EOperationStatus.Succeed)
{
//更新成功
Debug.Log($"UnityEvo:加载主配置文件 loadHotfixSettings : 【成功】");
config = loadHotfixSettingsOp.AssetObject as DomainConfig;
}
else
{
Debug.LogError($"UnityEvo:加载主配置文件 loadHotfixSettings : 【失败】");
}
// 加载热更资源
var loadOperation = package.LoadAssetAsync<GameObject>(config.mainPrefab);
await loadOperation;
if (loadOperation.Status == EOperationStatus.Succeed)
{
GameObject loadhotfix = loadOperation.InstantiateSync();
AppConfig.SetDefaultMainInstance(loadhotfix);
if (loadhotfix != null)
{
DomainBase hotfixInstance = loadhotfix.GetComponent<MainDomain>();
if (hotfixInstance == null)
{
hotfixInstance = loadhotfix.AddComponent<MainDomain>();
}
if (hotfixInstance == null)
{
Debug.LogError($"热更类{loadhotfix.name}实例创建失败必须继承MonoBehaviour");
return;
}
// 原有调用逻辑修改为使用实例
hotfixInstance.OnEnter("");
hotfixInstance.OnEnterAsync("");
}
}
}
public override UniTask OnEnterAsync<T>(T param)
{
return UniTask.CompletedTask;
}
public override UniTask OnEnterAsync<T1, T2>(T1 param1, T2 param2)
{
return UniTask.CompletedTask;
}
public override void OnUpdate()
{
base.OnUpdate();
}
public override UniTask OnExitAsync()
{
return UniTask.CompletedTask;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c0fed0de80c04e7fb0f513ce21fed7b9
timeCreated: 1744361114

View File

@@ -0,0 +1,92 @@
using System;
using Cysharp.Threading.Tasks;
using Stary.Evo.InformationSave;
using UnityEngine;
using YooAsset;
namespace Stary.Evo
{
public class LoadResState : AbstractFSMIState
{
public GameObject mainPrefab;
public LoadResState(IFsmSystem system) : base(system)
{
}
public override UniTask OnEnterAsync()
{
return UniTask.CompletedTask;
}
public override UniTask OnEnterAsync<T>(T param)
{
return UniTask.CompletedTask;
}
public override async UniTask OnEnterAsync<T1, T2>(T1 param1, T2 param2)
{
Debug.Log("加载资源...");
DomainConfig domainConfig = param1 as DomainConfig;
Type type = param2 as Type;
var package = YooAssets.GetPackage(domainConfig.domain);
// 加载热更资源
var loadOperation = package.LoadAssetAsync<GameObject>(domainConfig.mainPrefab);
await loadOperation;
if (loadOperation.Status == EOperationStatus.Succeed)
{
mainPrefab = loadOperation.InstantiateSync();
LocalTransformInfo info = mainPrefab.GetComponentInChildren<LocalTransformInfo>();
FsmLoadSystem fsmLoadSystem = FsmSystem as FsmLoadSystem;
if (fsmLoadSystem.GetOpenDomainType() == OpenDomainType.DEFAULT)
{
info.Switch(0);
}
else if (fsmLoadSystem.GetOpenDomainType() == OpenDomainType.VIOICE)
{
info.Switch(1);
}
if (mainPrefab != null)
{
DomainBase hotfixInstance = mainPrefab.GetComponent(type) as DomainBase;
if (hotfixInstance == null)
{
hotfixInstance = mainPrefab.AddComponent(type) as DomainBase;
}
hotfixInstance.DomainName = domainConfig.domain;
if (hotfixInstance == null)
{
Debug.LogError($"热更类{type.Name}实例创建失败必须继承MonoBehaviour");
return;
}
// 原有调用逻辑修改为使用实例
hotfixInstance.OnEnter("");
hotfixInstance.OnEnterAsync("");
}
}
}
public override void OnUpdate()
{
base.OnUpdate();
}
public override async UniTask OnExitAsync()
{
Debug.Log("UnityEvo:Domain退出...");
DomainBase domainBase = mainPrefab.GetComponent<DomainBase>();
domainBase.OnExit();
await domainBase.OnExitAsync();
GameObject.Destroy(domainBase.gameObject);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f689e40cd4654793a8f1d3ce69ba3532
timeCreated: 1741165763

View File

@@ -0,0 +1,251 @@
using System;
using System.IO;
using Cysharp.Threading.Tasks;
using Main;
using Newtonsoft.Json;
using Stary.Evo.UIFarme;
using UnityEditor;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.Networking;
using YooAsset;
namespace Stary.Evo
{
public class ResStartState : AbstractFSMIState
{
public ResStartState(IFsmSystem system) : base(system)
{
}
public override async UniTask OnEnterAsync()
{
Debug.Log("UnityEvo:启动开始资源初始化...");
//初始化读取资源配置表
HotfixMainResDomain hotfixMainResDomain = Resources.Load<HotfixMainResDomain>("HotfixMainResDomain");
if (hotfixMainResDomain != null)
{
AppConfig.IpConfig = hotfixMainResDomain.hotfixMainResDomainEntity.ipconfig;
AppConfig.UserName = hotfixMainResDomain.hotfixMainResDomainEntity.username;
AppConfig.PassWord = hotfixMainResDomain.hotfixMainResDomainEntity.password;
AppConfig.ProductName = hotfixMainResDomain.hotfixMainResDomainEntity.productName;
AppConfig.MainDomainVersion = hotfixMainResDomain.hotfixMainResDomainEntity.mainDomainVersion;
}
Debug.Log($"UnityEvo:读取资源配置表成功...{AppConfig.IpConfig}{AppConfig.UserName}{AppConfig.PassWord}");
// 初始化资源系统
YooAssets.Initialize();
//自定义网络请求器
// 设置自定义请求委托
//YooAssets.SetDownloadSystemUnityWebRequest(NasWebRequester);
//初始化资源加载模块
// 增加包存在性检查
var package = YooAssets.TryGetPackage(AppConfig.PackageDomainName);
if (package == null)
{
Debug.LogWarning($"UnityEvo:资源包 {AppConfig.PackageDomainName} 不存在,正在尝试创建...");
package = YooAssets.CreatePackage(AppConfig.PackageDomainName);
}
YooAssets.SetDefaultPackage(package);
// 初始化资源包
#if EDITOR_SIMULATEMODE
await EDITOR_SIMULATEMODE(package);
FsmSystem.SetCurState(nameof(ResUpdateServerState));
#elif OFFLINE_PLAYMODE
await OFFLINE_PLAYMODE(package);
FsmSystem.SetCurState(nameof(ResUpdateLocalState));
#elif HOST_PLAYMODE
if (package.PackageName.Equals("Main"))
{
await OFFLINE_PLAYMODE(package);
}
else
{
//登录
string url = AppConfig.IpConfig + "/Authentication/login";
bool isLogin = await WebRequestSystem.Login(url, AppConfig.UserName, AppConfig.PassWord);
if (isLogin)
await HOST_PLAYMODE(package);
else
await OFFLINE_PLAYMODE(package);
}
FsmSystem.SetCurState(nameof(ResUpdateLocalState));
#elif WEB_PLAYMODE
// IRemoteServices remoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
// var webServerFileSystemParams = FileSystemParameters.CreateDefaultWebServerFileSystemParameters();
// var webRemoteFileSystemParams =
// FileSystemParameters.CreateDefaultWebRemoteFileSystemParameters(remoteServices); //支持跨域下载
//
// var initParameters = new WebPlayModeParameters();
// initParameters.WebServerFileSystemParameters = webServerFileSystemParams;
// initParameters.WebRemoteFileSystemParameters = webRemoteFileSystemParams;
//
// var initOperation = package.InitializeAsync(initParameters);
// await initOperation;
//
// if (initOperation.Status == EOperationStatus.Succeed)
// Debug.Log("UnityEvo:资源包初始化成功!");
// else
// Debug.LogError($"UnityEvo:资源包初始化失败:{initOperation.Error}");
Debug.LogError($"UnityEvo:暂不支持");
#endif
}
public override UniTask OnEnterAsync<T>(T param)
{
return UniTask.CompletedTask;
}
public override UniTask OnEnterAsync<T1, T2>(T1 param1, T2 param2)
{
return UniTask.CompletedTask;
}
public override void OnUpdate()
{
base.OnUpdate();
}
public override UniTask OnExitAsync()
{
return UniTask.CompletedTask;
}
private async UniTask EDITOR_SIMULATEMODE(ResourcePackage package)
{
var buildResult = EditorSimulateModeHelper.SimulateBuild(AppConfig.PackageDomainName);
var packageRoot = buildResult.PackageRootDirectory;
var editorFileSystemParameters = FileSystemParameters.CreateDefaultEditorFileSystemParameters(packageRoot);
var initParams = new EditorSimulateModeParameters();
initParams.EditorFileSystemParameters = editorFileSystemParameters;
var initialization = package.InitializeAsync(initParams);
await initialization;
if (initialization.Status == EOperationStatus.Succeed)
{
Assert.AreEqual(EOperationStatus.Succeed, initialization.Status);
Debug.Log("UnityEvo:资源包初始化成功!");
}
else
{
Debug.LogError($"UnityEvo:资源包初始化失败:{initialization.Error}");
}
}
private async UniTask OFFLINE_PLAYMODE(ResourcePackage package)
{
var buildinFileSystemParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters();
var initParameters = new OfflinePlayModeParameters();
initParameters.BuildinFileSystemParameters = buildinFileSystemParams;
var initOperation = package.InitializeAsync(initParameters);
await initOperation;
if (initOperation.Status == EOperationStatus.Succeed)
Debug.Log("UnityEvo:从本地加载资源包,初始化成功!");
else
Debug.LogError($"UnityEvo:从本地加载资源包,初始化失败:{initOperation.Error}");
}
public async UniTask HOST_PLAYMODE(ResourcePackage package)
{
// 新增平台判断代码
#if UNITY_EDITOR
BuildTarget buildTarget = UnityEditor.EditorUserBuildSettings.activeBuildTarget;
AppConfig.Platform = buildTarget.ToString();
#else
AppConfig.Platform = Application.platform.ToString();
#endif
Debug.Log($"目标平台标识: {AppConfig.Platform}");
// 请求资源版本
string url = $"{AppConfig.IpConfig}/ResDomain/GetResDomainByDomain";
var resDmainRequst = new ResDmainRequst()
{
ProductName = AppConfig.ProductName,
DomainName = AppConfig.PackageDomainName,
Platform = AppConfig.Platform,
};
//获取服务器版本
var resDmainMessageEntity = await WebRequestSystem.Post(url, JsonConvert.SerializeObject(resDmainRequst));
if (resDmainMessageEntity.code == 200)
{
ResDmainResponse resDmainResponse =
JsonConvert.DeserializeObject<ResDmainResponse>(resDmainMessageEntity.data.ToString());
//获取当前版本
var oldVersion = PlayerPrefs.GetString($"{AppConfig.PackageDomainName}_GAME_VERSION");
//版本不一致,开始下载
if (resDmainResponse.PackageVersion != oldVersion)
{
await Download(resDmainResponse.DocumentFileId);
PlayerPrefs.SetString($"{AppConfig.PackageDomainName}_GAME_VERSION",
resDmainResponse.PackageVersion);
}
else //版本一致,加载缓存资源
{
Debug.Log($"UnityEvo:资源版本一致,自动跳过更新...");
}
}
else
{
Debug.LogError($"UnityEvo:获取资源版本失败: 【{resDmainMessageEntity.message}】");
}
var initParameters = new OfflinePlayModeParameters();
var buildinFileSystemParams = FileSystemParameters.CreateDefaultBuildinFileSystemParameters(null,
$"{Application.persistentDataPath}/DownloadedContent/{AppConfig.PackageDomainName}");
buildinFileSystemParams.AddParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, true);
buildinFileSystemParams.AddParameter(FileSystemParametersDefine.COPY_BUILDIN_PACKAGE_MANIFEST, true);
initParameters.BuildinFileSystemParameters = buildinFileSystemParams;
// initParameters.CacheFileSystemParameters = cacheFileSystemParams;
var initOperation = package.InitializeAsync(initParameters);
await initOperation;
if (initOperation.Status == EOperationStatus.Succeed)
Debug.Log("UnityEvo:从远程加载资源包,初始化成功!");
else
Debug.LogError($"UnityEvo:从远程加载资源包,初始化失败:{initOperation.Error}");
}
public async UniTask Download(string fileId)
{
// 在任意MonoBehaviour或DomainBase派生类中
string loadPath = $"{Application.persistentDataPath}/DownloadedContent/{AppConfig.PackageDomainName}";
if (Directory.Exists(loadPath))
{
Directory.Delete(loadPath, true);
}
await MainArchitecture.Interface.GetSystem<IPanelSystem>()
.PushQueue<ProgressBarPanel>(Camera.main.transform, "Main");
await ZipTool.DownloadAndUnzipAsync(fileId, loadPath, DownLoadProgress, UnzipProgress);
}
private void DownLoadProgress(float progress)
{
Debug.Log($"下载进度:{progress:P0}");
MainArchitecture.Interface.GetSystem<IPanelSystem>()
.SendPanelEvent(ProgressBarPanel.ProgressBarType.Add, "下载中", progress);
}
private void UnzipProgress(float progress)
{
Debug.Log($"解压进度:{progress:P0}");
MainArchitecture.Interface.GetSystem<IPanelSystem>()
.SendPanelEvent(ProgressBarPanel.ProgressBarType.Add, "解压中", progress);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2462c737fc9c4b53b35557f8a6aac453
timeCreated: 1741165298

View File

@@ -0,0 +1,152 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Assertions;
using YooAsset;
namespace Stary.Evo
{
public class ResUpdateLocalState : AbstractFSMIState
{
public ResUpdateLocalState(IFsmSystem system) : base(system)
{
}
public override async UniTask OnEnterAsync()
{
//初始化读取资源配置表
var package = YooAssets.GetPackage(AppConfig.PackageDomainName);
//更新失败
Debug.Log($"UnityEvo:切换为加载本地缓存资源...");
string packageVersion = "";
if (package.PackageName.Equals("Main"))
{
var operation = package.RequestPackageVersionAsync();
await operation;
if (operation.Status == EOperationStatus.Succeed)
{
//更新成功
packageVersion = operation.PackageVersion;
Debug.Log($"Unity:【Main】Request package Version : {packageVersion}");
}
else
{
//更新失败
Debug.LogError("Unity:【Main】"+operation.Error);
}
}
else
{
// 获取上次成功记录的版本
packageVersion = PlayerPrefs.GetString($"{AppConfig.PackageDomainName}_GAME_VERSION", string.Empty);
if (string.IsNullOrEmpty(packageVersion))
{
Debug.Log($"UnityEvo:没有找到本地版本记录,需要更新资源!");
return;
}
}
Debug.Log($"UnityEvo:获取资源版本 Version : 【{packageVersion}】");
Debug.Log($"UnityEvo:开始加载本地资源...");
// Assert.AreEqual(EOperationStatus.Succeed, requetVersionOp.Status);
// 加载本地缓存的资源清单文件
var updateManifestOp = package.UpdatePackageManifestAsync(packageVersion);
await updateManifestOp;
if (updateManifestOp.Status == EOperationStatus.Succeed)
{
//更新成功
Debug.Log($"UnityEvo:更新本地资源清单 updateManifest : 【成功】");
}
else
{
//更新失败
Debug.LogError($"UnityEvo:加载本地资源清单文件失败,需要更新资源!: 【{updateManifestOp.Error}】");
return;
}
Assert.AreEqual(EOperationStatus.Succeed, updateManifestOp.Status);
//4.下载补丁包
await Download();
//加载热更配置文件
var loadHotfixSettingsOp = package.LoadAssetAsync<DomainConfig>("Config_DomainConfig");
await loadHotfixSettingsOp;
DomainConfig domainConfig = null;
if (loadHotfixSettingsOp.Status == EOperationStatus.Succeed)
{
//更新成功
Debug.Log($"UnityEvo:加载热更配置文件 DomainConfig : 【成功】");
domainConfig = loadHotfixSettingsOp.AssetObject as DomainConfig;
}
else
{
Debug.LogError($"UnityEvo:加载热更配置文件 DomainConfig : 【失败】");
}
if (package.PackageName.Equals("Main"))
{
FsmSystem.SetCurState(nameof(LoadResMainState));
}
else
{
if (domainConfig == null)
{
Debug.LogError($"UnityEvo:【{package.PackageName}】加载DomainConfig为空无法继续执行后续流程请检查");
}
FsmSystem.SetCurState(nameof(HotFixState), domainConfig);
}
}
public override UniTask OnEnterAsync<T>(T param)
{
return UniTask.CompletedTask;
}
public override UniTask OnEnterAsync<T1, T2>(T1 param1, T2 param2)
{
return UniTask.CompletedTask;
}
public override void OnUpdate()
{
base.OnUpdate();
}
public override UniTask OnExitAsync()
{
return UniTask.CompletedTask;
}
#region
public async UniTask Download()
{
int downloadingMaxNum = 1;
int failedTryAgain = 1;
var package = YooAssets.GetPackage(AppConfig.PackageDomainName);
var downloader = package.CreateResourceDownloader(downloadingMaxNum, failedTryAgain);
// 在正常开始游戏之前,还需要验证本地清单内容的完整性。
if (downloader.TotalDownloadCount > 0)
{
Debug.Log("UnityEvo:资源内容本地并不完整,需要更新资源!");
return;
}
}
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: eca158039896455dba3ded1eb703a5da
timeCreated: 1742291100

View File

@@ -0,0 +1,202 @@
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Assertions;
using YooAsset;
namespace Stary.Evo
{
public class ResUpdateServerState : AbstractFSMIState
{
public ResUpdateServerState(IFsmSystem system) : base(system)
{
}
public override async UniTask OnEnterAsync()
{
Debug.Log("UnityEvo:开始资源更新...");
// //初始化读取资源配置表
var package = YooAssets.GetPackage(AppConfig.PackageDomainName);
// 请求资源版本
var requetVersionOp = package.RequestPackageVersionAsync();
await requetVersionOp;
string packageVersion = "";
if (requetVersionOp.Status == EOperationStatus.Succeed)
{
//更新成功
packageVersion = requetVersionOp.PackageVersion;
PlayerPrefs.SetString($"{AppConfig.PackageDomainName}_GAME_VERSION", packageVersion);
Debug.Log($"UnityEvo:获取资源版本 Version : 【{packageVersion}】");
Debug.Log($"UnityEvo:开始加载服务器资源...");
}
else
{
Debug.LogError($"UnityEvo:获取资源版本失败: 【{requetVersionOp.Error}】");
FsmSystem.SetCurState(nameof(ResUpdateLocalState));
return;
}
// Assert.AreEqual(EOperationStatus.Succeed, requetVersionOp.Status);
// 更新资源清单
var updateManifestOp = package.UpdatePackageManifestAsync(packageVersion);
await updateManifestOp;
if (updateManifestOp.Status == EOperationStatus.Succeed)
{
//更新成功
Debug.Log($"UnityEvo:更新资源清单 updateManifest : 【成功】");
}
else
{
//更新失败
Debug.LogError($"UnityEvo:更新资源清单失败: 【{updateManifestOp.Error}】");
}
Assert.AreEqual(EOperationStatus.Succeed, updateManifestOp.Status);
//4.下载补丁包
await Download();
//加载热更配置文件
var loadHotfixSettingsOp = package.LoadAssetAsync<DomainConfig>("Config_DomainConfig");
await loadHotfixSettingsOp;
DomainConfig domainConfig = null;
if (loadHotfixSettingsOp.Status == EOperationStatus.Succeed)
{
//更新成功
Debug.Log($"UnityEvo:加载热更配置文件 loadHotfixSettings : 【成功】");
domainConfig = loadHotfixSettingsOp.AssetObject as DomainConfig;
}
else
{
Debug.LogError($"UnityEvo:加载热更配置文件 loadHotfixSettings : 【失败】");
}
if (package.PackageName.Equals("Main"))
{
FsmSystem.SetCurState(nameof(LoadResMainState));
}
else
{
if (domainConfig == null)
{
Debug.LogError($"UnityEvo:【{package.PackageName}】加载DomainConfig为空无法继续执行后续流程请检查");
}
FsmSystem.SetCurState(nameof(HotFixState), domainConfig);
}
}
public override UniTask OnEnterAsync<T>(T param)
{
return UniTask.CompletedTask;
}
public override UniTask OnEnterAsync<T1, T2>(T1 param1, T2 param2)
{
return UniTask.CompletedTask;
}
public override void OnUpdate()
{
base.OnUpdate();
}
public override UniTask OnExitAsync()
{
return UniTask.CompletedTask;
}
#region
public async UniTask Download()
{
int downloadingMaxNum = 10;
int failedTryAgain = 3;
var package = YooAssets.GetPackage(AppConfig.PackageDomainName);
var downloader = package.CreateResourceDownloader(downloadingMaxNum, failedTryAgain);
//没有需要下载的资源
if (downloader.TotalDownloadCount == 0)
{
Debug.Log("UnityEvo:没有需要下载的资源,跳过更新");
return;
}
//需要下载的文件总数和总大小
int totalDownloadCount = downloader.TotalDownloadCount;
long totalDownloadBytes = downloader.TotalDownloadBytes;
Debug.Log($"UnityEvo:需要下载的资源的个数【{totalDownloadCount}】,需要下载的资源的总大小{totalDownloadBytes/1024} MB");
//===================================适应新版本YooAsset插件的修改===================================
//注册回调方法
downloader.DownloadErrorCallback = OnDownloadErrorFunction;
downloader.DownloadUpdateCallback = OnDownloadProgressUpdateFunction;
downloader.DownloadFinishCallback = OnDownloadOverFunction;
downloader.DownloadFileBeginCallback = OnStartDownloadFileFunction;
//===================================适应新版本YooAsset插件的修改===================================
//开启下载
downloader.BeginDownload();
await downloader;
//检测下载结果
if (downloader.Status == EOperationStatus.Succeed)
{
//下载成功
Debug.Log("UnityEvo:资源更新完成");
}
else
{
//下载失败
Debug.Log("UnityEvo:资源更新失败");
}
}
//===================================适应新版本YooAsset插件的修改===================================
/// <summary>
/// 开始下载
/// </summary>
private void OnStartDownloadFileFunction(DownloadFileData downloadFileData)
{
Debug.Log($"UnityEvo:开始下载:文件名:{downloadFileData.FileName},文件大小:{downloadFileData.FileSize/1024f/1024f} MB");
}
/// <summary>
/// 下载完成
/// </summary>
private void OnDownloadOverFunction(DownloaderFinishData downloaderFinishData)
{
Debug.Log("UnityEvo:下载" + (downloaderFinishData.Succeed ? "成功" : "失败"));
}
/// <summary>
/// 更新中
/// </summary>
private void OnDownloadProgressUpdateFunction(DownloadUpdateData downloadUpdateData)
{
Debug.Log($"UnityEvo:文件总数:{downloadUpdateData.TotalDownloadCount},已下载文件数:{downloadUpdateData.CurrentDownloadCount},下载总大小:{downloadUpdateData.TotalDownloadBytes/1024f/1024f} MB已下载大小{downloadUpdateData.CurrentDownloadBytes/1024f/1024f} MB");
}
/// <summary>
/// 下载出错
/// </summary>
/// <param name="errorData"></param>
private void OnDownloadErrorFunction(DownloadErrorData errorData)
{
Debug.Log($"UnityEvo:下载出错:包名:{errorData.PackageName} 文件名:{errorData.FileName},错误信息:{errorData.ErrorInfo}");
}
//===================================适应新版本YooAsset插件的修改===================================
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: bf15fa0d3ca74b0991fd60bef616d007
timeCreated: 1741248693

View File

@@ -30,20 +30,20 @@ namespace Stary.Evo
domain = "Main";
#endif
_fsmSystem.SetOpenDomainType(OpenDomainType.DEFAULT);
AppConfig.ASSETPACKGENAME = domain;
AppConfig.PackageDomainName = domain;
_fsmSystem.SetCurState(nameof(ResStartState));
}
public void OpenDomain()
{
AppConfig.ASSETPACKGENAME = domain;
AppConfig.PackageDomainName = domain;
_fsmSystem.SetCurState(nameof(ResStartState));
}
public void OpenDomain(string domain, OpenDomainType openDomainType)
{
_fsmSystem.SetOpenDomainType(openDomainType);
AppConfig.ASSETPACKGENAME = domain;
AppConfig.PackageDomainName = domain;
_fsmSystem.SetCurState(nameof(ResStartState));
}