using System.Collections.Generic; using UnityEngine; using System; using System.Linq; using ET; using FairyGUI; namespace GFGGame { public enum DressUpOption { Auto, Add, Remove } public class DressUpObj { public int bgId { get { return _dressUpData.bgId; } } public int suitId { get { return _dressUpData.suitId; } } public int actionId { get { return _dressUpData.actionId; } } public bool IsAction { get { return _dressUpData.actionId > 0; } } public List itemList { get { return _dressUpData.itemList.ToList(); } } /// /// /// /// /// /// /// /// /// 是否重置装备数据 public void setSceneObj(GameObject sceneObj, bool needSetMask = false, bool showSceneType = true, GameObject roleObj = null, bool showBg = true) { if (_sceneObj != null && _sceneObj != sceneObj) { GameObject.Destroy(_sceneObj); } _sceneObj = sceneObj; _needSetMask = needSetMask; _showSceneType = showSceneType; _showBg = showBg; _roleObj = roleObj; if (_dressUpData.IsNew) { PutOnDefaultDressUpData(); } else { var tempData = DressUpDataClone(); TakeOffAll(); PutOnDressUpData(tempData); } Timers.inst.AddUpdate(OnUpdate); } public DressUpData DressUpDataClone() { return _dressUpData.Clone(); } public void Dispose() { _sceneObj = null; _dressUpData = null; } //传入一个服装部件Id,判断是否有与此部件同类型服装已穿着 public bool CheckSameTypeIsOn(int itemId) { int subType = ItemUtilCS.GetItemSubType(itemId); for (int i = 0; i < _dressUpData.itemList.Count; i++) { int _subType = ItemUtilCS.GetItemSubType(_dressUpData.itemList[i]); if (subType == _subType) return true; } return false; } /// /// 仅判断换装部件是否已穿着 /// /// /// public bool CheckDressUpItemIsOn(int itemId) { if (itemId == _dressUpData.bgId) { return true; } return _dressUpData.itemList.Contains(itemId); } /// /// 仅判断套装是否穿上 /// /// /// public bool CheckSuitIsOn(int id) { SuitCfg suitCfg = SuitCfgArray.Instance.GetCfg(id); if (suitCfg == null) { return false; } int[] items = suitCfg.partsArr; foreach (int itemId in items) { if (_dressUpData.actionId == id) { if (SuitCfgArray.Instance.CheckActionContainsItem(itemId, id)) { continue; } } bool isOn = CheckDressUpItemIsOn(itemId); if (!isOn) { return false; } } return true; } public void AddOrRemove(int itemId, bool checkDefault, DressUpOption dressUpOption = DressUpOption.Auto) { int subType = ItemUtilCS.GetItemSubType(itemId); if (subType == ConstDressUpItemType.BEI_JING) { if (!_showBg) { return; } _dressUpData.bgId = itemId; List handlers = DressUpUtil.AddItemAsync(_dressUpData.bgId, _sceneObj, _needSetMask, true, _roleObj); TryAddHandlers(handlers); } else { if (!CheckDressUpItemIsOn(itemId)) { if (dressUpOption != DressUpOption.Remove) { if (checkDefault) { TryCancelActionWhenPutOn(itemId); } CheckRemoveSameType(subType); Add(itemId); } } else { if (dressUpOption != DressUpOption.Add) { Remove(itemId); } } if (checkDefault) { checkDefaultItem(); } } } //脱掉所有换装,换成默认装(不处理背景) public void TakeOffAll(bool checkDefault = true) { _dressUpData.suitId = 0; _dressUpData.actionId = 0; foreach (int itemID in itemList) { AddOrRemove(itemID, false, DressUpOption.Remove); } if (checkDefault) { checkDefaultItem(); } RoleLevelCfg roleLevelCfg = RoleLevelCfgArray.Instance.GetCfg(GameGlobal.myNumericComponent.GetAsInt(NumericType.Lvl)); // FightDataManager.Instance.score = roleLevelCfg.baseScore; // foreach (int itemId in _dressUpData.itemList) // { // FightDataManager.Instance.score += ItemDataManager.GetItemAdditionScore(itemId, InstanceZonesDataManager.currentScoreType, InstanceZonesDataManager.currentFightTags); // } } //穿上或脱掉一个动作 public void PutOnOrTakeOffAction(int actionId) { if (_dressUpData.actionId == actionId) { CancelAction(); } else { PutOnAction(actionId); } } /// /// 尝试穿戴配置套装 /// /// 套装id /// 尝试穿上动作 /// 排除类型列表 /// 是否显示可选部件 /// 是否只显示主角拥有的部件 public void PutOnSuitCfg(int suitId, bool tryShowAction, int[] excludeType = null, bool showOptional = true, bool CheckOwn = true) { SuitCfg suitCfg = SuitCfgArray.Instance.GetCfg(suitId); if(suitCfg == null) { return; } bool oldIsAction = IsAction; _dressUpData.suitId = suitId; bool hasSuitActionRes = DressUpMenuSuitDataManager.CheckSuitHasActionRes(_dressUpData.suitId); _dressUpData.actionId = (hasSuitActionRes && tryShowAction) ? suitId : 0; List items = new List(suitCfg.partsArr); if (showOptional) { if (suitCfg.partsOptionalArr != null && suitCfg.partsOptionalArr.Length > 0) { items.AddRange(suitCfg.partsOptionalArr); } } int subType = 0; //找到要穿的散件 List targetItemList = new List(); foreach (int itemId in items) { if (!CheckOwn || DressUpMenuItemDataManager.CheckHasItem(itemId)) { subType = ItemUtilCS.GetItemSubType(itemId); bool notInAction = SuitCfgArray.Instance.CheckItemNotInAction(itemId); if (!IsAction || notInAction) { if (excludeType == null || Array.IndexOf(excludeType, subType) < 0) { targetItemList.Add(itemId); } } } } CompareAndAddItemList(oldIsAction, IsAction, targetItemList); checkDefaultItem(); } //取消动作 public void CancelAction(bool changeToStand = false) { if (_dressUpData.actionId <= 0) { return; } var tempActionId = _dressUpData.actionId; _dressUpData.actionId = 0; //更新非场景类型部件形态 foreach (int itemId in itemList) { if (!DressUpMenuItemCfg1Array.Instance.CheckIsSceneType(itemId)) { //场景类型不受动作影响并且本来就有动画,对非场景类型处理 bool notInAction = SuitCfgArray.Instance.CheckItemNotInAction(itemId); if (notInAction) { //更新成图片模式 Update(itemId); } } } if (changeToStand) { SuitCfg suitCfg = SuitCfgArray.Instance.GetCfg(tempActionId); List items = new List(suitCfg.partsArr); if (suitCfg.partsOptionalArr != null && suitCfg.partsOptionalArr.Length > 0) { items.AddRange(suitCfg.partsOptionalArr); } foreach (int itemId in items) { if (DressUpMenuItemDataManager.CheckHasItem(itemId)) { bool notInAction = SuitCfgArray.Instance.CheckItemNotInAction(itemId); if (!notInAction) { AddOrRemove(itemId, false, DressUpOption.Add); } } } } checkDefaultItem(); } //穿戴一组换装数据 public void PutOnDressUpData(DressUpData targetDressUpData, int[] excludeType = null) { bool oldIsAction = IsAction; _dressUpData.suitId = targetDressUpData.suitId; _dressUpData.actionId = targetDressUpData.actionId; var targetItemList = new List(); foreach(var itemId in targetDressUpData.itemList) { int subType = ItemUtilCS.GetItemSubType(itemId); if (excludeType == null || Array.IndexOf(excludeType, subType) < 0) { targetItemList.Add(itemId); } } if (targetDressUpData.bgId > 0 && (excludeType == null || Array.IndexOf(excludeType, ConstDressUpItemType.BEI_JING) < 0)) { targetItemList.Add(targetDressUpData.bgId); } CompareAndAddItemList(oldIsAction, IsAction, targetItemList); checkDefaultItem(); } //穿戴默认换装数据 public void PutOnDefaultDressUpData(bool bgType = false) { var dressUpData = DressUpData.CreateDefault(); if (bgType) { dressUpData.bgId = 180002; } PutOnDressUpData(dressUpData); } //穿戴一组散件数据(会脱掉不包含的部分) public void PutOnItemList(List targetItemList) { bool oldIsAction = IsAction; _dressUpData.suitId = 0; _dressUpData.actionId = 0; CompareAndAddItemList(oldIsAction, IsAction, targetItemList); checkDefaultItem(); } #region private private GameObject _sceneObj; private GameObject _roleObj; private bool _needSetMask; private bool _showSceneType = true; private bool _showBg = true; private DressUpData _dressUpData = new DressUpData(); private List handlers = new List(); //穿上一个动作 private void PutOnAction(int actionId) { bool hasSuitActionRes = DressUpMenuSuitDataManager.CheckSuitHasActionRes(actionId); _dressUpData.actionId = actionId; if (hasSuitActionRes) { foreach (int itemId in itemList) { if (!DressUpMenuItemCfg1Array.Instance.CheckIsSceneType(itemId)) { //场景类型不受动作影响并且本来就有动画,对非场景类型处理 bool notInAction = SuitCfgArray.Instance.CheckItemNotInAction(itemId); if (notInAction) { //更新成动画模式 Update(itemId); } else { AddOrRemove(itemId, false, DressUpOption.Remove); } } } } else { CancelAction(true); } checkDefaultItem(); } //当穿一件部件时检查是否需要取消动作,如果需要则取消该动作 private void TryCancelActionWhenPutOn(int itemId) { if (_dressUpData.actionId > 0) { bool replaceableByAction = SuitCfgArray.Instance.CheckItemReaplaceableOnAction(itemId, _dressUpData.actionId); if (!replaceableByAction) { CancelAction(); _dressUpData.actionId = 0; } } } private void Add(int itemId) { if (!_showSceneType) { if (DressUpMenuItemCfg1Array.Instance.CheckIsSceneType(itemId)) { return; } } if (!_dressUpData.itemList.Contains(itemId)) { _dressUpData.itemList.Add(itemId); Update(itemId); } } private void Update(int itemId) { bool showAni = IsAction || DressUpMenuItemCfg1Array.Instance.CheckIsSceneType(itemId); var handlers = DressUpUtil.AddItemAsync(itemId, _sceneObj, _needSetMask, showAni, _roleObj); TryAddHandlers(handlers); } private void Remove(int itemId) { if (_dressUpData.itemList == null) { return; } if (_dressUpData.itemList.Contains(itemId)) { _dressUpData.itemList.Remove(itemId); var handler = DressUpUtil.RemoveItemAsync(itemId, _sceneObj, _roleObj); TryAddHandler(handler); } } private void CheckRemoveSameType(int type) { int count = 0; int firstTeshuId = 0; for (int i = 0; i < _dressUpData.itemList.Count; i++) { int itemID = (int)_dressUpData.itemList[i]; int subType = ItemUtilCS.GetItemSubType(itemID); if (subType == type || (type == ConstDressUpItemType.LIAN_YI_QUN && (subType == ConstDressUpItemType.SHANG_YI || subType == ConstDressUpItemType.XIA_ZHUANG || subType == ConstDressUpItemType.NEI_DA)) || (type == ConstDressUpItemType.SHANG_YI && subType == ConstDressUpItemType.LIAN_YI_QUN) || (type == ConstDressUpItemType.XIA_ZHUANG && subType == ConstDressUpItemType.LIAN_YI_QUN) || (type == ConstDressUpItemType.NEI_DA && subType == ConstDressUpItemType.LIAN_YI_QUN)) { Remove(itemID); i--; } if (subType > ConstDressUpItemType.TE_SHU) { if (count == 0) { firstTeshuId = itemID; } count++; } } if (type > ConstDressUpItemType.TE_SHU && count >= 3) { //特殊饰品最多穿三件,第四件会自动顶掉第一件 Remove(firstTeshuId); } } //与身上的散件对比差异然后添加 private void CompareAndAddItemList(bool oldIsAction, bool newIsAction, List targetItemList) { bool actionStatusChanged = (oldIsAction && !newIsAction) || (!oldIsAction && newIsAction); foreach (int itemID in itemList) { if (!targetItemList.Contains(itemID)) { //移除不穿的部件 AddOrRemove(itemID, false, DressUpOption.Remove); } else if (actionStatusChanged) { //当动画形态切换时 if (!DressUpMenuItemCfg1Array.Instance.CheckIsSceneType(itemID)) { //非场景类型重穿 Update(itemID); targetItemList.Remove(itemID); } } } foreach (int itemID in targetItemList) { AddOrRemove(itemID, false, DressUpOption.Add); } } //检测当前穿戴是否是一件完整套装,且只穿了一件套装,返回套装id private int CheckCurDressIsSuit() { var suitId = 0; var suitIdList = new List(); for (int i = 0; i < _dressUpData.itemList.Count; i++) { int itemSuitId = SuitCfgArray.Instance.GetSuitIdOfItem(_dressUpData.itemList[i]); if (!suitIdList.Contains(itemSuitId)) { suitIdList.Add(itemSuitId); } } foreach (var itemSuitId in suitIdList) { if (CheckSuitIsOn(itemSuitId)) { suitId = itemSuitId; break; } } _dressUpData.suitId = suitId; return _dressUpData.suitId; } private void checkDefaultItem() { //是否有头发 bool hasFaXing = false; //检查默认资源 //是否有连衣裙 bool hasLianYiQun = false; //是否有内搭 bool hasNeiDa = false; //是否有上衣 bool hasShangYi = false; //是否有下装 bool hasXiaZhuang = false; //是否有默认内搭 bool hasNeiDaDefault = false; //是否有默认下装 bool hasXiaZhuangDefault = false; //是否有妆容 bool hasZhuangRong = false; for (int i = 0; i < _dressUpData.itemList.Count; i++) { int itemID = (int)_dressUpData.itemList[i]; int subType = ItemUtilCS.GetItemSubType(itemID); if (subType == (int)ConstDressUpItemType.FA_XING) { hasFaXing = true; } else if (subType == ConstDressUpItemType.LIAN_YI_QUN) { hasLianYiQun = true; } else if (subType == ConstDressUpItemType.NEI_DA) { hasNeiDa = true; } else if (subType == ConstDressUpItemType.XIA_ZHUANG) { hasXiaZhuang = true; } else if (subType == ConstDressUpItemType.SHANG_YI) { hasShangYi = true; } else if (subType == ConstDressUpItemType.ZHUANG_RONG) { hasZhuangRong = true; } if (itemID == ConstItemID.DEFULT_NEI_DA) { hasNeiDaDefault = true; } else if (itemID == ConstItemID.DEFULT_XIA_ZHUANG) { hasXiaZhuangDefault = true; } } if (!hasFaXing) { Add(ConstItemID.DEFULT_FA_XING); } if (!IsAction) { if (!hasLianYiQun) { if (!hasShangYi && (!hasNeiDa || hasNeiDaDefault) && (!hasXiaZhuang || hasXiaZhuangDefault)) { Remove(ConstItemID.DEFULT_XIA_ZHUANG); Remove(ConstItemID.DEFULT_NEI_DA); Add(ConstItemID.DEFULT_LIAN_YI_QUN); } else { if (!hasXiaZhuang) { Add(ConstItemID.DEFULT_XIA_ZHUANG); } if (!hasNeiDa) { Add(ConstItemID.DEFULT_NEI_DA); } } } } CheckCurDressIsSuit(); var handler = DressUpUtil.UpdateHeadAsync(!hasZhuangRong, _sceneObj, _needSetMask, _roleObj); TryAddHandler(handler); UpdateBodyView(); } //更新整个身体 private void UpdateBodyView() { string actionRes = null; if (IsAction) { SuitCfg suitCfg = SuitCfgArray.Instance.GetCfg(_dressUpData.actionId); var hasAniRes = ResPathUtil.CheckDressUpAnimationResExist(suitCfg.aniRes); actionRes = hasAniRes ? suitCfg.aniRes : null; } var handler = DressUpUtil.UpdateBodyAsync(actionRes, _sceneObj, _needSetMask, _roleObj); TryAddHandler(handler); } private void OnUpdate(object param = null) { if(handlers != null && handlers.Count > 0) { bool draw = true; foreach(var handler in handlers) { if(!handler.IsDone) { draw = false; } } if(draw) { var t = handlers.ToArray(); handlers.Clear(); foreach (var handler in t) { handler.UpdateView(); handler.Release(); } //Debug.Log($"draw {TimeHelper.ClientNow()}"); } } } private void TryAddHandlers(List handlers) { if (handlers != null) { this.handlers.AddRange(handlers); //OnUpdate(); } } private void TryAddHandler(DressUpOperationBase handler) { if (handler != null) { this.handlers.Add(handler); //OnUpdate(); } } #endregion } }