Add WeaponFeedback component and AddressableManagerWindow meta file
- Implemented WeaponFeedback class for handling weapon-related feedbacks such as hit effects and attack sounds. - Added meta file for AddressableManagerWindow to manage addressable assets. - Included a new jump.data file for profiler data.
This commit is contained in:
@@ -81,7 +81,8 @@ namespace BaseGames.Enemies.AI
|
||||
|
||||
if (distance > 0.01f)
|
||||
{
|
||||
var hit = Physics2D.Raycast(origin, direction.normalized, distance, requester.LOSBlockingMask);
|
||||
// direction / distance == direction.normalized,避免重复开方
|
||||
var hit = Physics2D.Raycast(origin, direction / distance, distance, requester.LOSBlockingMask);
|
||||
// 若无遮挡物(hit.collider == null),则视线畅通
|
||||
hasLOS = hit.collider == null;
|
||||
}
|
||||
|
||||
@@ -27,15 +27,18 @@ namespace BaseGames.Enemies
|
||||
/// <summary>按 SO 配置速度水平移动。dir: +1 右 / -1 左 / 0 停止。</summary>
|
||||
public void MoveHorizontal(float dir)
|
||||
{
|
||||
float speed = _config.WalkSpeed;
|
||||
_rb.velocity = new Vector2(dir * speed, _rb.velocity.y);
|
||||
var vel = _rb.velocity;
|
||||
vel.x = dir * _config.WalkSpeed;
|
||||
_rb.velocity = vel;
|
||||
UpdateFacing(dir);
|
||||
}
|
||||
|
||||
/// <summary>显式指定速度(BD 追击任务调用)。</summary>
|
||||
public void MoveWithSpeed(float dir, float speed)
|
||||
{
|
||||
_rb.velocity = new Vector2(dir * speed, _rb.velocity.y);
|
||||
var vel = _rb.velocity;
|
||||
vel.x = dir * speed;
|
||||
_rb.velocity = vel;
|
||||
UpdateFacing(dir);
|
||||
}
|
||||
|
||||
@@ -52,7 +55,9 @@ namespace BaseGames.Enemies
|
||||
|
||||
public void StopHorizontal()
|
||||
{
|
||||
_rb.velocity = new Vector2(0f, _rb.velocity.y);
|
||||
var vel = _rb.velocity;
|
||||
vel.x = 0f;
|
||||
_rb.velocity = vel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace BaseGames.Enemies
|
||||
private readonly HashSet<EnemyBase> _registeredSet = new();
|
||||
private readonly List<EnemyBase> _registered = new();
|
||||
private readonly Dictionary<EnemyBase, int> _indexMap = new();
|
||||
// 排序临时缓冲区:预计算每个敌人到玩家的距离,避免 Sort 比较器内重复 Vector3 运算(O(n logn) → O(n))
|
||||
private readonly List<(EnemyBase enemy, float sqDist)> _sortTemp = new();
|
||||
// 缓存玩家 Transform
|
||||
private Transform _playerTransform;
|
||||
private readonly CompositeDisposable _subs = new();
|
||||
@@ -72,22 +74,35 @@ namespace BaseGames.Enemies
|
||||
// ── 内部 ──────────────────────────────────────────────────────────
|
||||
private void Rebalance()
|
||||
{
|
||||
if (_registered.Count == 0) return;
|
||||
int n = _registered.Count;
|
||||
if (n == 0) return;
|
||||
|
||||
var playerPos = _playerTransform != null ? _playerTransform.position : Vector3.zero;
|
||||
|
||||
// 按距离平方升序排序(避免开方,性能更好)
|
||||
_registered.Sort((a, b) =>
|
||||
// ① 预计算距离(O(n) Vector3 运算,而非在比较器内重复执行 O(n logn) 次)
|
||||
_sortTemp.Clear();
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
if (a == null) return 1;
|
||||
if (b == null) return -1;
|
||||
float sqA = (a.transform.position - playerPos).sqrMagnitude;
|
||||
float sqB = (b.transform.position - playerPos).sqrMagnitude;
|
||||
return sqA.CompareTo(sqB);
|
||||
});
|
||||
var e = _registered[i];
|
||||
float sqd = e != null
|
||||
? (e.transform.position - playerPos).sqrMagnitude
|
||||
: float.MaxValue;
|
||||
_sortTemp.Add((e, sqd));
|
||||
}
|
||||
|
||||
// ② 对临时列表排序(比较器只做 float 比较,无额外 Vector3 开销)
|
||||
_sortTemp.Sort(static (a, b) => a.sqDist.CompareTo(b.sqDist));
|
||||
|
||||
// ③ 将排序结果写回 _registered,同步重建 _indexMap(修复排序后索引过期的 bug)
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
var e = _sortTemp[i].enemy;
|
||||
_registered[i] = e;
|
||||
if (e != null) _indexMap[e] = i;
|
||||
}
|
||||
|
||||
#if GRAPH_DESIGNER
|
||||
for (int i = _registered.Count - 1; i >= 0; i--)
|
||||
for (int i = n - 1; i >= 0; i--)
|
||||
{
|
||||
var enemy = _registered[i];
|
||||
if (enemy == null) { _registered.RemoveAt(i); continue; }
|
||||
|
||||
Reference in New Issue
Block a user