using System; using ET; using System.Collections.Generic; using cfg.GfgCfg; using UnityEngine; using YooAsset; namespace GFGGame { //换装部件操作器,负责部件换装的资源加载、预渲染等 public class DressUpLayerOperation : DressUpOperationBase { internal enum EAction { Layer, Body, Head } public const int PRE_RENDER_FRAME = 1; internal ItemCfg itemCfg; internal GameObject parentObj; private int layerId; private bool needSetMask; private bool showAni; public string resPath; public string effectResPath; private int preRendering; private ResourceDownloaderOperation downloaderOperation; internal EAction actionType; private string[] locationsLoading; public DressUpLayerOperation(GameObject parentObj, bool needSetMask, bool showAni, string resPath, string effectResPath) { this.parentObj = parentObj; this.needSetMask = needSetMask; this.resPath = resPath; this.effectResPath = effectResPath; this.showAni = showAni; preRendering = 0; } public void InitLayer(ItemCfg itemCfg, int layerId) { //LogUtil.LogEditor($"add InitLayer {itemCfg.id} layerId {layerId}"); this.itemCfg = itemCfg; this.layerId = layerId; actionType = EAction.Layer; } public void InitBody() { //LogUtil.LogEditor("update InitBody"); actionType = EAction.Body; } public void InitHead() { //LogUtil.LogEditor("update InitHead"); actionType = EAction.Head; } internal override bool CheckRepeated(DressUpOperationBase t) { DressUpLayerOperation layerOperation = t as DressUpLayerOperation; if (layerOperation != null && layerOperation.actionType == this.actionType) { if (actionType == EAction.Layer) { return (layerOperation.parentObj == this.parentObj && layerOperation.itemCfg == this.itemCfg && layerOperation.layerId == this.layerId); } else { return true; } } if (this.actionType == EAction.Layer) { DressUpRemoveOperation removeOperation = t as DressUpRemoveOperation; if (removeOperation != null && this.itemCfg != null) { if (removeOperation.itemID == this.itemCfg.Id) { if (removeOperation.parentObj == this.parentObj) { return true; } } } } return false; } /// /// 取消下载 /// internal override void Cancel() { if (_steps != EDressUpSteps.Done) { if (downloaderOperation != null) { downloaderOperation.CancelDownload(); } if (_steps == EDressUpSteps.PreDrawing) { //取消预渲染 PrefabManager.Instance.CancelPreDraw(resPath); } _steps = EDressUpSteps.Done; } Status = EOperationStatus.Failed; Error = "User cancel."; } internal override void UpdateView(Action action = null) { if (parentObj == null) { this.Release(); return; } ViewManager.Hide(); switch (actionType) { case EAction.Layer: UpdateLayer(action); break; case EAction.Body: UpdateBody(action); break; case EAction.Head: UpdateHead(action); break; default: break; } } internal override void Release() { downloaderOperation = null; this.itemCfg = null; this.parentObj = null; locationsLoading = null; } internal override void Start() { _steps = EDressUpSteps.Check; Update(); } internal override void Update() { if (_steps == EDressUpSteps.None || _steps == EDressUpSteps.Done) return; if (_steps == EDressUpSteps.Check) { CheckLoadRes(); } if (_steps == EDressUpSteps.Loading) { if (downloaderOperation != null) { Progress = downloaderOperation.Progress; if (downloaderOperation.IsDone) { if (downloaderOperation.Status == EOperationStatus.Succeed) { foreach (var t in locationsLoading) { LoadManager.Instance.SetResDownloaded(t); } CheckPreDraw(); } else { _steps = EDressUpSteps.Done; Status = EOperationStatus.Failed; } } } } if (_steps == EDressUpSteps.PreDrawing) { //LogUtil.LogEditor($"preRendering {preRendering} {resPath} {TimeHelper.ClientNow()}"); if (preRendering <= 0) { _steps = EDressUpSteps.Done; Status = EOperationStatus.Succeed; } preRendering--; } } private void CheckLoadRes() { List locations = new List(); if (!string.IsNullOrEmpty(resPath) && !LoadManager.Instance.CheckResExsited(resPath)) { //需加载 locations.Add(this.resPath); } if (!string.IsNullOrEmpty(effectResPath) && !LoadManager.Instance.CheckResExsited(effectResPath)) { //需加载 locations.Add(effectResPath); } if (locations.Count == 0) { //文件已在本地,不需要下载 CheckPreDraw(); return; } locationsLoading = locations.ToArray(); downloaderOperation = YooAssets.CreateBundleDownloader(locationsLoading, 3, 3); if (downloaderOperation.TotalDownloadCount == 0) { //文件已在本地,不需要下载 CheckPreDraw(); return; } ViewManager.Show("资源加载中,请耐心等待..."); //下载 _steps = EDressUpSteps.Loading; downloaderOperation.BeginDownload(); } private void CheckPreDraw() { if (!string.IsNullOrEmpty(resPath)) { if (showAni) { _steps = EDressUpSteps.PreDrawing; //设置预渲染帧数 preRendering = PRE_RENDER_FRAME; //预渲染 PrefabManager.Instance.PreDraw(resPath); //LogUtil.LogEditor($"PreDraw {resPath} {TimeHelper.ClientNow()}"); return; } } _steps = EDressUpSteps.Done; Status = EOperationStatus.Succeed; } private void UpdateLayer(Action onComplete = null) { //LogUtil.LogEditor($"add UpdateLayer {itemCfg.id} layerId {layerId}"); int sortingOrder = ItemTypeCfgArray.Instance.GetSortingOrder(itemCfg.SubType, layerId); // 清理旧的资源 var spritObjName = DressUpUtil.GetSpriteName(itemCfg, layerId); DressUpUtil.TryRemoveSprite(parentObj, spritObjName); var aniObjName = string.Format(DressUpUtil.FORMAT_ANIMATION_NAME, itemCfg.Id, layerId); DressUpUtil.TryRemoveObj(parentObj, aniObjName); string effectObjName = string.Format(DressUpUtil.FORMAT_EFFECT_OBJ_NAME, itemCfg.Id, layerId); DressUpUtil.TryRemoveObj(parentObj, effectObjName); // 异步操作计数器 int asyncOperationCount = 0; bool mainResAdded = false; bool effectResAdded = false; // 检查并处理主资源 if (!string.IsNullOrEmpty(this.resPath)) { asyncOperationCount++; if (this.showAni) { // 异步加载动画 DressUpUtil.AddAnimationObjAsync( resPath, aniObjName, parentObj, sortingOrder, (gameObj) => { mainResAdded = gameObj != null; asyncOperationCount--; CheckComplete(); }); } else { // 精灵资源异步加载 string ext = ItemUtil.GetItemResExt(itemCfg.ItemType, itemCfg.SubType); DressUpUtil.AddSpriteObjAsync( resPath, spritObjName, parentObj, sortingOrder, needSetMask, (gameObj) => { mainResAdded = gameObj != null; asyncOperationCount--; CheckComplete(); }); } } // 检查并处理特效资源(改为异步方式) if (!string.IsNullOrEmpty(effectResPath)) { asyncOperationCount++; DressUpUtil.TryAddEffectObjAsync( effectResPath, effectObjName, parentObj, sortingOrder, (gameObj) => { effectResAdded = gameObj != null; asyncOperationCount--; CheckComplete(); }); } // 检查所有异步操作是否完成 void CheckComplete() { if (asyncOperationCount <= 0) { onComplete?.Invoke(); } } // 如果没有异步操作,直接调用完成回调 if (asyncOperationCount == 0) { onComplete?.Invoke(); } } private void UpdateBody(Action onComplete = null) { var spritObjName = DressUpUtil.BODY_SPRITE_NAME; var aniObjName = DressUpUtil.BODY_ANIMATION_NAME; var effectObjName = DressUpUtil.BODY_EFFECT_OBJ_NAME; int sortingOrder = 0; // 清理旧的资源(保持同步) var removeBodyAni = DressUpUtil.TryRemoveObj(parentObj, aniObjName); DressUpUtil.TryRemoveObj(parentObj, effectObjName); DressUpUtil.TryRemoveSprite(parentObj, spritObjName); // 异步操作计数器 int asyncOperationCount = 0; bool mainResAdded = false; bool effectResAdded = false; // 处理主资源 if (!string.IsNullOrEmpty(this.resPath)) { if (this.showAni) { // 异步加载动画 asyncOperationCount++; DressUpUtil.AddAnimationObjAsync( resPath, aniObjName, parentObj, 5, (gameObj) => { if (gameObj != null) { mainResAdded = true; } asyncOperationCount--; CheckComplete(); }); } else { // 精灵资源改为异步加载 asyncOperationCount++; DressUpUtil.AddSpriteObjAsync( this.resPath, spritObjName, parentObj, sortingOrder, needSetMask, (gameObj) => { if (gameObj != null) { mainResAdded = true; } // 如果从动画切换到精灵且移除了动画,重置位置和旋转 if (!this.showAni && removeBodyAni) { parentObj.transform.localPosition = Vector3.zero; parentObj.transform.localRotation = Quaternion.identity; } asyncOperationCount--; CheckComplete(); }); } } // 处理特效资源(改为异步方式) if (!string.IsNullOrEmpty(effectResPath)) { asyncOperationCount++; DressUpUtil.TryAddEffectObjAsync( effectResPath, effectObjName, parentObj, sortingOrder, (gameObj) => { if (gameObj != null) { effectResAdded = true; } asyncOperationCount--; CheckComplete(); }); } // 检查所有异步操作是否完成 void CheckComplete() { if (asyncOperationCount <= 0) { // 额外检查:如果是从动画切换到精灵且移除了动画 if (!this.showAni && removeBodyAni && asyncOperationCount == 0) { parentObj.transform.localPosition = Vector3.zero; parentObj.transform.localRotation = Quaternion.identity; } onComplete?.Invoke(); } } // 如果没有异步操作,直接调用完成回调 if (asyncOperationCount == 0) { onComplete?.Invoke(); } } private void UpdateHead(Action onComplete = null) { LogUtil.LogEditor("update UpdateHead"); var spritObjName = DressUpUtil.HEAD_SPRITE_NAME; int sortingOrder = 1; Transform transform_t = parentObj.transform.Find(spritObjName); if (!string.IsNullOrEmpty(this.resPath)) { if (transform_t != null) { // 如果对象已存在,直接激活并返回 transform_t.gameObject.SetActive(true); onComplete?.Invoke(); return; } // 异步添加精灵对象 DressUpUtil.AddSpriteObjAsync( resPath, spritObjName, parentObj, sortingOrder, needSetMask, (gameObj) => { // 回调中可以添加额外处理逻辑(如有需要) onComplete?.Invoke(); }); } else { // 资源路径为空时,隐藏现有对象 if (transform_t == null) { onComplete?.Invoke(); return; } transform_t.gameObject.SetActive(false); onComplete?.Invoke(); } } } }