using ET; using System.Collections.Generic; using UnityEngine; using YooAsset; namespace GFGGame { public class DressUpLayerOperation : DressUpOperationBase { private enum EAction { Layer, Body, Head } public const int PRE_RENDER_FRAME = 1; private ItemCfg itemCfg; private GameObject parentObj; private int layerId; private bool needSetMask; private bool showAni; private string resPath; private string effectResPath; private int preRendering; private ResourceDownloaderOperation downloaderOperation; private EAction actionType; private List preloadList = new List(); 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) { this.itemCfg = itemCfg; this.layerId = layerId; actionType = EAction.Layer; } public void InitBody() { actionType = EAction.Body; } public void InitHead() { actionType = EAction.Head; } /// /// 取消下载 /// public void Cancel() { if (_steps != EDressUpSteps.Done) { if (downloaderOperation != null) { downloaderOperation.CancelDownload(); } _steps = EDressUpSteps.Done; Status = EOperationStatus.Failed; Error = "User cancel."; } } internal override void UpdateView() { ViewManager.Hide(); foreach (var t in preloadList) { Live2dAnimationManager.Instance.FinishPreDrawed(t); } preloadList.Clear(); preloadList = null; switch (actionType) { case EAction.Layer: UpdateLayer(); break; case EAction.Body: UpdateBody(); break; case EAction.Head: UpdateHead(); break; default: break; } } internal override void Release() { downloaderOperation = null; this.itemCfg = null; this.parentObj = null; preloadList?.Clear(); preloadList = 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) { Progress = downloaderOperation.Progress; if(downloaderOperation.IsDone) { if (downloaderOperation.Status == EOperationStatus.Succeed) { CheckPreDraw(); } else { _steps = EDressUpSteps.Done; Status = EOperationStatus.Failed; } } } if(_steps == EDressUpSteps.PreDrawing) { Debug.Log($"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)) { //需加载 locations.Add(this.resPath); } if(!string.IsNullOrEmpty(effectResPath)) { //需加载 locations.Add(effectResPath); } if(locations.Count == 0) { _steps = EDressUpSteps.Done; Status = EOperationStatus.Succeed; return; } downloaderOperation = YooAssets.CreateBundleDownloader(locations.ToArray(), 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; //预渲染 var t = Live2dAnimationManager.Instance.PreDraw(resPath); preloadList.Add(t); Debug.Log($"PreDraw {resPath} {TimeHelper.ClientNow()}"); return; } } _steps = EDressUpSteps.Done; Status = EOperationStatus.Succeed; } private void UpdateLayer() { //清理旧的 var spritObjName = string.Format(DressUpUtil.FORMAT_SPRITE_NAME, itemCfg.subType, layerId); DressUpUtil.TryRemoveObj(parentObj, spritObjName); var aniObjName = string.Format(DressUpUtil.FORMAT_ANIMATION_NAME, itemCfg.subType, layerId); DressUpUtil.TryRemoveObj(parentObj, aniObjName); string effectObjName = string.Format(DressUpUtil.FORMAT_EFFECT_OBJ_NAME, itemCfg.subType, layerId); DressUpUtil.TryRemoveObj(parentObj, effectObjName); //添加新的 int sortingOrder = ItemTypeCfgArray.Instance.GetSortingOrder(itemCfg.subType, layerId); if (this.showAni) { DressUpUtil.AddAnimationObj(resPath, aniObjName, parentObj, sortingOrder); } else { string ext = ItemUtil.GetItemResExt(itemCfg.itemType, itemCfg.subType); DressUpUtil.AddSpriteObj(resPath, spritObjName, parentObj, sortingOrder, needSetMask); } if (!string.IsNullOrEmpty(effectResPath)) { DressUpUtil.TryAddEffectObj(effectResPath, effectObjName, parentObj, sortingOrder); } } private void UpdateBody() { 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.TryRemoveObj(parentObj, spritObjName); if (this.showAni) { DressUpUtil.AddAnimationObj(this.resPath, aniObjName, parentObj, sortingOrder); } else { DressUpUtil.AddSpriteObj(this.resPath, spritObjName, parentObj, sortingOrder, needSetMask); if (removeBodyAni) { parentObj.transform.SetPositionAndRotation(new Vector3(), new Quaternion()); } } if (!string.IsNullOrEmpty(effectResPath)) { DressUpUtil.TryAddEffectObj(effectResPath, effectObjName, parentObj, sortingOrder); } } private void 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); return; } DressUpUtil.AddSpriteObj(resPath, spritObjName, parentObj, sortingOrder, needSetMask); } else { if (transform_t == null) { return; } transform_t.gameObject.SetActive(false); } } } }