using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Cysharp.Threading.Tasks; using DG.Tweening; using UnityEngine; using UnityEngine.UI; /// /// 公会基础界面 /// public class GuildBossWin : UIBase { [SerializeField] Text endTimeText; [SerializeField] Text fightPowerText; [SerializeField] Transform rankRect; [SerializeField] Text rankText; [SerializeField] Text noRankText; [SerializeField] AvatarCell headCell; [SerializeField] Text nameText; [SerializeField] Text todayHurtText; [SerializeField] Image newHighestHurtImg; //布阵 [SerializeField] Text bzAttrText; [SerializeField] UIEffectPlayer bzEffect1; [SerializeField] Text bzLayerText; //公会布阵层级 [SerializeField] UIEffectPlayer bzEffect2; [SerializeField] Button bzBtn; [SerializeField] Text bzTimesText; //个人布阵次数 [SerializeField] Button bzRecordBtn; //怒气条 [SerializeField] Image processLeft; //颜色从00FF0B 到 FFE400 到 E30400 [SerializeField] Image processRight; [SerializeField] Button atkBtn; [SerializeField] Image angerAtk; //怒气攻击 [SerializeField] Transform normalAtk; //普通攻击 [SerializeField] UIEffectPlayer atkEffect; //普通攻击特效 0次不显示 按钮用 [SerializeField] Text normalAtkCntText; //普通攻击次数 [SerializeField] Text atkCDText; //攻击cd [SerializeField] Transform addTimesRect; [SerializeField] Image addTimesItemImg; [SerializeField] ButtonEx closeBtn; [SerializeField] ButtonEx scoreBtn; [SerializeField] ButtonEx awardBtn; [SerializeField] Transform awardCntRect; [SerializeField] Text awardCntText; //攻击区 [SerializeField] UIHeroController bossModel; [SerializeField] Transform atkTargetPos; [SerializeField] HorseController heroModel; [SerializeField] Transform[] attackAreas; [SerializeField] RectTransform attackAreaParent; [SerializeField] GuildBossOtherPlayer otherPlayer; //创建多个用 List otherPlayers; [SerializeField] GuildBossOtherPlayerAttack[] otherPlayerAttacks; //自己的攻击 [SerializeField] UIEffectPlayer hurtEffect; [SerializeField] UIEffectPlayer hurtAngerEffect; [SerializeField] Text[] hurtValues; [SerializeField] Text[] awardValues; [SerializeField] Image[] awardIcons; [SerializeField] Transform pos1; [SerializeField] Transform pos2; [SerializeField] Transform[] dropBoxes; [SerializeField] Transform targetPos; [SerializeField] Transform fakeRedBZ; [SerializeField] Transform fakeRedAward; [Header("武将进场时间")] public float heroShowTime = 0.1f; [Header("武将攻击速度越大越快")] public float heroAtkSpeed = 2f; [Header("多段飘血以及物品出现间隔毫秒")] public int atkValueShowCD = 200; [Header("是否循环播放他人战斗")] public bool isOthersLoop = false; bool isCD = false; int beforeLayerNum; //布阵层级 对比变化展示特效 protected override void InitComponent() { closeBtn.AddListener(CloseWindow); bzBtn.AddListener(OnBzBtnClick); bzRecordBtn.AddListener(() => { UIManager.Instance.OpenWindow(); }); atkBtn.AddListener(OnAtkBtnClick); scoreBtn.AddListener(() => { UIManager.Instance.OpenWindow(); }); awardBtn.AddListener(() => { UIManager.Instance.OpenWindow(); }); bossModel.Create(GuildBossManager.Instance.bossSkinID, 1, motionName: "chuxian"); } protected override void OnPreOpen() { GlobalTimeEvent.Instance.secondEvent += OnSecondEvent; PlayerDatas.Instance.playerDataRefreshEvent += OnPlayerDataRefresh; GuildBossManager.Instance.BossHurtEvent += BossHurtEvent; GuildBossManager.Instance.AtkResultEvent += AtkResultEvent; Display(); InitAttack(); } protected override void OnPreClose() { GlobalTimeEvent.Instance.secondEvent -= OnSecondEvent; PlayerDatas.Instance.playerDataRefreshEvent -= OnPlayerDataRefresh; GuildBossManager.Instance.BossHurtEvent -= BossHurtEvent; GuildBossManager.Instance.AtkResultEvent -= AtkResultEvent; } protected override void NextFrameAfterOpen() { SoundPlayer.Instance.PlayUIAudio(28); } void Display() { endTimeText.text = Language.Get("Arena14", TimeUtility.SecondsToHMS((int)(TimeUtility.GetTodayEndTime() - TimeUtility.ServerNow).TotalSeconds)); fightPowerText.text = PlayerDatas.Instance.baseData.FightPower.ToString(); headCell.InitUI(AvatarHelper.GetAvatarModel((int)PlayerDatas.Instance.baseData.PlayerID, PlayerDatas.Instance.baseData.face, PlayerDatas.Instance.baseData.facePic)); nameText.text = PlayerDatas.Instance.baseData.PlayerName; BossHurtEvent(); } //战力变化 void OnPlayerDataRefresh(PlayerDataType type) { if (type == PlayerDataType.FightPower) fightPowerText.text = PlayerDatas.Instance.baseData.FightPower.ToString(); } //显示动态UI void ShowDynamicUI() { var bossAction = GuildBossManager.Instance.GetGuildBossAction(); ShowRank(); ShowBzInfo(bossAction); todayHurtText.text = Language.Get("GuildBoss17") + UIHelper.ReplaceLargeNum(GuildBossManager.Instance.m_BoxHurt); if (GuildBossManager.Instance.m_BoxHurt >= GuildBossManager.Instance.m_BoxHurtHis) { newHighestHurtImg.SetActive(true); } else { newHighestHurtImg.SetActive(false); } bzTimesText.text = Language.Get("Guild_65") + (GuildBossManager.Instance.m_BuZhenState == 1 ? "0/1" : UIHelper.AppendColor(TextColType.Green, "1/1", false)); ShowProcess(GuildBossManager.Instance.m_Anger * 1.0f / GuildBossManager.Instance.maxAngerValue); if (isCD) { angerAtk.SetActive(false); normalAtk.SetActive(false); } else { atkCDText.text = ""; if (GuildBossManager.Instance.m_Anger >= GuildBossManager.Instance.maxAngerValue) { angerAtk.SetActive(true); normalAtk.SetActive(false); } else { angerAtk.SetActive(false); normalAtk.SetActive(true); int cnt = GuildBossManager.Instance.GetHasAtkCnt(); if (cnt > 0) { atkEffect.Play(); } else { atkEffect.Stop(); } normalAtkCntText.text = Language.Get("TianziBillborad07", cnt); } } var hasCnt = GuildBossManager.Instance.GetHasAtkCnt(); if (hasCnt > 0 || GuildBossManager.Instance.m_Anger >= GuildBossManager.Instance.maxAngerValue) { addTimesRect.SetActive(false); } else { addTimesRect.SetActive(true); addTimesItemImg.SetItemSprite(GuildBossManager.Instance.addAtkCntItemID); } if (GuildBossManager.Instance.m_BoxUnGetCount > 0) { awardCntRect.SetActive(true); awardCntText.text = Language.Get("TianziBillborad07", GuildBossManager.Instance.m_BoxUnGetCount); } else { awardCntRect.SetActive(false); } fakeRedBZ.SetActive(GuildBossManager.Instance.m_BuZhenState != 1); fakeRedAward.SetActive(GuildBossManager.Instance.m_BoxUnGetCount > 0); } void BossHurtEvent() { var bossAction = GuildBossManager.Instance.GetGuildBossAction(); var layer = bossAction == null ? 0 : bossAction.Value3; if (beforeLayerNum != layer) { bzEffect1.Play(); bzEffect2.Play(); beforeLayerNum = (int)layer; } ShowDynamicUI(); ShowDropBox(); ShowOtherAttacker(); } void ShowRank() { int myRank = GuildBossManager.Instance.GetMyRank(); if (myRank > 0) { rankRect.SetActive(true); noRankText.SetActive(false); rankText.text = myRank.ToString(); } else { rankRect.SetActive(false); noRankText.SetActive(true); } } //布阵 void ShowBzInfo(HA513_tagMCFamilyActionInfo.tagMCFamilyAction bossAction) { bzAttrText.text = GetAddAttrs(bossAction); var layer = bossAction == null ? 0 : bossAction.Value3; var bzTime = bossAction == null ? 0 : bossAction.Value2; if (bzTime == 0) { bzLayerText.text = $"{layer}/{GuildBossManager.Instance.bzMaxLevel}"; } else { int remainTime = (int)Math.Max(0, bzTime - TimeUtility.AllSeconds); if (remainTime > 0) { bzLayerText.text = $"{layer}/{GuildBossManager.Instance.bzMaxLevel}" + Language.Get("GuildBoss28", TimeUtility.SecondsToHMS(remainTime)); } } } //获取布阵属性 string GetAddAttrs(HA513_tagMCFamilyActionInfo.tagMCFamilyAction action) { var layerNum = action == null ? 0 : action.Value3; var superHitRate = GuildBossManager.Instance.initSuperHitRate + (int)layerNum * GuildBossManager.Instance.bzAddAttrs[0]; var addHurtPer = (int)layerNum * GuildBossManager.Instance.bzAddAttrs[1]; if (addHurtPer == 0) { return Language.Get("GuildBoss18_0", superHitRate / 100); } return Language.Get("GuildBoss18_0", superHitRate / 100) + Language.Get("L1112") + Language.Get("GuildBoss18_1", addHurtPer / 100); } void OnSecondEvent() { endTimeText.text = Language.Get("Arena14", TimeUtility.SecondsToHMS((int)(TimeUtility.GetTodayEndTime() - TimeUtility.ServerNow).TotalSeconds)); var bossAction = GuildBossManager.Instance.GetGuildBossAction(); ShowBzInfo(bossAction); OtherPlayerAnimation(); } void ShowProcess(float value) { //颜色从00FF0B 到 FFE400 到 E30400 processLeft.fillAmount = value; processRight.fillAmount = value; Color processColor = GetProcessColor(value); processLeft.color = processColor; processRight.color = processColor; } Color GetProcessColor(float value) { // 限制值在0-1范围内 value = Mathf.Clamp01(value); if (value <= 0.5f) { float t = value / 0.5f; return Color.Lerp(new Color(0f, 1f, 0.043f), new Color(1f, 0.894f, 0f), t); } else { float t = (value - 0.5f) / 0.5f; return Color.Lerp(new Color(1f, 0.894f, 0f), new Color(0.89f, 0.016f, 0f), t); } } void OnBzBtnClick() { // int curLayer = 0; // var bossAction = GuildBossManager.Instance.GetGuildBossAction(); // if (bossAction != null) // { // curLayer = (int)bossAction.Value3; // } // if (curLayer >= GuildBossManager.Instance.bzMaxLevel) // { // SysNotifyMgr.Instance.ShowTip("GuildBoss2"); // return; // } if (GuildBossManager.Instance.m_BuZhenState == 1) { SysNotifyMgr.Instance.ShowTip("GuildBoss1"); return; } GuildBossManager.Instance.TaofaBoss(1); } void OnAtkBtnClick() { if (isCD) return; //怒气伤害不消耗次数 //次数不足 提示使用道具,若用完提示本日次数已用完 if (GuildBossManager.Instance.m_Anger < GuildBossManager.Instance.maxAngerValue) { if (GuildBossManager.Instance.GetHasAtkCnt() <= 0) { var itemCfg = ItemConfig.Get(GuildBossManager.Instance.addAtkCntItemID); var singleCnt = itemCfg.EffectValueA1; var todayUseMaxCnt = itemCfg.MaxSkillCnt; if (GuildBossManager.Instance.m_ItemAddCount / singleCnt >= todayUseMaxCnt) { SysNotifyMgr.Instance.ShowTip("HeroWishFinish"); return; } ConfirmCancel.ShowUseItemPopConfirm(Language.Get("GuildBoss24"), Language.Get("GuildBoss23", itemCfg.IconKey, singleCnt, todayUseMaxCnt - GuildBossManager.Instance.m_ItemAddCount / singleCnt), GuildBossManager.Instance.addAtkCntItemID, 1, (bool isOK) => { if (isOK) { if (ItemLogicUtility.CheckItemCount(PackType.Item, GuildBossManager.Instance.addAtkCntItemID, 1, 2)) { ItemLogicUtility.Instance.UseItem(PackManager.Instance.GetItemGUIDByID(GuildBossManager.Instance.addAtkCntItemID)); } } }); return; } } GuildBossManager.Instance.TaofaBoss(0); // ShowAttackCD().Forget(); } async UniTask ShowAttackCD() { angerAtk.SetActive(false); normalAtk.SetActive(false); isCD = true; atkBtn.SetColorful(null, false); atkCDText.text = "3"; await UniTask.Delay(1000); atkCDText.text = "2"; await UniTask.Delay(1000); atkCDText.text = "1"; await UniTask.Delay(1000); atkBtn.SetColorful(null, true); isCD = false; ShowDynamicUI(); } void AtkResultEvent() { //1. 玩家从pos1 移动到pos2 //2. 播放攻击动作 - 显示对应类型特效 //3. 延迟100毫秒飘血物品 heroModel.GetHero().onComplete = null; heroModel.PlayAnimation("run", true); heroModel.transform.localPosition = pos1.localPosition; heroModel.transform.DOLocalMove(pos2.localPosition, heroShowTime).OnComplete(() => { ShowDmg().Forget(); }); } async UniTask ShowDmg() { heroModel.GetHero().onComplete = () => { heroModel.transform.localPosition = pos1.localPosition; }; heroModel.HeroPlay("attack"); if (GuildBossManager.Instance.atkResult.AtkType == 0) { hurtEffect.Play(); } else { hurtAngerEffect.Play(); } bossModel.PlayAnimation("hit"); bossModel.onComplete = () => { bossModel.PlayAnimation("idle", true); bossModel.onComplete = null; }; for (int i = 0; i < hurtValues.Length; i++) { if (i < GuildBossManager.Instance.atkResult.HurtCount) { int index = i; hurtValues[i].transform.localScale = Vector3.one; var tween = hurtValues[i].GetComponent(); if (tween.isActiveAndEnabled) { tween.SetStartState(); tween.Play(() => { hurtValues[index].transform.localScale = Vector3.zero; }); } var hurtData = GuildBossManager.Instance.atkResult.HurtList[i]; BattleDmg dmg = new BattleDmg() { damage = hurtData.HurtValue + hurtData.HurtValueEx * Constants.ExpPointValue, attackType = hurtData.IsSuper == 1 ? (int)DamageType.CritDamage : 2 }; hurtValues[i].text = BattleUtility.DisplayDamageNum(dmg); await UniTask.Delay(atkValueShowCD); } else { hurtValues[i].transform.localScale = Vector3.zero; } } for (int i = 0; i < awardValues.Length; i++) { if (i < GuildBossManager.Instance.atkResult.ItemCount) { var itemData = GuildBossManager.Instance.atkResult.ItemList[i]; awardValues[i].transform.localScale = Vector3.one; int index = i; var tween = awardValues[i].GetComponent(); if (tween.isActiveAndEnabled) { tween.SetStartState(); tween.Play(() => { awardValues[index].transform.localScale = Vector3.zero; }); } awardValues[i].text = itemData.Count.ToString(); awardIcons[i].SetItemSprite((int)itemData.ItemID); await UniTask.Delay(atkValueShowCD); } else { awardValues[i].transform.localScale = Vector3.zero; } } } void InitAttack() { var skinConfig = HorseSkinConfig.Get(HorseManager.Instance.GetUsingHorseSkinID(false)); heroModel.Create(skinConfig.SkinID, PhantasmPavilionManager.Instance.GetMyModelSkinID(), 1.2f); heroModel.GetHero().SetSpeed(heroAtkSpeed); for (int i = 0; i < hurtValues.Length; i++) { hurtValues[i].transform.localScale = Vector3.zero; } for (int i = 0; i < awardValues.Length; i++) { awardValues[i].transform.localScale = Vector3.zero; } heroModel.transform.localPosition = pos1.localPosition; bossModel.onComplete = () => { bossModel.PlayAnimation("idle", true); bossModel.onComplete = null; }; bossModel.PlayAnimation("chuxian"); lastValueIndex = FindHurtIndex(); for (int i = 0; i < dropBoxes.Length; i++) { dropBoxes[i].transform.localScale = Vector3.zero; } for (int i = otherPlayers.Count - 1; i >= 0; i--) { otherPlayers[i].moveState = 0; } for (int i = 0; i < otherPlayerAttacks.Length; i++) { otherPlayerAttacks[i].Hide(); //置底 otherPlayerAttacks[i].transform.SetAsLastSibling(); } } int lastValueIndex = -1; // -1 未达标 void ShowDropBox() { int index = FindHurtIndex(); if (index > lastValueIndex) { var showBoxCnt = index - lastValueIndex; lastValueIndex = index; for (int i = 0; i < dropBoxes.Length; i++) { if (i < showBoxCnt) { dropBoxes[i].transform.localScale = Vector3.one*0.5f; var startPos = new Vector3(UnityEngine.Random.Range(-80, 80), 30, 0); //随机方向返回1或者-1 int randDir = UnityEngine.Random.Range(0, 2) == 0 ? 1 : -1; dropBoxes[i].localPosition = startPos; int _index = i; dropBoxes[i].DOLocalPath(new Vector3[] { startPos, new Vector3(startPos.x + randDir * 10, startPos.y + 30f, 0), new Vector3(startPos.x + randDir * 25, startPos.y - 60, 0) }, 0.5f, PathType.CatmullRom).SetEase(Ease.InOutSine).OnComplete(()=> { dropBoxes[_index].DOLocalMove(targetPos.localPosition, 0.3f).OnComplete(()=> { dropBoxes[_index].transform.localScale = Vector3.zero; awardBtn.GetComponent().Play(); }); }); } else { dropBoxes[i].transform.localScale = Vector3.zero; } } } } int FindHurtIndex() { for (int i = 0; i < GuildBossManager.Instance.allBXCumulativeDamageList.Count; i++) { if (GuildBossManager.Instance.m_BoxHurt < GuildBossManager.Instance.allBXCumulativeDamageList[i]) { return i - 1; } } return GuildBossManager.Instance.allBXCumulativeDamageList.Count; } void ShowOtherAttacker() { CreateOtherAttacker(); var cnt = GuildBossManager.Instance.playerBossHurtRank.Count; //伤害高的在上面,逆序显示 for (int i = otherPlayers.Count - 1; i >= 0; i--) { if (i < cnt) { otherPlayers[i].SetActive(true); otherPlayers[i].Display(GuildBossManager.Instance.playerBossHurtRank[cnt - i - 1]); } else { otherPlayers[i].SetActive(false); } } } void CreateOtherAttacker() { if (otherPlayers.IsNullOrEmpty()) { otherPlayers = new List(); } int addCnt = GuildBossManager.Instance.playerBossHurtRank.Count - otherPlayers.Count; for (int i = 0; i < addCnt; i++) { var inst = Instantiate(otherPlayer, attackAreaParent); //坐标从attackAreas 随机一个组件,然后在组件的范围内随机,父类为attackAreaParent int pos = UnityEngine.Random.Range(0, attackAreas.Length); var rect = attackAreas[pos] as RectTransform; inst.transform.localPosition = attackAreas[pos].transform.localPosition + new Vector3(UnityEngine.Random.Range(-rect.rect.width / 2, rect.rect.width / 2), UnityEngine.Random.Range(-rect.rect.height / 2, rect.rect.height / 2), 0); inst.NotePos(); otherPlayers.Add(inst); } } void OtherPlayerAnimation() { if (GuildBossManager.Instance.taofaAtkData.Keys.Count == 0) { return; } var keys = GuildBossManager.Instance.taofaAtkData.Keys.ToList(); keys.Sort(); int index = keys.IndexOf(GuildBossManager.Instance.lastPlayTick) + 1; if (index >= keys.Count) { index = isOthersLoop ? 0 : -1; //是否循环播放 } int atkPlayerID = 0; TaofaAtkData atkData = null; if (index >= 0) { GuildBossManager.Instance.lastPlayTick = keys[index]; atkData = GuildBossManager.Instance.taofaAtkData[keys[index]]; atkPlayerID = atkData.playerID; } for (int i = 0; i < otherPlayers.Count; i++) { if (!otherPlayers[i].isActiveAndEnabled) { continue; } if (otherPlayers[i].moveState != 0) { continue; } // 突进 if (otherPlayers[i].playerID == atkPlayerID) { if (otherPlayers[i].moveState != 1) { otherPlayers[i].moveState = 1; //向目标 atkTargetPos 突进80后回原位置 Vector3 currentPos = otherPlayers[i].transform.localPosition; Vector3 targetPos = atkTargetPos.localPosition; // 计算从当前点到目标点的方向向量 Vector3 direction = (targetPos - currentPos).normalized; // 向目标方向移动80的距离 Vector3 attackPos = currentPos + direction * 50f; // 记录原位置,用于后续返回 Vector3 originalPos = currentPos; // 先移动到攻击位置,然后返回原位置 // 先停止原位置的移动 int _index = i; int valueIndex = i % otherPlayerAttacks.Length; otherPlayerAttacks[valueIndex].transform.localPosition = currentPos + direction * 160f; otherPlayerAttacks[valueIndex].Display(atkData); otherPlayers[i].transform.DOKill(); otherPlayers[i].transform.DOLocalMove(attackPos, 0.2f).SetEase(Ease.OutQuad) .OnComplete(() => { otherPlayers[_index].transform.DOLocalMove(originalPos, 0.2f).SetEase(Ease.InQuad); otherPlayers[_index].moveState = 0; }); } continue; } otherPlayers[i].transform.DOKill(); //缓慢移动 var randomPos = otherPlayers[i].startPos + new Vector3(UnityEngine.Random.Range(-50, 50), UnityEngine.Random.Range(-50, 50), 0); otherPlayers[i].transform.DOLocalMove(randomPos, 2f).SetEase(Ease.InOutSine); } } }