using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using DG.Tweening; using DG.Tweening.Core; public static class BattleUtility { // 其他通用的战斗工具方法可以放在这里 public static void MarkStartAndEnd(RectTransform startNode, RectTransform endNode) { // 运行时才执行 if (!Application.isPlaying) { Debug.LogWarning("请在运行时使用该功能!"); return; } var battleField = BattleManager.Instance.storyBattleField; if (battleField == null) { BattleDebug.LogError("BattleManager.storyBattleField 未初始化!"); return; } BattleWin battleWin = UIManager.Instance.GetUI(); RectTransform canvasRect = battleWin.transform as RectTransform; CreateMarker(canvasRect, startNode, "StartMarker"); CreateMarker(canvasRect, endNode, "EndMarker"); } private static void CreateMarker(RectTransform canvasRect, RectTransform targetNode, string markerName) { // 获取目标节点的世界坐标(中心点) Vector3 worldPos = targetNode.TransformPoint(targetNode.rect.center); // 转换到Canvas本地坐标 Vector2 localPoint; RectTransformUtility.ScreenPointToLocalPointInRectangle( canvasRect, RectTransformUtility.WorldToScreenPoint(null, worldPos), null, out localPoint); // 创建RawImage GameObject marker = new GameObject(markerName, typeof(RawImage)); GameObject.Destroy(marker, 5f); marker.transform.SetParent(canvasRect, false); var rawImage = marker.GetComponent(); rawImage.color = Color.white; rawImage.rectTransform.sizeDelta = new Vector2(100, 100); rawImage.rectTransform.anchoredPosition = localPoint; } public static TweenerCore MoveToTarget( RectTransform transform, RectTransform target, Vector2 offset, float duration, Action onComplete = null) { // 获取目标节点的世界坐标(中心点) Vector3 worldPos = target.TransformPoint(target.rect.center + offset); RectTransform canvasRect = transform.parent as RectTransform; // 转换到Canvas本地坐标 Vector2 localPoint; RectTransformUtility.ScreenPointToLocalPointInRectangle( canvasRect, RectTransformUtility.WorldToScreenPoint(null, worldPos), null, out localPoint); // 创建RawImage var tween = transform.DOAnchorPos(localPoint, duration).SetEase(Ease.Linear); tween.onComplete += () => { onComplete?.Invoke(); }; // MarkStartAndEnd(transform as RectTransform, target); // // 1. 获取目标的世界坐标(加 offset) // Vector3 targetWorldPos = target.TransformPoint(target.anchoredPosition + offset); // // 2. 获取源节点的 parent // RectTransform sourceParent = transform.parent as RectTransform; // if (sourceParent == null) // { // BattleDebug.LogError("源节点没有父节点,无法转换坐标!"); // return null; // } // // 3. 把目标世界坐标转换到源 parent 的本地坐标 // Vector2 targetAnchoredPos; // RectTransformUtility.ScreenPointToLocalPointInRectangle( // sourceParent, // RectTransformUtility.WorldToScreenPoint(CameraManager.uiCamera, targetWorldPos), // CameraManager.uiCamera, // out targetAnchoredPos); // // 4. DOTween 移动 // var tween = transform.DOAnchorPos(targetAnchoredPos, duration).SetEase(Ease.Linear); // tween.onComplete += () => // { // onComplete?.Invoke(); // }; return tween; } public static string DisplayDamageNum(long num, int attackType) { var basePowerStr = UIHelper.ReplaceLargeArtNum(num); var result = string.Empty; for (int i = 0; i < basePowerStr.Length; i++) { var numChar = (char)GetDamageNumKey((DamageType)attackType, basePowerStr[i]); if (numChar > 0) { result += numChar; } } return result; } public static int GetDamageNumKey(DamageType damageType, int _num) { var config = DamageNumConfig.Get(damageType.ToString()); //.的ASCII码是46 if (_num == 46) { return config.nums[10]; } //k的ASCII码是107 else if (_num == 107) { return config.nums[11]; } //m的ASCII码是109 else if (_num == 109) { return config.nums[12]; } //b的ASCII码是98 else if (_num == 98) { return config.nums[13]; } //t的ASCII码是116 else if (_num == 116) { return config.nums[14]; } return config.nums[_num - 48]; } /// /// 保证所有分配项加起来等于totalDamage,避免因整除导致的误差 /// public static List DivideDamageToList(int[] damageDivide, long totalDamage) { List fixedDamageList = new List(); long assigned = 0; int count = damageDivide.Length; for (int i = 0; i < count; i++) { long damage; if (i == count - 1) { // 最后一个分配项修正为剩余 damage = totalDamage - assigned; } else { damage = (totalDamage * damageDivide[i] + 5000) / 10000; // 四舍五入 assigned += damage; } fixedDamageList.Add(damage); } return fixedDamageList; } public static List FindDeadPack(List packList) { List deadPacks = new List(); for (int i = 0; i < packList.Count; i++) { var pack = packList[i]; // 寻找死亡包 找到死亡包之后要找掉落包 不能超过技能包 if (pack is HB422_tagMCTurnFightObjDead) { var deadPack = pack as HB422_tagMCTurnFightObjDead; deadPacks.Add(deadPack); } else if (pack is CustomHB426CombinePack) { // 找死亡包不要越过技能包 var combinePack = pack as CustomHB426CombinePack; if (combinePack.startTag.Tag.StartsWith("Skill_")) { break; } } } return deadPacks; } public static List FindRebornPack(List packList) { List rebornPack = new List(); for (int i = 0; i < packList.Count; i++) { var pack = packList[i]; // 寻找死亡包 找到死亡包之后要找掉落包 不能超过技能包 if (pack is HB423_tagMCTurnFightObjReborn) { var deadPack = pack as HB423_tagMCTurnFightObjReborn; rebornPack.Add(deadPack); } else if (pack is CustomHB426CombinePack) { // 找死亡包不要越过技能包 var combinePack = pack as CustomHB426CombinePack; if (combinePack.startTag.Tag.StartsWith("Skill_")) { break; } } } return rebornPack; } }