using System.Collections.Generic; using UnityEngine; public class TargetFinder { HashSet filterTags = new HashSet(); public TargetFinder(params string[] filterTags) { for(int i = 0; i < filterTags.Length; i++) { this.filterTags.Add(filterTags[i]); } } public IList GetRandom(Bounds bounds, int maxCount) { var areaSize = BattleMgr.SGetBgSize(); var result = new List(); for(int i = 0; i < maxCount; i++) { float rndX = Random.Range(bounds.min.x, bounds.max.x); float rndY = Random.Range(bounds.min.y, bounds.max.y); rndX = Mathf.Clamp(rndX, areaSize.bounds.min.x, areaSize.bounds.max.x); rndY = Mathf.Clamp(rndY, areaSize.bounds.min.y, areaSize.bounds.max.y); result.Add(new Vector2(rndX, rndY)); } return result; } public IList GetNearests(Vector2 pivot, int maxCount, ICollection except = null) { var heap = new SimpleHeap((a, b) => { float distA = (pivot - (Vector2)a.transform.position).sqrMagnitude; float distB = (pivot - (Vector2)b.transform.position).sqrMagnitude; return distA < distB; }); if(except is null) { BattleMgr.LoopAllCreatures((creature) => { if (filterTags.Contains(creature.tag)) { heap.Push(creature); } return true; }); } else { BattleMgr.LoopAllCreatures((creature) => { if (filterTags.Contains(creature.tag) && !except.Contains(creature)) { heap.Push(creature); } return true; }); } var result = new List(); while (heap.Count > 0 && result.Count < maxCount) { result.Add(heap.Pop()); } return result; } public bool TryFindNearest(Vector2 pivot, out CreatureBase result, ICollection except = null, bool ignoreExcepIfNoTarget = false) { CreatureBase minDistCreature = null; float minSqrtDist = float.MaxValue; if(except is null) { BattleMgr.LoopAllCreatures((creature) => { if (filterTags.Contains(creature.tag)) { float sqrtDist = (pivot - (Vector2)creature.transform.position).sqrMagnitude; if (sqrtDist < minSqrtDist) { minSqrtDist = sqrtDist; minDistCreature = creature; } } return true; }); } else if(!ignoreExcepIfNoTarget) { BattleMgr.LoopAllCreatures((creature) => { if (filterTags.Contains(creature.tag) && !except.Contains(creature)) { float sqrtDist = (pivot - (Vector2)creature.transform.position).sqrMagnitude; if (sqrtDist < minSqrtDist) { minSqrtDist = sqrtDist; minDistCreature = creature; } } return true; }); } else { var targetCandidates = new List(); BattleMgr.LoopAllCreatures((creature) => { if (filterTags.Contains(creature.tag) && !except.Contains(creature)) { float sqrtDist = (pivot - (Vector2)creature.transform.position).sqrMagnitude; if (sqrtDist < minSqrtDist) { minSqrtDist = sqrtDist; minDistCreature = creature; } } targetCandidates.Add(creature); return true; }); if(minDistCreature is null && targetCandidates.Count > 0) { minDistCreature = targetCandidates[Random.Range(0, targetCandidates.Count)]; } } result = minDistCreature; return minDistCreature != null; } }