从 EnemyManager 里拆分出敌人的注册/管理/查询功能
This commit is contained in:
parent
b6a13b18fc
commit
921193f469
|
|
@ -17,18 +17,14 @@ namespace SepCore.EnemyManager
|
|||
private const string EnemyGroupName = "Enemy";
|
||||
|
||||
private EntityComponent _entity;
|
||||
private EnemyRegistry _enemyRegistry;
|
||||
|
||||
private List<EntityBase> _enemies;
|
||||
private Dictionary<int, EntityBase> _enemyById;
|
||||
|
||||
public List<EntityBase> Enemies => _enemies;
|
||||
public List<EntityBase> Enemies => _enemyRegistry?.Enemies;
|
||||
|
||||
private float _spawnEnemyTimer;
|
||||
|
||||
[SerializeField] private int _spawnEnemyMaxCount = 5000;
|
||||
|
||||
private int _currentEnemyCount;
|
||||
|
||||
[SerializeField] private int _spawnDistanceFromPlayer = 20;
|
||||
|
||||
private int _currentSpawnEnemyId;
|
||||
|
|
@ -51,15 +47,14 @@ namespace SepCore.EnemyManager
|
|||
public float SpawnRateScale => _spawnRateScale;
|
||||
public float BattleDuration => _duration;
|
||||
public float ElapsedBattleTime => _spawnEnemyTimer;
|
||||
public int CurrentEnemyCount => _currentEnemyCount;
|
||||
public int CurrentEnemyCount => _enemyRegistry?.Count ?? 0;
|
||||
|
||||
#region FSM
|
||||
|
||||
private void Start()
|
||||
{
|
||||
_entity = GameEntry.Entity;
|
||||
_enemies = new List<EntityBase>();
|
||||
_enemyById = new Dictionary<int, EntityBase>();
|
||||
_enemyRegistry = new EnemyRegistry();
|
||||
|
||||
GameEntry.Event.Subscribe(HideEntityCompleteEventArgs.EventId, OnHideEntityComplete);
|
||||
}
|
||||
|
|
@ -68,8 +63,7 @@ namespace SepCore.EnemyManager
|
|||
{
|
||||
GameEntry.Event.Unsubscribe(HideEntityCompleteEventArgs.EventId, OnHideEntityComplete);
|
||||
|
||||
_enemies = null;
|
||||
_enemyById = null;
|
||||
_enemyRegistry = null;
|
||||
_entity = null;
|
||||
}
|
||||
|
||||
|
|
@ -87,7 +81,7 @@ namespace SepCore.EnemyManager
|
|||
|
||||
SetSpawnRateScale(_spawnRateScale);
|
||||
|
||||
_currentEnemyCount = 0;
|
||||
_enemyRegistry.Clear();
|
||||
_currentSpawnEnemyId = 0;
|
||||
}
|
||||
|
||||
|
|
@ -124,8 +118,6 @@ namespace SepCore.EnemyManager
|
|||
_nextSpawnTimes = null;
|
||||
|
||||
ClearEnemies();
|
||||
|
||||
_currentEnemyCount = 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -134,7 +126,7 @@ namespace SepCore.EnemyManager
|
|||
{
|
||||
if (_player == null) return;
|
||||
|
||||
if (_currentEnemyCount >= _spawnEnemyMaxCount) return;
|
||||
if (_enemyRegistry.Count >= _spawnEnemyMaxCount) return;
|
||||
int entityPoolId = _currentSpawnEnemyId % _spawnEnemyMaxCount;
|
||||
var enemyData = EntityDataFactory.Create(entityPoolId, enemyType, _currentLevel);
|
||||
enemyData.Position = _spawnPositionStrategy.GetSpawnPosition(_player);
|
||||
|
|
@ -146,37 +138,24 @@ namespace SepCore.EnemyManager
|
|||
return;
|
||||
}
|
||||
|
||||
RegisterEnemy(enemy);
|
||||
enemy.SetTarget(_player);
|
||||
_enemyRegistry.Register(enemy);
|
||||
}
|
||||
|
||||
public void ClearEnemies()
|
||||
{
|
||||
foreach (var enemy in _enemies)
|
||||
foreach (var enemy in _enemyRegistry.Enemies)
|
||||
{
|
||||
if (enemy == null || !enemy.Available) continue;
|
||||
_entity.HideEntity(enemy);
|
||||
}
|
||||
|
||||
_enemies.Clear();
|
||||
_enemyById?.Clear();
|
||||
_enemyRegistry.Clear();
|
||||
}
|
||||
|
||||
public bool TryGetEnemy(int entityId, out EntityBase enemy)
|
||||
{
|
||||
enemy = null;
|
||||
if (_enemyById == null || !_enemyById.TryGetValue(entityId, out EntityBase cachedEnemy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cachedEnemy == null || !cachedEnemy.Available)
|
||||
{
|
||||
_enemyById.Remove(entityId);
|
||||
return false;
|
||||
}
|
||||
|
||||
enemy = cachedEnemy;
|
||||
return true;
|
||||
return _enemyRegistry.TryGet(entityId, out enemy);
|
||||
}
|
||||
|
||||
public void SetSpawnRateScale(float scale)
|
||||
|
|
@ -226,20 +205,6 @@ namespace SepCore.EnemyManager
|
|||
|
||||
#region Event Handler
|
||||
|
||||
private void RegisterEnemy(EnemyBase enemy)
|
||||
{
|
||||
if (enemy == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_currentEnemyCount++;
|
||||
enemy.SetTarget(_player);
|
||||
RemoveEnemyFromCache(enemy.Id);
|
||||
_enemies.Add(enemy);
|
||||
_enemyById[enemy.Id] = enemy;
|
||||
}
|
||||
|
||||
private void OnHideEntityComplete(object sender, GameEventArgs e)
|
||||
{
|
||||
if (e is not HideEntityCompleteEventArgs ne) return;
|
||||
|
|
@ -247,34 +212,7 @@ namespace SepCore.EnemyManager
|
|||
string entityGroupName = ne.EntityGroup.Name;
|
||||
if (entityGroupName == EnemyGroupName)
|
||||
{
|
||||
if (_currentEnemyCount > 0)
|
||||
{
|
||||
_currentEnemyCount--;
|
||||
}
|
||||
|
||||
RemoveEnemyFromCache(ne.EntityId);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveEnemyFromCache(int entityId)
|
||||
{
|
||||
if (_enemyById != null)
|
||||
{
|
||||
_enemyById.Remove(entityId);
|
||||
}
|
||||
|
||||
for (int i = _enemies.Count - 1; i >= 0; i--)
|
||||
{
|
||||
EntityBase cachedEnemy = _enemies[i];
|
||||
if (cachedEnemy == null || cachedEnemy.Id == entityId)
|
||||
{
|
||||
if (cachedEnemy != null && _enemyById != null)
|
||||
{
|
||||
_enemyById.Remove(cachedEnemy.Id);
|
||||
}
|
||||
|
||||
_enemies.RemoveAt(i);
|
||||
}
|
||||
_enemyRegistry.Remove(ne.EntityId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
using System.Collections.Generic;
|
||||
using SepCore.Entity;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SepCore.EnemyManager
|
||||
{
|
||||
public class EnemyRegistry
|
||||
{
|
||||
private readonly List<EntityBase> _enemies;
|
||||
private readonly Dictionary<int, EntityBase> _enemyById;
|
||||
|
||||
public int Count { get; private set; }
|
||||
public List<EntityBase> Enemies => _enemies;
|
||||
|
||||
public EnemyRegistry()
|
||||
{
|
||||
_enemies = new List<EntityBase>();
|
||||
_enemyById = new Dictionary<int, EntityBase>();
|
||||
}
|
||||
|
||||
public void Register(EnemyBase enemy)
|
||||
{
|
||||
if (enemy == null) return;
|
||||
|
||||
Count++;
|
||||
RemoveFromCache(enemy.Id);
|
||||
_enemies.Add(enemy);
|
||||
_enemyById[enemy.Id] = enemy;
|
||||
}
|
||||
|
||||
public void Remove(int entityId)
|
||||
{
|
||||
if (Count > 0)
|
||||
{
|
||||
Count--;
|
||||
}
|
||||
|
||||
RemoveFromCache(entityId);
|
||||
}
|
||||
|
||||
public bool TryGet(int entityId, out EntityBase enemy)
|
||||
{
|
||||
enemy = null;
|
||||
if (!_enemyById.TryGetValue(entityId, out EntityBase cachedEnemy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cachedEnemy == null || !cachedEnemy.Available)
|
||||
{
|
||||
_enemyById.Remove(entityId);
|
||||
return false;
|
||||
}
|
||||
|
||||
enemy = cachedEnemy;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_enemies.Clear();
|
||||
_enemyById.Clear();
|
||||
Count = 0;
|
||||
}
|
||||
|
||||
private void RemoveFromCache(int entityId)
|
||||
{
|
||||
_enemyById.Remove(entityId);
|
||||
|
||||
for (int i = _enemies.Count - 1; i >= 0; i--)
|
||||
{
|
||||
EntityBase cachedEnemy = _enemies[i];
|
||||
if (cachedEnemy == null || cachedEnemy.Id == entityId)
|
||||
{
|
||||
if (cachedEnemy != null)
|
||||
{
|
||||
_enemyById.Remove(cachedEnemy.Id);
|
||||
}
|
||||
|
||||
_enemies.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7a24dd17510328f4392432d9da7ab6a5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Reference in New Issue