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();
}
}
}
}