refactor(enemy): 小怪选招改用 WeightedPick 共享原语(权重缓冲复用,零 GC)
This commit is contained in:
@@ -10,9 +10,14 @@ namespace BaseGames.Enemies.Abilities
|
|||||||
public sealed class EnemyAttackSelector
|
public sealed class EnemyAttackSelector
|
||||||
{
|
{
|
||||||
private readonly List<IAttackCandidate> _candidates;
|
private readonly List<IAttackCandidate> _candidates;
|
||||||
|
// 权重缓冲区(与 _candidates 等长,每次选招复用):避免每次选招 new List 造成 GC
|
||||||
|
private readonly List<float> _weightBuf;
|
||||||
|
|
||||||
public EnemyAttackSelector(IEnumerable<IAttackCandidate> candidates)
|
public EnemyAttackSelector(IEnumerable<IAttackCandidate> candidates)
|
||||||
=> _candidates = new List<IAttackCandidate>(candidates);
|
{
|
||||||
|
_candidates = new List<IAttackCandidate>(candidates);
|
||||||
|
_weightBuf = new List<float>(_candidates.Count);
|
||||||
|
}
|
||||||
|
|
||||||
public int Count => _candidates.Count;
|
public int Count => _candidates.Count;
|
||||||
|
|
||||||
@@ -47,22 +52,19 @@ namespace BaseGames.Enemies.Abilities
|
|||||||
|
|
||||||
private IAttackCandidate SelectByWeight(bool hasLOS, bool grounded)
|
private IAttackCandidate SelectByWeight(bool hasLOS, bool grounded)
|
||||||
{
|
{
|
||||||
float total = 0f;
|
// 有效权重:不合格候选填 0(由共享原语保证零权重项绝不被选中)。缓冲区复用 → 选招零 GC。
|
||||||
|
_weightBuf.Clear();
|
||||||
for (int i = 0; i < _candidates.Count; i++)
|
for (int i = 0; i < _candidates.Count; i++)
|
||||||
{
|
{
|
||||||
var c = _candidates[i];
|
var c = _candidates[i];
|
||||||
if (Eligible(c, hasLOS, grounded)) total += Mathf.Max(0f, c.Weight);
|
_weightBuf.Add(Eligible(c, hasLOS, grounded) ? Mathf.Max(0f, c.Weight) : 0f);
|
||||||
}
|
}
|
||||||
if (total <= 0f) return SelectByPriority(hasLOS, grounded); // 权重全 0 → 退化为按 Priority 选(并列取首个)
|
|
||||||
float roll = Random.value * total;
|
int idx = BaseGames.Core.WeightedPick.Index(_weightBuf);
|
||||||
for (int i = 0; i < _candidates.Count; i++)
|
if (idx >= 0) return _candidates[idx];
|
||||||
{
|
|
||||||
var c = _candidates[i];
|
// 无正权重(合格候选权重全 0)→ 退化为按 Priority 选(并列取首个)
|
||||||
if (!Eligible(c, hasLOS, grounded)) continue;
|
return SelectByPriority(hasLOS, grounded);
|
||||||
roll -= Mathf.Max(0f, c.Weight);
|
|
||||||
if (roll <= 0f) return c;
|
|
||||||
}
|
|
||||||
return null; // 理论不达(浮点边界兜底)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user