Files
plugin-library/Assets/00.StaryEvoTools/Runtime/HybridLoad/Fsm/LoadResState.cs
2025-10-24 19:08:10 +08:00

211 lines
7.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using Cysharp.Threading.Tasks;
#if Immersal
using Immersal.AR;
#endif
using Stary.Evo;
using Stary.Evo.InformationSave;
using UnityEngine;
using UnityEngine.SceneManagement;
using YooAsset;
namespace Stary.Evo
{
public class LoadResState : AbstractFSMIStateAsync
{
private DomainConfig.LoadResType loadResType;
public GameObject mainPrefab;
private DomainConfig domainConfig;
private string _sceneName;
public LoadResState(IFsmSystemAsync 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 = param1 as DomainConfig;
loadResType = domainConfig.loadResType;
Type type = param2 as Type;
var package = YooAssets.GetPackage(domainConfig.domain);
switch (loadResType)
{
case DomainConfig.LoadResType.Prefab:
await LoadDomainPrefab(package);
break;
case DomainConfig.LoadResType.Scene:
var sceneMode = domainConfig.loadSceneMode;
var physicsMode = LocalPhysicsMode.None;
SceneHandle handle = package.LoadSceneAsync(domainConfig.sceneIdentifier, sceneMode, physicsMode);
await handle;
Scene targetScene = SceneManager.GetSceneByName(handle.SceneName);
// targetScene.name = domainConfig.mainScene;
// 设置为 active scene 或者后续 Move 到该 scene
SceneManager.SetActiveScene(targetScene);
_sceneName = targetScene.name;
mainPrefab = GameObject.Find(domainConfig.mainPrefab);
if (mainPrefab == null)
{
await LoadDomainPrefab(package);
}
break;
}
if (domainConfig.domain != "Main")
{
LocalTransformInfo info = mainPrefab.GetOrAddComponent<LocalTransformInfo>();
FsmLoadSystem fsmLoadSystem = FsmSystem as FsmLoadSystem;
if (info._list.Count >= 2)
{
if (fsmLoadSystem.GetOpenDomainType() == OpenDomainType.PointCloud)
{
info.Switch(1);
}
else if (fsmLoadSystem.GetOpenDomainType() == OpenDomainType.VIOICE)
{
info.Switch(0);
}
else if (fsmLoadSystem.GetOpenDomainType() == OpenDomainType.ImageTracked)
{
info.transform.position = fsmLoadSystem.GetTransformCtor().position;
info.transform.rotation = Quaternion.Euler(fsmLoadSystem.GetTransformCtor().rotation);
info.transform.localScale = fsmLoadSystem.GetTransformCtor().scale;
}
else
{
info.Switch(0);
}
}
else
{
Debug.LogError($"UnityEvo:{mainPrefab.name}的TransformInfo长度小于2无法继续运行请排查");
}
}
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();
}
private async UniTask LoadDomainPrefab(ResourcePackage package)
{
// 加载热更资源
var loadOperation = package.LoadAssetAsync<GameObject>(domainConfig.mainPrefab);
await loadOperation;
if (loadOperation.Status == EOperationStatus.Succeed)
{
#if Immersal
ARSpace arSpace = GameObject.FindObjectOfType<ARSpace>();
if (arSpace != null)
{
Debug.Log("UnityEvo:找到ARSpace开始加载点云运行环境...");
mainPrefab = loadOperation.InstantiateSync(arSpace.transform);
} else
{
Debug.Log("UnityEvo:未找到ARSpace开始加载普通运行环境通过语音唤醒...");
mainPrefab = loadOperation.InstantiateSync();
}
#elif NotPointClond
mainPrefab = loadOperation.InstantiateSync();
#endif
if (domainConfig.domain == "Main")
AppConfig.SetDefaultMainInstance(mainPrefab);
}
}
public override async UniTask OnExitAsync()
{
Debug.Log("UnityEvo:Domain退出...");
if (domainConfig.domain != "Main")
{
DomainBase domainBase = mainPrefab.GetOrAddComponent<DomainBase>();
if (domainBase == null)
{
Debug.LogError($"UnityEvo:{mainPrefab.name}的DomainBase为空无法退出请排查");
}
else
{
domainBase.OnExit();
await domainBase.OnExitAsync();
}
if (domainBase != null)
{
GameObject.Destroy(domainBase.gameObject);
await ForceUnloadAllAssets(domainBase.DomainName);
}
if (loadResType == DomainConfig.LoadResType.Scene)
{
await SceneManager.UnloadSceneAsync(_sceneName);
}
AppConfig.PackageDomainName = "";
}
}
// 强制卸载所有资源包,该方法请在合适的时机调用。
// 注意Package在销毁的时候也会自动调用该方法。
private async UniTask ForceUnloadAllAssets(string packageName)
{
var package = YooAssets.TryGetPackage(packageName);
if (package != null)
{
var operation = package.UnloadAllAssetsAsync();
await operation;
await package.DestroyAsync();
YooAssets.RemovePackage(packageName);
Resources.UnloadUnusedAssets();
GC.Collect();
GC.WaitForPendingFinalizers();
Debug.Log($"UnityEvo:{packageName} 资源包已卸载...");
}
else
{
Debug.LogWarning($"UnityEvo:{packageName} 资源包不存在,请检查是否已经卸载还是卸载异常...");
}
}
}
}