123 lines
4.6 KiB
C#
123 lines
4.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Cielonos.MainGame.Characters;
|
|
using UnityEngine;
|
|
|
|
namespace Cielonos.MainGame
|
|
{
|
|
public partial class CombatManager
|
|
{
|
|
public partial class EnemySubmodule : SubmoduleBase<CombatManager>
|
|
{
|
|
public enum SortingType
|
|
{
|
|
Nearest,
|
|
Farthest
|
|
}
|
|
|
|
public List<Enemy> activeEnemiesList;
|
|
|
|
/// <summary>
|
|
/// 敌人从活跃列表中移除时触发(即敌人死亡/离场)。
|
|
/// 参数为被移除的敌人实例。
|
|
/// </summary>
|
|
public event Action<Enemy> OnEnemyRemoved;
|
|
|
|
public EnemySubmodule(CombatManager owner) : base(owner)
|
|
{
|
|
activeEnemiesList = new List<Enemy>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 将敌人从活跃列表中移除并触发 OnEnemyRemoved 事件。
|
|
/// 由 Automata.Die() 调用,替代直接操作 activeEnemiesList。
|
|
/// </summary>
|
|
public void RemoveEnemy(Enemy enemy)
|
|
{
|
|
if (!activeEnemiesList.Remove(enemy)) return;
|
|
OnEnemyRemoved?.Invoke(enemy);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 清空活跃敌人列表(房间重置时调用)。不触发逐条 OnEnemyRemoved 事件。
|
|
/// </summary>
|
|
public void Reset()
|
|
{
|
|
activeEnemiesList.Clear();
|
|
}
|
|
|
|
public List<Enemy> GetEnemiesInRadius(Vector3 origin, float radius, SortingType sortingType = SortingType.Nearest)
|
|
{
|
|
List<Enemy> enemiesInRadius = new List<Enemy>();
|
|
foreach (Enemy enemy in activeEnemiesList)
|
|
{
|
|
float enemyRadius = enemy.collisionSc.useCharacterController
|
|
? enemy.collisionSc.characterController.radius
|
|
: enemy.collisionSc.mainColliderRadius;
|
|
|
|
float distance = Vector3.Distance(origin, enemy.transform.position) - enemyRadius;
|
|
if (distance <= radius)
|
|
{
|
|
enemiesInRadius.Add(enemy);
|
|
}
|
|
}
|
|
|
|
if (sortingType == SortingType.Nearest)
|
|
{
|
|
enemiesInRadius = enemiesInRadius.OrderBy(x => Vector3.Distance(origin, x.transform.position)).ToList();
|
|
}
|
|
else if (sortingType == SortingType.Farthest)
|
|
{
|
|
enemiesInRadius = enemiesInRadius.OrderByDescending(x => Vector3.Distance(origin, x.transform.position)).ToList();
|
|
}
|
|
|
|
return enemiesInRadius;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取所有可见敌人
|
|
/// </summary>
|
|
public List<Enemy> GetVisibleEnemies(float radius = 50f)
|
|
{
|
|
List<Enemy> result = new List<Enemy>();
|
|
List<Enemy> enemies = GetEnemiesInRadius(Player.transform.position, radius);
|
|
|
|
foreach (Enemy enemy in enemies)
|
|
{
|
|
if (enemy == null || enemy.statusSm.isDead) continue;
|
|
|
|
Vector3 screenPos = Player.viewSc.playerCamera.WorldToScreenPoint(enemy.centerPoint.position);
|
|
bool isInScreen = screenPos.z > 0 &&
|
|
screenPos.x > 0 && screenPos.x < Screen.width &&
|
|
screenPos.y > 0 && screenPos.y < Screen.height;
|
|
|
|
if (isInScreen)
|
|
{
|
|
result.Add(enemy);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取按屏幕X坐标从左到右排序的可见敌人列表
|
|
/// </summary>
|
|
public List<Enemy> GetVisibleEnemiesSortedByScreenX(float radius = 50f)
|
|
{
|
|
List<Enemy> visibleEnemies = GetVisibleEnemies(radius);
|
|
|
|
visibleEnemies.Sort((a, b) =>
|
|
{
|
|
Vector3 screenA = Player.viewSc.playerCamera.WorldToScreenPoint(a.centerPoint.position);
|
|
Vector3 screenB = Player.viewSc.playerCamera.WorldToScreenPoint(b.centerPoint.position);
|
|
return screenA.x.CompareTo(screenB.x);
|
|
});
|
|
|
|
return visibleEnemies;
|
|
}
|
|
}
|
|
}
|
|
}
|