using ET; using System.Collections.Generic; 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; private string resPath; private 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() { if (parentObj == null) { this.Release(); return; } ViewManager.Hide(); 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; 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) { 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() { //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); //添加新的 if(!string.IsNullOrEmpty(this.resPath)) { 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() { //LogUtil.LogEditor("update 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.TryRemoveSprite(parentObj, spritObjName); if(!string.IsNullOrEmpty(this.resPath)) { if (this.showAni) { DressUpUtil.AddAnimationObj(this.resPath, aniObjName, parentObj, sortingOrder); } else { DressUpUtil.AddSpriteObj(this.resPath, spritObjName, parentObj, sortingOrder, needSetMask); } } if(!this.showAni && removeBodyAni) { parentObj.transform.localPosition = Vector3.zero; parentObj.transform.localRotation = Quaternion.identity; } if (!string.IsNullOrEmpty(effectResPath)) { DressUpUtil.TryAddEffectObj(effectResPath, effectObjName, parentObj, sortingOrder); } } private void UpdateHead() { 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); return; } DressUpUtil.AddSpriteObj(resPath, spritObjName, parentObj, sortingOrder, needSetMask); } else { if (transform_t == null) { return; } transform_t.gameObject.SetActive(false); } } } }