AI性能优化减少GC
parent
801377fd05
commit
0e2a73fc8c
|
|
@ -18,7 +18,7 @@ public class BT_CallHelp : Action
|
|||
|
||||
public override TaskStatus OnUpdate()
|
||||
{
|
||||
var friends = AIUtils.FindFriendInRange(owner, Range);
|
||||
var friends = AIUtils.FindFriendsWithDistance(owner, Range);
|
||||
if (friends == null || friends.Count <= 0) return TaskStatus.Failure;
|
||||
foreach (var friend in friends.Keys)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public class BT_HasFriendInCondition : Conditional
|
|||
|
||||
public override TaskStatus OnUpdate()
|
||||
{
|
||||
var friends = AIUtils.FindFriendInRange(owner, Range);
|
||||
var friends = AIUtils.FindFriendsWithDistance(owner, Range);
|
||||
if (friends.Count <= 0) return TaskStatus.Failure;
|
||||
GameUnit target;
|
||||
if (CheckHp && CheckMore) target = GetHPMoreThan(friends);
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ public class BTDefendWithinSight : Conditional
|
|||
// 如果目标都为空 寻找敌人
|
||||
if (_owner.controlData.targetEnemy == null && _owner.controlData.followUnit == null)
|
||||
{
|
||||
var enemy = AIUtils.FindNearestEnemyInSightDistance(_owner);
|
||||
var enemy = AIUtils.FindNearestTarget(_owner);
|
||||
if (enemy != null)
|
||||
{
|
||||
_owner.statusData.isInFight = true;
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ namespace Code.Scripts.Gameplay.BT.Conditional
|
|||
// 如果目标都为空 寻找敌人
|
||||
if (_owner.controlData.targetEnemy == null && _owner.controlData.followUnit == null)
|
||||
{
|
||||
var enemy = AIUtils.FindNearestEnemyInSightDistance(_owner);
|
||||
var enemy = AIUtils.FindNearestTarget(_owner);
|
||||
if (enemy == null) return TaskStatus.Failure;
|
||||
|
||||
var cellIndex = enemy.transData.cellIndex;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using cfg.CharacterCfg;
|
||||
using Gameplay.AI;
|
||||
using Gameplay.Pool;
|
||||
using Gameplay.Unit;
|
||||
|
||||
public interface IAITargetFilter
|
||||
|
|
@ -7,14 +8,24 @@ public interface IAITargetFilter
|
|||
bool IsValid(GameUnit unit);
|
||||
}
|
||||
|
||||
public class EnemyFilter : IAITargetFilter
|
||||
public class EnemyFilter : IAITargetFilter, IPoolData
|
||||
{
|
||||
private readonly GameUnit _owner;
|
||||
private readonly int _range;
|
||||
private readonly Ejob _job;
|
||||
private readonly uint _excludeTargetID;
|
||||
private GameUnit _owner;
|
||||
private int _range;
|
||||
private Ejob _job;
|
||||
private uint _excludeTargetID;
|
||||
|
||||
// 默认构造函数,用于对象池
|
||||
public EnemyFilter()
|
||||
{
|
||||
}
|
||||
|
||||
public EnemyFilter(GameUnit owner, int range, Ejob job = Ejob.Job_Other, uint excludeTargetID = 0)
|
||||
{
|
||||
Init(owner, range, job, excludeTargetID);
|
||||
}
|
||||
|
||||
public void Init(GameUnit owner, int range, Ejob job = Ejob.Job_Other, uint excludeTargetID = 0)
|
||||
{
|
||||
_owner = owner;
|
||||
_range = range;
|
||||
|
|
@ -34,27 +45,48 @@ public class EnemyFilter : IAITargetFilter
|
|||
return distance <= checkRange &&
|
||||
unit.statusData.CheckCanBeTarget(_owner, (int)_owner.fightData.findEnemyRange);
|
||||
}
|
||||
|
||||
public void OnGet()
|
||||
{
|
||||
// 从对象池获取时的初始化
|
||||
}
|
||||
|
||||
public void OnReturn()
|
||||
{
|
||||
// 清空引用,防止内存泄漏
|
||||
_owner = null;
|
||||
_range = 0;
|
||||
_job = Ejob.Job_Other;
|
||||
_excludeTargetID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class FriendFilter : IAITargetFilter
|
||||
public class FriendFilter : IAITargetFilter, IPoolData
|
||||
{
|
||||
private readonly GameUnit _owner;
|
||||
private readonly int _range;
|
||||
private readonly Ejob _job;
|
||||
private readonly uint _excludeTargetID;
|
||||
private GameUnit _owner;
|
||||
private int _range;
|
||||
private Ejob _job;
|
||||
|
||||
public FriendFilter(GameUnit owner, int range, Ejob job = Ejob.Job_Other, uint excludeTargetID = 0)
|
||||
// 默认构造函数,用于对象池
|
||||
public FriendFilter()
|
||||
{
|
||||
}
|
||||
|
||||
public FriendFilter(GameUnit owner, int range, Ejob job = Ejob.Job_Other)
|
||||
{
|
||||
Init(owner, range, job);
|
||||
}
|
||||
|
||||
public void Init(GameUnit owner, int range, Ejob job = Ejob.Job_Other)
|
||||
{
|
||||
_owner = owner;
|
||||
_range = range;
|
||||
_job = job;
|
||||
_excludeTargetID = excludeTargetID;
|
||||
}
|
||||
|
||||
public bool IsValid(GameUnit unit)
|
||||
{
|
||||
if (unit == null || unit.statusData.isDead) return false;
|
||||
if (_excludeTargetID != 0 && unit.GetID() == _excludeTargetID) return false;
|
||||
if (_job != Ejob.Job_Other && unit.commonData.eJob != _job) return false;
|
||||
|
||||
var distance = AIUtils.GetDistance(_owner.transData.cellIndex, unit.transData.cellIndex);
|
||||
|
|
@ -62,4 +94,17 @@ public class FriendFilter : IAITargetFilter
|
|||
|
||||
return distance <= checkRange;
|
||||
}
|
||||
|
||||
public void OnGet()
|
||||
{
|
||||
// 从对象池获取时的初始化
|
||||
}
|
||||
|
||||
public void OnReturn()
|
||||
{
|
||||
// 清空引用,防止内存泄漏
|
||||
_owner = null;
|
||||
_range = 0;
|
||||
_job = Ejob.Job_Other;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using Gameplay.AI;
|
||||
using Gameplay.Unit;
|
||||
|
||||
public static class AITargetFinder
|
||||
{
|
||||
public static Dictionary<GameUnit, int> FindUnits(GameUnit owner, List<GameUnit> candidates, IAITargetFilter filter)
|
||||
{
|
||||
var results = new Dictionary<GameUnit, int>(candidates.Count);
|
||||
|
||||
var ownerCell = owner.transData?.cellIndex;
|
||||
if (!ownerCell.HasValue) return results;
|
||||
|
||||
foreach (var unit in candidates)
|
||||
{
|
||||
var cell = unit.transData?.cellIndex;
|
||||
if (!cell.HasValue) continue;
|
||||
|
||||
if (filter.IsValid(unit))
|
||||
{
|
||||
int distance = AIUtils.GetDistance(ownerCell.Value, cell.Value);
|
||||
results[unit] = distance;
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 35b1e0038beb443de9733fc639ae0c07
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
|
@ -1,312 +1,416 @@
|
|||
using System;
|
||||
using Framework;
|
||||
using System.Linq;
|
||||
using Gameplay.Unit;
|
||||
using Gameplay.Area;
|
||||
using Gameplay.Level;
|
||||
using cfg.CharacterCfg;
|
||||
using Gameplay.Character;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Gameplay.AI
|
||||
{
|
||||
public static partial class AIUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// 通过GUID获取单位
|
||||
/// </summary>
|
||||
public static GameUnit FindUnit(uint id)
|
||||
{
|
||||
if (GameUnitManager.instance.deadUnits.Contains(id))
|
||||
return null;
|
||||
return GameUnitManager.instance.infightUnits.Contains(id)
|
||||
? GameUnitManager.instance.infightUnits.Search(id)
|
||||
: null;
|
||||
}
|
||||
|
||||
#region 寻找敌人
|
||||
|
||||
/// <summary>
|
||||
/// 寻找视野内的最近敌人 range为-1则为索敌范围
|
||||
/// </summary>
|
||||
public static GameUnit FindNearestTarget(GameUnit owner, int range = -1, Ejob job = Ejob.Job_Other)
|
||||
{
|
||||
try
|
||||
{
|
||||
var inSightDistanceDic = FindEnemiesInRange(owner, range, job);
|
||||
return GetNearestUnit(inSightDistanceDic);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.FindNearestTarget error: {0}", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 寻找范围内符合条件的所有敌人
|
||||
/// </summary>
|
||||
public static Dictionary<GameUnit, int> FindEnemiesInRange(GameUnit owner, int range = -1,
|
||||
Ejob job = Ejob.Job_Other, uint targetID = 0)
|
||||
{
|
||||
if (owner == null || range == 0) return null;
|
||||
|
||||
var enemies = GameUnitManager.instance.SearchEnemies(owner);
|
||||
|
||||
var filter = new EnemyFilter(owner, range, job, targetID);
|
||||
return AITargetFinder.FindUnits(owner, enemies, filter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最近的单位
|
||||
/// </summary>
|
||||
public static GameUnit GetNearestUnit(Dictionary<GameUnit, int> units)
|
||||
{
|
||||
var minDistance = float.MaxValue;
|
||||
GameUnit nearestUnit = null;
|
||||
foreach (var pair in units)
|
||||
{
|
||||
if (minDistance > pair.Value)
|
||||
{
|
||||
minDistance = pair.Value;
|
||||
nearestUnit = pair.Key;
|
||||
}
|
||||
}
|
||||
|
||||
return nearestUnit;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取更近的攻击来源单位
|
||||
/// </summary>
|
||||
public static GameUnit GetNearestAttackGameUnit(GameUnit owner, GameUnit newUnit, GameUnit unit)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (owner == null || newUnit == null || unit == null) return null;
|
||||
|
||||
var map = LevelManager.Instance.CurrentLevel.Map;
|
||||
if (map == null) return null;
|
||||
|
||||
var ownerCellIndex = owner.transData?.cellIndex;
|
||||
var unitCellIndex = unit.transData?.cellIndex;
|
||||
var newUnitCellIndex = newUnit.transData?.cellIndex;
|
||||
if (!ownerCellIndex.HasValue || !unitCellIndex.HasValue || !newUnitCellIndex.HasValue) return null;
|
||||
|
||||
var distance = MapUtils.Distance(map, ownerCellIndex.Value, unitCellIndex.Value);
|
||||
var newDistance = MapUtils.Distance(map, ownerCellIndex.Value, newUnitCellIndex.Value);
|
||||
return distance <= newDistance ? unit : newUnit;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.GetNearestGameUnit error: {0}", e);
|
||||
// 异常返回默认单位
|
||||
return unit;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 寻找友军
|
||||
|
||||
/// <summary>
|
||||
/// 通过MonsterID寻找友军 只返回第一个Monster
|
||||
/// </summary>
|
||||
public static GameUnit FindFriendByMonsterID(int id)
|
||||
{
|
||||
foreach (var unit in GameUnitManager.instance.totalUnits.unitList)
|
||||
{
|
||||
if (unit.unitLevelData != null && !unit.statusData.isDead && unit.unitLevelData.monsterId == id)
|
||||
{
|
||||
return unit;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 寻找视野内的最近敌人 range为-1则为索敌范围
|
||||
/// </summary>
|
||||
public static GameUnit FindNearestFriend(GameUnit owner, int range = -1, Ejob job = Ejob.Job_Other)
|
||||
{
|
||||
try
|
||||
{
|
||||
var inSightDistanceDic = FindFriendInRange(owner, range, job);
|
||||
return GetNearestUnit(inSightDistanceDic);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.FindNearestFriend error: {0}", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 寻找范围内符合条件的友军
|
||||
/// </summary>
|
||||
public static Dictionary<GameUnit, int> FindFriendInRange(GameUnit owner, int range = -1,
|
||||
Ejob job = Ejob.Job_Other)
|
||||
{
|
||||
if (owner == null || range == 0) return null;
|
||||
|
||||
var friends = GameUnitManager.instance.SearchFriends(owner);
|
||||
|
||||
var filter = new FriendFilter(owner, range, job);
|
||||
return AITargetFinder.FindUnits(owner, friends, filter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测某个地格是否有友军单位
|
||||
/// </summary>
|
||||
public static GameUnit FindFriendByCellIndex(int cellIndex)
|
||||
{
|
||||
var units = AreaManager.instance.GetUnitsByCellIndex(cellIndex);
|
||||
foreach (var unit in units)
|
||||
{
|
||||
if (unit.commonData.troopId == ETroopsId.Enemy)
|
||||
{
|
||||
return unit;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 寻找随机目标
|
||||
|
||||
public static int FindRandomCell(GameUnit owner, int maxStep = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = LevelManager.Instance.CurrentLevel?.Map;
|
||||
if (map == null || owner == null) return -1;
|
||||
var cellIndex = owner.transData.cellIndex;
|
||||
if (!AreaManager.instance.CheckContainsMoveUnit(cellIndex))
|
||||
return -1;
|
||||
var randomCells = new List<int>();
|
||||
for (var i = 1; i <= maxStep; i++)
|
||||
{
|
||||
var minSteps = i - 1;
|
||||
var maxSteps = i;
|
||||
var cells = map.TerrainGridSystem.CellGetNeighboursWithinRange(cellIndex, minSteps, maxSteps,
|
||||
canCrossCheckType: TGS.CanCrossCheckType.IgnoreCanCrossCheckOnAllCells);
|
||||
foreach (var cell in cells)
|
||||
{
|
||||
if (!CheckCellCanSelect(cell)) continue;
|
||||
if (!PathFinder.CanBasePass(cell, owner)) continue;
|
||||
if (AreaManager.instance.CheckContainsMoveUnit(cell)) continue;
|
||||
if (maxSteps > 1)
|
||||
{
|
||||
if (CheckPathExits(owner, cell))
|
||||
{
|
||||
randomCells.Add(cell);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
randomCells.Add(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (randomCells.Count == 0)
|
||||
return -1;
|
||||
|
||||
var randomIndex = UnityEngine.Random.Range(0, randomCells.Count);
|
||||
return randomCells[randomIndex];
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.FindRandomCell error: {0}", e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 寻找随机单位
|
||||
/// </summary>
|
||||
public static GameUnit FindRandomTarget(GameUnit owner, uint enemy, int range = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
var targetID = enemy;
|
||||
var inSightDistanceDic = FindEnemiesInRange(owner, range, targetID: targetID);
|
||||
|
||||
return GetRandomUnit(inSightDistanceDic);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.FindRandomTarget error: {0}", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取随机单位
|
||||
/// </summary>
|
||||
private static GameUnit GetRandomUnit(Dictionary<GameUnit, int> units)
|
||||
{
|
||||
if (units == null || units.Count == 0)
|
||||
return null;
|
||||
|
||||
var unitList = units.Keys.ToList();
|
||||
var randomUnit = unitList[UnityEngine.Random.Range(0, unitList.Count)];
|
||||
return randomUnit;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 组内单位 寻找 判断
|
||||
|
||||
public static bool GroupTargetInRange(GameUnit owner, List<int> group)
|
||||
{
|
||||
var inRange = false;
|
||||
var groupFriends = FindGroupUnits(owner, group);
|
||||
foreach (var groupFriend in groupFriends)
|
||||
{
|
||||
var targetID = groupFriend.unitLevelData.AIBattleInfo.Value.targetID;
|
||||
if (targetID == Constants.INVALID_UINT_ID) continue;
|
||||
var target = GameUnitManager.instance.infightUnits.Search(targetID);
|
||||
var distance = GetDistance(owner.transData.cellIndex, target.transData.cellIndex);
|
||||
if (distance <= groupFriend.fightData.trackRange)
|
||||
{
|
||||
inRange = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return inRange;
|
||||
}
|
||||
|
||||
public static List<GameUnit> FindGroupUnits(GameUnit owner, List<int> group)
|
||||
{
|
||||
var groupUnits = new List<GameUnit>();
|
||||
if (owner == null || group == null || group.Count == 0)
|
||||
return groupUnits;
|
||||
|
||||
var friends = GameUnitManager.instance.SearchFriends(owner);
|
||||
foreach (var friend in friends)
|
||||
{
|
||||
if (friend.unitLevelData == null || friend.unitLevelData.AIBattleInfo == null) continue;
|
||||
var unitGroups = friend.unitLevelData.AIBattleInfo.Value.groupInfo;
|
||||
if (unitGroups == null || unitGroups.Count <= 0) continue;
|
||||
// 检查当前单位的组ID列表与传入的组ID列表是否有交集
|
||||
foreach (var groupId in unitGroups)
|
||||
{
|
||||
if (group.Contains(groupId))
|
||||
{
|
||||
groupUnits.Add(friend);
|
||||
break; // 找到一个匹配就可以添加该单位,无需继续检查其他组ID
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return groupUnits;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
using System;
|
||||
using Framework;
|
||||
using System.Linq;
|
||||
using Gameplay.Unit;
|
||||
using Gameplay.Area;
|
||||
using Gameplay.Level;
|
||||
using cfg.CharacterCfg;
|
||||
using Gameplay.Character;
|
||||
using Gameplay.Pool;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Gameplay.AI
|
||||
{
|
||||
public static partial class AIUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// 对象池 - 用于缓存单位距离字典
|
||||
/// </summary>
|
||||
private static readonly Dictionary<GameUnit, int> UnitsDistanceCache = new (64);
|
||||
|
||||
/// <summary>
|
||||
/// 临时列表,用于避免在 GetNearestUnit/GetRandomUnit 中创建新列表
|
||||
/// </summary>
|
||||
private static readonly List<KeyValuePair<GameUnit, int>> TempPairList = new (64);
|
||||
|
||||
/// <summary>
|
||||
/// 通过GUID获取单位
|
||||
/// </summary>
|
||||
public static GameUnit FindUnit(uint id)
|
||||
{
|
||||
if (GameUnitManager.instance.deadUnits.Contains(id))
|
||||
return null;
|
||||
return GameUnitManager.instance.infightUnits.Contains(id)
|
||||
? GameUnitManager.instance.infightUnits.Search(id)
|
||||
: null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取符合条件的单位及距离
|
||||
/// </summary>
|
||||
/// <param name="owner">自身</param>
|
||||
/// <param name="candidates">需要筛选的对象</param>
|
||||
/// <param name="filter">条件</param>
|
||||
/// <returns></returns>
|
||||
private static Dictionary<GameUnit, int> FindUnits(GameUnit owner, List<GameUnit> candidates,
|
||||
IAITargetFilter filter)
|
||||
{
|
||||
// 清空临时字典以便重用
|
||||
UnitsDistanceCache.Clear();
|
||||
|
||||
var ownerCell = owner.transData?.cellIndex;
|
||||
if (!ownerCell.HasValue) return UnitsDistanceCache;
|
||||
|
||||
foreach (var unit in candidates)
|
||||
{
|
||||
var cell = unit.transData?.cellIndex;
|
||||
if (!cell.HasValue) continue;
|
||||
|
||||
if (filter.IsValid(unit))
|
||||
{
|
||||
int distance = GetDistance(ownerCell.Value, cell.Value);
|
||||
UnitsDistanceCache[unit] = distance;
|
||||
}
|
||||
}
|
||||
|
||||
return UnitsDistanceCache;
|
||||
}
|
||||
|
||||
#region 寻找敌人
|
||||
|
||||
/// <summary>
|
||||
/// 寻找视野内的最近敌人
|
||||
/// </summary>
|
||||
/// <param name="owner">自身</param>
|
||||
/// <param name="range">指定范围 -1则为索敌范围</param>
|
||||
/// <param name="job">指定职业</param>
|
||||
/// <returns></returns>
|
||||
public static GameUnit FindNearestTarget(GameUnit owner, int range = -1, Ejob job = Ejob.Job_Other)
|
||||
{
|
||||
try
|
||||
{
|
||||
var inSightDistanceDic = FindEnemiesInRange(owner, range, job);
|
||||
return GetNearestUnit(inSightDistanceDic);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.FindNearestTarget error: {0}", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 寻找范围内符合条件的所有敌人
|
||||
/// </summary>
|
||||
public static Dictionary<GameUnit, int> FindEnemiesInRange(GameUnit owner, int range = -1,
|
||||
Ejob job = Ejob.Job_Other, uint targetID = 0)
|
||||
{
|
||||
if (owner == null || range == 0) return null;
|
||||
|
||||
var enemies = GameUnitManager.instance.SearchEnemies(owner);
|
||||
|
||||
// 使用对象池获取EnemyFilter
|
||||
var filter = ObjPoolManager.instance.Get<EnemyFilter>();
|
||||
filter.Init(owner, range, job, targetID);
|
||||
|
||||
var result = FindUnits(owner, enemies, filter);
|
||||
|
||||
// 使用完毕后返回对象池
|
||||
ObjPoolManager.instance.Return(filter);
|
||||
|
||||
// 归还临时列表
|
||||
GameUnitManager.instance.ReturnTempList(enemies);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最近的单位
|
||||
/// </summary>
|
||||
public static GameUnit GetNearestUnit(Dictionary<GameUnit, int> units)
|
||||
{
|
||||
if (units == null || units.Count == 0)
|
||||
return null;
|
||||
|
||||
var minDistance = float.MaxValue;
|
||||
GameUnit nearestUnit = null;
|
||||
foreach (var pair in units)
|
||||
{
|
||||
if (minDistance > pair.Value)
|
||||
{
|
||||
minDistance = pair.Value;
|
||||
nearestUnit = pair.Key;
|
||||
}
|
||||
}
|
||||
|
||||
return nearestUnit;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取更近的攻击来源单位
|
||||
/// </summary>
|
||||
public static GameUnit GetNearestAttackGameUnit(GameUnit owner, GameUnit newUnit, GameUnit unit)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (owner == null || newUnit == null || unit == null) return null;
|
||||
|
||||
var map = LevelManager.Instance.CurrentLevel.Map;
|
||||
if (map == null) return null;
|
||||
|
||||
var ownerCellIndex = owner.transData?.cellIndex;
|
||||
var unitCellIndex = unit.transData?.cellIndex;
|
||||
var newUnitCellIndex = newUnit.transData?.cellIndex;
|
||||
if (!ownerCellIndex.HasValue || !unitCellIndex.HasValue || !newUnitCellIndex.HasValue) return null;
|
||||
|
||||
var distance = MapUtils.Distance(map, ownerCellIndex.Value, unitCellIndex.Value);
|
||||
var newDistance = MapUtils.Distance(map, ownerCellIndex.Value, newUnitCellIndex.Value);
|
||||
return distance <= newDistance ? unit : newUnit;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.GetNearestGameUnit error: {0}", e);
|
||||
// 异常返回默认单位
|
||||
return unit;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 寻找友军
|
||||
|
||||
/// <summary>
|
||||
/// 通过MonsterID寻找友军 只返回第一个Monster
|
||||
/// </summary>
|
||||
public static GameUnit FindFriendByMonsterID(int id)
|
||||
{
|
||||
foreach (var unit in GameUnitManager.instance.totalUnits.unitList)
|
||||
{
|
||||
if (unit.unitLevelData != null && !unit.statusData.isDead && unit.unitLevelData.monsterId == id)
|
||||
{
|
||||
return unit;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 寻找视野内的最近友军
|
||||
/// </summary>
|
||||
/// <param name="owner">自身</param>
|
||||
/// <param name="range">指定距离 -1为锁敌距离</param>
|
||||
/// <param name="job">指定职业</param>
|
||||
public static GameUnit FindNearestFriend(GameUnit owner, int range = -1, Ejob job = Ejob.Job_Other)
|
||||
{
|
||||
try
|
||||
{
|
||||
var inSightDistanceDic = FindFriendsWithDistance(owner, range, job);
|
||||
return GetNearestUnit(inSightDistanceDic);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.FindNearestFriend error: {0}", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 寻找锁敌范围内的友军列表
|
||||
/// </summary>
|
||||
public static List<GameUnit> FindFriendsInSightDistance(GameUnit owner)
|
||||
{
|
||||
try
|
||||
{
|
||||
var friends = FindFriendsWithDistance(owner);
|
||||
if (friends == null || friends.Count == 0) return new List<GameUnit>();
|
||||
|
||||
// 避免创建新列表,使用单位字典的键集合
|
||||
var result = new List<GameUnit>(friends.Keys);
|
||||
return result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.FindFriendsInSightDistance error: {0}", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 寻找符合条件的友军及距离字典
|
||||
/// </summary>
|
||||
public static Dictionary<GameUnit, int> FindFriendsWithDistance(GameUnit owner, int range = -1,
|
||||
Ejob job = Ejob.Job_Other)
|
||||
{
|
||||
if (owner == null || range == 0) return null;
|
||||
|
||||
var friends = GameUnitManager.instance.SearchFriends(owner);
|
||||
|
||||
// 使用对象池获取FriendFilter
|
||||
var filter = ObjPoolManager.instance.Get<FriendFilter>();
|
||||
filter.Init(owner, range, job);
|
||||
|
||||
var result = FindUnits(owner, friends, filter);
|
||||
|
||||
// 使用完毕后返回对象池
|
||||
ObjPoolManager.instance.Return(filter);
|
||||
|
||||
// 归还临时列表
|
||||
GameUnitManager.instance.ReturnTempList(friends);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测某个地格是否有友军单位
|
||||
/// </summary>
|
||||
public static GameUnit FindFriendByCellIndex(int cellIndex)
|
||||
{
|
||||
var units = AreaManager.instance.GetUnitsByCellIndex(cellIndex);
|
||||
foreach (var unit in units)
|
||||
{
|
||||
if (unit.commonData.troopId == ETroopsId.Enemy)
|
||||
{
|
||||
return unit;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 寻找随机目标
|
||||
|
||||
public static int FindRandomCell(GameUnit owner, int maxStep = 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var map = LevelManager.Instance.CurrentLevel?.Map;
|
||||
if (map == null || owner == null) return -1;
|
||||
var cellIndex = owner.transData.cellIndex;
|
||||
if (!AreaManager.instance.CheckContainsMoveUnit(cellIndex))
|
||||
return -1;
|
||||
var randomCells = new List<int>();
|
||||
for (var i = 1; i <= maxStep; i++)
|
||||
{
|
||||
var minSteps = i - 1;
|
||||
var maxSteps = i;
|
||||
var cells = map.TerrainGridSystem.CellGetNeighboursWithinRange(cellIndex, minSteps, maxSteps,
|
||||
canCrossCheckType: TGS.CanCrossCheckType.IgnoreCanCrossCheckOnAllCells);
|
||||
foreach (var cell in cells)
|
||||
{
|
||||
if (!CheckCellCanSelect(cell)) continue;
|
||||
if (!PathFinder.CanBasePass(cell, owner)) continue;
|
||||
if (AreaManager.instance.CheckContainsMoveUnit(cell)) continue;
|
||||
if (maxSteps > 1)
|
||||
{
|
||||
if (CheckPathExits(owner, cell))
|
||||
{
|
||||
randomCells.Add(cell);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
randomCells.Add(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (randomCells.Count == 0)
|
||||
return -1;
|
||||
|
||||
var randomIndex = UnityEngine.Random.Range(0, randomCells.Count);
|
||||
return randomCells[randomIndex];
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.FindRandomCell error: {0}", e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 寻找随机单位
|
||||
/// </summary>
|
||||
public static GameUnit FindRandomTarget(GameUnit owner, uint enemy, int range = -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
var targetID = enemy;
|
||||
var inSightDistanceDic = FindEnemiesInRange(owner, range, targetID: targetID);
|
||||
|
||||
return GetRandomUnit(inSightDistanceDic);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.FindRandomTarget error: {0}", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取随机单位
|
||||
/// </summary>
|
||||
private static GameUnit GetRandomUnit(Dictionary<GameUnit, int> units)
|
||||
{
|
||||
if (units == null || units.Count == 0)
|
||||
return null;
|
||||
|
||||
// 使用复用的临时列表避免创建新列表
|
||||
TempPairList.Clear();
|
||||
foreach (var pair in units)
|
||||
{
|
||||
TempPairList.Add(new KeyValuePair<GameUnit, int>(pair.Key, pair.Value));
|
||||
}
|
||||
|
||||
if (TempPairList.Count == 0)
|
||||
return null;
|
||||
|
||||
var randomIndex = UnityEngine.Random.Range(0, TempPairList.Count);
|
||||
return TempPairList[randomIndex].Key;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 组内单位 寻找 判断
|
||||
|
||||
public static bool GroupTargetInRange(GameUnit owner, List<int> group)
|
||||
{
|
||||
var inRange = false;
|
||||
var groupFriends = FindGroupUnits(owner, group);
|
||||
foreach (var groupFriend in groupFriends)
|
||||
{
|
||||
var targetID = groupFriend.unitLevelData.AIBattleInfo.Value.targetID;
|
||||
if (targetID == Constants.INVALID_UINT_ID) continue;
|
||||
var target = GameUnitManager.instance.infightUnits.Search(targetID);
|
||||
var distance = GetDistance(owner.transData.cellIndex, target.transData.cellIndex);
|
||||
if (distance <= groupFriend.fightData.trackRange)
|
||||
{
|
||||
inRange = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return inRange;
|
||||
}
|
||||
|
||||
public static List<GameUnit> FindGroupUnits(GameUnit owner, List<int> group)
|
||||
{
|
||||
var groupUnits = new List<GameUnit>();
|
||||
if (owner == null || group == null || group.Count == 0)
|
||||
return groupUnits;
|
||||
|
||||
var friends = GameUnitManager.instance.SearchFriends(owner);
|
||||
foreach (var friend in friends)
|
||||
{
|
||||
if (friend.unitLevelData == null || friend.unitLevelData.AIBattleInfo == null) continue;
|
||||
var unitGroups = friend.unitLevelData.AIBattleInfo.Value.groupInfo;
|
||||
if (unitGroups == null || unitGroups.Count <= 0) continue;
|
||||
// 检查当前单位的组ID列表与传入的组ID列表是否有交集
|
||||
foreach (var groupId in unitGroups)
|
||||
{
|
||||
if (group.Contains(groupId))
|
||||
{
|
||||
groupUnits.Add(friend);
|
||||
break; // 找到一个匹配就可以添加该单位,无需继续检查其他组ID
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return groupUnits;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -9,127 +9,13 @@ using Gameplay.Character;
|
|||
using Gameplay.Area.Around;
|
||||
using Gameplay.Vehicle.Impl;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static Gameplay.Level.LevelData;
|
||||
|
||||
namespace Gameplay.AI
|
||||
{
|
||||
public static partial class AIUtils
|
||||
{
|
||||
private static List<GameUnit> inSightEnemies = new List<GameUnit>(16);
|
||||
private static Dictionary<GameUnit, int> inSightDistanceList = new Dictionary<GameUnit, int>(16);
|
||||
|
||||
private static List<GameUnit> allFriends = new List<GameUnit>(16);
|
||||
private static List<GameUnit> friendsInSight = new List<GameUnit>(16);
|
||||
|
||||
private static Dictionary<int, int> patrolDistanceList = new Dictionary<int, int>(64);
|
||||
|
||||
/// <summary>
|
||||
/// 寻找锁敌范围内最近的敌人
|
||||
/// </summary>
|
||||
public static GameUnit FindNearestEnemyInSightDistance(GameUnit owner)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (owner == null) return null;
|
||||
|
||||
var map = LevelManager.Instance.CurrentLevel.Map;
|
||||
if (map == null) return null;
|
||||
inSightDistanceList.Clear();
|
||||
var enemies = GameUnitManager.instance.SearchEnemies(owner);
|
||||
var ownerCellIndex = owner.transData?.cellIndex;
|
||||
for (var i = 0; i < enemies.Count; i++)
|
||||
{
|
||||
var enemy = enemies[i];
|
||||
if (enemy == null || enemy.statusData.isDead)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var enemyCellIndex = enemy.transData?.cellIndex;
|
||||
|
||||
if (!ownerCellIndex.HasValue || !enemyCellIndex.HasValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var distance = MapUtils.Distance(map, ownerCellIndex.Value, enemyCellIndex.Value);
|
||||
if (distance <= owner.fightData.findEnemyRange &&
|
||||
enemy.statusData.CheckCanBeTarget(owner, (int)owner.fightData.findEnemyRange))
|
||||
{
|
||||
inSightDistanceList.Add(enemy, distance);
|
||||
}
|
||||
}
|
||||
|
||||
if (inSightDistanceList.Count <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
var minDistance = float.MaxValue;
|
||||
GameUnit nearestEnemy = null;
|
||||
foreach (var pair in inSightDistanceList)
|
||||
{
|
||||
if (minDistance > pair.Value)
|
||||
{
|
||||
minDistance = pair.Value;
|
||||
nearestEnemy = pair.Key;
|
||||
}
|
||||
}
|
||||
|
||||
return nearestEnemy;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.FindNearestEnemyInSightDistance error: {0}", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 寻找锁敌范围内的友军
|
||||
/// </summary>
|
||||
public static List<GameUnit> FindFriendsInSightDistance(GameUnit owner)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (owner == null) return null;
|
||||
|
||||
var map = LevelManager.Instance.CurrentLevel.Map;
|
||||
if (map == null) return null;
|
||||
friendsInSight.Clear();
|
||||
var friends = GameUnitManager.instance.SearchFriends(owner);
|
||||
var ownerCellIndex = owner.transData?.cellIndex;
|
||||
for (var i = 0; i < friends.Count; i++)
|
||||
{
|
||||
var friend = friends[i];
|
||||
if (friend == null || friend.GetID() == owner.GetID())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var friendCellIndex = friend.transData?.cellIndex;
|
||||
if (!ownerCellIndex.HasValue || !friendCellIndex.HasValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var distance = MapUtils.Distance(map, ownerCellIndex.Value, friendCellIndex.Value);
|
||||
if (distance <= owner.fightData.findEnemyRange)
|
||||
{
|
||||
friendsInSight.Add(friend);
|
||||
}
|
||||
}
|
||||
|
||||
return friendsInSight;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.FindFriendsInSightDistance error: {0}", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 寻找范围内最近的敌方npc
|
||||
|
|
@ -138,19 +24,38 @@ namespace Gameplay.AI
|
|||
{
|
||||
try
|
||||
{
|
||||
var enemyNpc = FindEnemyNpcInSight(owner);
|
||||
if (enemyNpc == null || enemyNpc.Count <= 0) return null;
|
||||
var level = LevelManager.Instance.CurrentLevel;
|
||||
if (level == null || level.SelfNpcLocalID == null || level.SelfNpcLocalID.Count <= 0) return null;
|
||||
|
||||
var map = LevelManager.Instance.CurrentLevel.Map;
|
||||
if (map == null) return null;
|
||||
|
||||
var enemies = GameUnitManager.instance.SearchEnemies(owner);
|
||||
GameUnit nearestEnemy = null;
|
||||
var minDistance = float.MaxValue;
|
||||
foreach (var pair in enemyNpc)
|
||||
|
||||
var ownerCellIndex = owner.transData?.cellIndex;
|
||||
if (!ownerCellIndex.HasValue) return null;
|
||||
|
||||
foreach (var enemy in enemies)
|
||||
{
|
||||
if (minDistance > pair.Value)
|
||||
if (enemy == null || enemy.statusData.isDead || enemy.unitLevelData == null) continue;
|
||||
if (!level.SelfNpcLocalID.Contains(enemy.unitLevelData.LocalId)) continue;
|
||||
|
||||
var enemyCellIndex = enemy.transData?.cellIndex;
|
||||
if (!enemyCellIndex.HasValue) continue;
|
||||
|
||||
var distance = MapUtils.Distance(map, ownerCellIndex.Value, enemyCellIndex.Value);
|
||||
if (distance <= owner.fightData.findEnemyRange)
|
||||
{
|
||||
minDistance = pair.Value;
|
||||
nearestEnemy = pair.Key;
|
||||
if (distance < minDistance)
|
||||
{
|
||||
minDistance = distance;
|
||||
nearestEnemy = enemy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nearestEnemy;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
@ -196,38 +101,8 @@ namespace Gameplay.AI
|
|||
{
|
||||
try
|
||||
{
|
||||
if (owner == null) return Constants.INVALID_ID;
|
||||
|
||||
var map = LevelManager.Instance.CurrentLevel.Map;
|
||||
if (map == null) return Constants.INVALID_ID;
|
||||
|
||||
patrolDistanceList.Clear();
|
||||
var ownerCellIndex = owner.transData?.cellIndex;
|
||||
for (var i = 0; i < patrolInfos.Count; i++)
|
||||
{
|
||||
var point = map.BlockPosition2TGSCellIndex(patrolInfos[i].patrolPoint);
|
||||
|
||||
if (!ownerCellIndex.HasValue || point == Constants.INVALID_ID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
patrolDistanceList.Add(i,
|
||||
MapUtils.Distance(map, ownerCellIndex.Value, point));
|
||||
}
|
||||
|
||||
var minDistance = int.MaxValue;
|
||||
int nearestPoint = 0;
|
||||
foreach (var pair in patrolDistanceList)
|
||||
{
|
||||
if (minDistance > pair.Value)
|
||||
{
|
||||
minDistance = pair.Value;
|
||||
nearestPoint = pair.Key;
|
||||
}
|
||||
}
|
||||
|
||||
return nearestPoint;
|
||||
// 使用优化后的通用方法
|
||||
return FindNearestPatrolInfoIndex(owner, patrolInfos);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -645,39 +520,6 @@ namespace Gameplay.AI
|
|||
return cellList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 寻找锁敌范围内的敌方npc
|
||||
/// </summary>
|
||||
private static Dictionary<GameUnit, int> FindEnemyNpcInSight(GameUnit owner)
|
||||
{
|
||||
try
|
||||
{
|
||||
var enemyNpc = new Dictionary<GameUnit, int>();
|
||||
var level = LevelManager.Instance.CurrentLevel;
|
||||
if (level == null) return enemyNpc;
|
||||
var map = LevelManager.Instance.CurrentLevel.Map;
|
||||
if (map == null || level.SelfNpcLocalID == null || level.SelfNpcLocalID.Count <= 0) return enemyNpc;
|
||||
var enemyList = GameUnitManager.instance.SearchEnemies(owner);
|
||||
foreach (var enemy in enemyList)
|
||||
{
|
||||
if (enemy.unitLevelData == null) continue;
|
||||
if (level.SelfNpcLocalID.Contains(enemy.unitLevelData.LocalId))
|
||||
{
|
||||
var distance = MapUtils.Distance(map, enemy.transData.cellIndex, owner.transData.cellIndex);
|
||||
if (distance <= owner.fightData.findEnemyRange)
|
||||
enemyNpc.Add(enemy, distance);
|
||||
}
|
||||
}
|
||||
|
||||
return enemyNpc;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugUtil.LogError("AIUtils.FindEnemyNpcInSight error: {0}", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------- New -------------------- //
|
||||
|
||||
#region 载具相关
|
||||
|
|
|
|||
|
|
@ -91,7 +91,11 @@ namespace Gameplay.Character
|
|||
{
|
||||
if (!Level.Level.IsEnemy(team.Key, self.commonData.troopId))
|
||||
{
|
||||
friendList.AddRange(team.Value.characters);
|
||||
var characterList = team.Value.characters;
|
||||
for (int i = 0; i < characterList.Count; i++)
|
||||
{
|
||||
friendList.Add(characterList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -682,17 +682,38 @@ namespace Gameplay.Unit
|
|||
instance = null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 为AI搜索单位列表创建对象池
|
||||
/// </summary>
|
||||
private readonly Stack<List<GameUnit>> _tempListPool = new (4);
|
||||
|
||||
private List<GameUnit> GetTempList()
|
||||
{
|
||||
if (_tempListPool.Count > 0)
|
||||
{
|
||||
var list = _tempListPool.Pop();
|
||||
list.Clear();
|
||||
return list;
|
||||
}
|
||||
return new List<GameUnit>(64);
|
||||
}
|
||||
|
||||
public void ReturnTempList(List<GameUnit> list)
|
||||
{
|
||||
list.Clear();
|
||||
_tempListPool.Push(list);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找所有敌人单位
|
||||
/// </summary>
|
||||
public List<GameUnit> SearchEnemies(GameUnit self)
|
||||
{
|
||||
var enemies = new List<GameUnit>();
|
||||
var enemies = GetTempList();
|
||||
if (self == null) return enemies;
|
||||
characterManager.SearchEnemies(self, enemies);
|
||||
var vehicles = vehicleManager.SearchEnemies(self.commonData.troopId);
|
||||
if (vehicles != null)
|
||||
enemies.AddRange(vehicles);
|
||||
vehicleManager.SearchEnemies(self.commonData.troopId, enemies);
|
||||
return enemies;
|
||||
}
|
||||
|
||||
|
|
@ -701,13 +722,11 @@ namespace Gameplay.Unit
|
|||
/// </summary>
|
||||
public List<GameUnit> SearchFriends(GameUnit self)
|
||||
{
|
||||
var friends = new List<GameUnit>();
|
||||
var friends = GetTempList();
|
||||
if (self == null) return friends;
|
||||
|
||||
characterManager.SearchFriends(self, friends);
|
||||
var vehicles = vehicleManager.SearchFriend(self.commonData.troopId);
|
||||
if (vehicles != null)
|
||||
friends.AddRange(vehicles);
|
||||
vehicleManager.SearchFriend(self.commonData.troopId, friends);
|
||||
return friends;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using Gameplay.Unit;
|
||||
using Gameplay.Vehicle.Impl;
|
||||
namespace Gameplay.Vehicle
|
||||
{
|
||||
|
|
@ -43,31 +44,48 @@ namespace Gameplay.Vehicle
|
|||
return null;
|
||||
}
|
||||
|
||||
public List<NormalVehicle> SearchEnemies(int troopId)
|
||||
/// <summary>
|
||||
/// 查找敌方载具,添加到提供的列表中
|
||||
/// </summary>
|
||||
/// <param name="troopId">己方部队ID</param>
|
||||
/// <param name="resultList">存储结果的列表</param>
|
||||
public void SearchEnemies(int troopId, List<GameUnit> resultList)
|
||||
{
|
||||
if (resultList == null) return;
|
||||
|
||||
foreach (var team in _troopVehicles)
|
||||
{
|
||||
if (Level.Level.IsEnemy(team.Key, troopId))
|
||||
{
|
||||
return team.Value;
|
||||
var vehicles = team.Value;
|
||||
for (int i = 0; i < vehicles.Count; i++)
|
||||
{
|
||||
resultList.Add(vehicles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<NormalVehicle> SearchFriend(int troopId)
|
||||
/// <summary>
|
||||
/// 查找友方载具,添加到提供的列表中
|
||||
/// </summary>
|
||||
/// <param name="troopId">己方部队ID</param>
|
||||
/// <param name="resultList">存储结果的列表</param>
|
||||
public void SearchFriend(int troopId, List<GameUnit> resultList)
|
||||
{
|
||||
if (resultList == null) return;
|
||||
|
||||
foreach (var team in _troopVehicles)
|
||||
{
|
||||
if (!Level.Level.IsEnemy(team.Key, troopId))
|
||||
{
|
||||
return team.Value;
|
||||
var vehicles = team.Value;
|
||||
for (int i = 0; i < vehicles.Count; i++)
|
||||
{
|
||||
resultList.Add(vehicles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue