调整部分数据表配置,优化 SpriteCache 功能
This commit is contained in:
+13
-8
@@ -19,7 +19,7 @@ namespace SepCore.EnemyManager
|
||||
private EnemyRegistry _enemyRegistry;
|
||||
private EnemySpawnScheduler _spawnScheduler;
|
||||
|
||||
public IReadOnlyCollection<EntityBase> Enemies => _enemyRegistry?.Enemies;
|
||||
public IReadOnlyCollection<EntityBase> Enemies => _enemyRegistry.Enemies;
|
||||
|
||||
[SerializeField] private int _spawnEnemyMaxCount = 5000;
|
||||
[SerializeField] private int _spawnDistanceFromPlayer = 20;
|
||||
@@ -38,10 +38,10 @@ namespace SepCore.EnemyManager
|
||||
// 此时 _isStopped 为真,由 OnShowEntitySuccess 在出生瞬间兜底 Hide 掉。
|
||||
private bool _isStopped;
|
||||
|
||||
public float SpawnRateScale => _spawnScheduler?.SpawnRateScale ?? 1f;
|
||||
public float SpawnRateScale => _spawnScheduler.SpawnRateScale;
|
||||
public float BattleDuration => _duration;
|
||||
public float ElapsedBattleTime => _spawnScheduler?.ElapsedTime ?? 0f;
|
||||
public int CurrentEnemyCount => _enemyRegistry?.Count ?? 0;
|
||||
public float ElapsedBattleTime => _spawnScheduler.ElapsedTime;
|
||||
public int CurrentEnemyCount => _enemyRegistry.Count;
|
||||
|
||||
#region Lifecycle
|
||||
|
||||
@@ -71,9 +71,15 @@ namespace SepCore.EnemyManager
|
||||
|
||||
public void OnInit(LevelConfig level, Player player)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
Log.Error("Can not init enemy manager without a player.");
|
||||
return;
|
||||
}
|
||||
|
||||
_isStopped = false;
|
||||
|
||||
_player = player != null ? player.CachedTransform : null;
|
||||
_player = player.CachedTransform;
|
||||
_spawnPositionStrategy = new RandomCircleSpawnStrategy(_spawnDistanceFromPlayer);
|
||||
|
||||
_baseDuration = level.Duration;
|
||||
@@ -116,14 +122,13 @@ namespace SepCore.EnemyManager
|
||||
_currentLevel = 0;
|
||||
_baseDuration = 0;
|
||||
_duration = 0;
|
||||
_player = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private async UniTaskVoid SpawnEnemyAsync(EnemyType enemyType)
|
||||
{
|
||||
if (_player == null) return;
|
||||
|
||||
if (_enemyRegistry.Count >= _spawnEnemyMaxCount) return;
|
||||
int entityId = _currentSpawnEnemyId++;
|
||||
|
||||
@@ -198,7 +203,7 @@ namespace SepCore.EnemyManager
|
||||
private void OnShowEntitySuccess(object sender, GameEventArgs e)
|
||||
{
|
||||
if (e is not ShowEntitySuccessEventArgs ne) return;
|
||||
if (ne.Entity.EntityGroup?.Name != EnemyGroupName)
|
||||
if (ne.Entity.EntityGroup.Name != EnemyGroupName)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace SepCore.EnemyManager
|
||||
public class EnemyRegistry
|
||||
{
|
||||
private readonly Dictionary<int, EntityBase> _enemyById;
|
||||
// PruneInvalidEntries 由 OnUpdate 每帧调用,复用缓冲避免每帧分配。
|
||||
private readonly List<int> _pruneBuffer;
|
||||
|
||||
public int Count => _enemyById.Count;
|
||||
public IReadOnlyCollection<EntityBase> Enemies => _enemyById.Values;
|
||||
@@ -13,11 +15,11 @@ namespace SepCore.EnemyManager
|
||||
public EnemyRegistry()
|
||||
{
|
||||
_enemyById = new Dictionary<int, EntityBase>();
|
||||
_pruneBuffer = new List<int>();
|
||||
}
|
||||
|
||||
public void Register(EnemyBase enemy)
|
||||
{
|
||||
if (enemy == null) return;
|
||||
_enemyById[enemy.Id] = enemy;
|
||||
}
|
||||
|
||||
@@ -35,16 +37,16 @@ namespace SepCore.EnemyManager
|
||||
|
||||
public void PruneInvalidEntries()
|
||||
{
|
||||
var invalidIds = new List<int>();
|
||||
_pruneBuffer.Clear();
|
||||
foreach (var kvp in _enemyById)
|
||||
{
|
||||
if (kvp.Value == null || !kvp.Value.Available)
|
||||
{
|
||||
invalidIds.Add(kvp.Key);
|
||||
_pruneBuffer.Add(kvp.Key);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (int id in invalidIds)
|
||||
foreach (int id in _pruneBuffer)
|
||||
{
|
||||
_enemyById.Remove(id);
|
||||
}
|
||||
|
||||
+10
-5
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using SepCore.CustomUtility;
|
||||
using SepCore.Definition;
|
||||
using SepCore.Timer;
|
||||
using UnityGameFramework.Runtime;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SepCore.EnemyManager
|
||||
@@ -20,7 +20,7 @@ namespace SepCore.EnemyManager
|
||||
|
||||
public float SpawnRateScale => _spawnRateScale;
|
||||
public float ElapsedTime => _elapsedTime;
|
||||
public int WaveCount => _enemyTypes?.Length ?? 0;
|
||||
public int WaveCount => _enemyTypes.Length;
|
||||
|
||||
public void Init(LevelConfig level, Action<EnemyType, int> onSpawn)
|
||||
{
|
||||
@@ -37,7 +37,7 @@ namespace SepCore.EnemyManager
|
||||
{
|
||||
var spawnConfig = level.EnemySpawnConfigs[i];
|
||||
_baseIntervals[i] = spawnConfig.Interval / 1000f;
|
||||
_enemyTypes[i] = EntityDataFactory.GetEnemyType(spawnConfig.EnemyName);
|
||||
_enemyTypes[i] = spawnConfig.EnemyType;
|
||||
_spawnCounts[i] = spawnConfig.EnemyCount;
|
||||
}
|
||||
|
||||
@@ -57,8 +57,13 @@ namespace SepCore.EnemyManager
|
||||
|
||||
public void SetSpawnRateScale(float scale)
|
||||
{
|
||||
if (_waveHandles == null)
|
||||
{
|
||||
Log.Error("Can not set spawn rate scale before scheduler init.");
|
||||
return;
|
||||
}
|
||||
|
||||
_spawnRateScale = Mathf.Max(MinSpawnRateScale, scale);
|
||||
if (_waveHandles == null) return;
|
||||
|
||||
for (int i = 0; i < _waveHandles.Length; i++)
|
||||
{
|
||||
@@ -81,7 +86,7 @@ namespace SepCore.EnemyManager
|
||||
|
||||
private void OnWaveTick(int waveIndex)
|
||||
{
|
||||
_onSpawn?.Invoke(_enemyTypes[waveIndex], _spawnCounts[waveIndex]);
|
||||
_onSpawn(_enemyTypes[waveIndex], _spawnCounts[waveIndex]);
|
||||
}
|
||||
|
||||
private static float GetScaledInterval(float baseInterval, float scale)
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace SepCore.CustomComponent
|
||||
{
|
||||
{
|
||||
typeof(EnemyConfig),
|
||||
StringAccessor(tables => key => tables.TbEnemyConfig.GetOrDefault(key),
|
||||
Accessor(tables => key => tables.TbEnemyConfig.GetOrDefault((EnemyType)key),
|
||||
tables => tables.TbEnemyConfig.DataList)
|
||||
},
|
||||
{
|
||||
@@ -124,7 +124,7 @@ namespace SepCore.CustomComponent
|
||||
},
|
||||
{
|
||||
typeof(WeaponConfig),
|
||||
Accessor(tables => id => tables.TbWeaponConfig.GetOrDefault(id),
|
||||
Accessor(tables => id => tables.TbWeaponConfig.GetOrDefault((WeaponType)id),
|
||||
tables => tables.TbWeaponConfig.DataList)
|
||||
},
|
||||
};
|
||||
|
||||
-1
@@ -1,7 +1,6 @@
|
||||
using SepCore.Event;
|
||||
using SepCore.Definition;
|
||||
using SepCore.Entity;
|
||||
using SepCore.Entity.Weapon;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SepCore.Simulation
|
||||
|
||||
-1
@@ -1,5 +1,4 @@
|
||||
using SepCore.Entity;
|
||||
using SepCore.Entity.Weapon;
|
||||
using UnityEngine;
|
||||
|
||||
namespace SepCore.Simulation
|
||||
|
||||
-1
@@ -1,7 +1,6 @@
|
||||
using SepCore.Event;
|
||||
using SepCore.Entity;
|
||||
using SepCore.AsyncTask;
|
||||
using SepCore.Entity.Weapon;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using GameFramework.Event;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3069a4f1cc8f5b84d98b3bf5745c6450
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,50 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using GameFramework.Resource;
|
||||
using SepCore.AsyncTask;
|
||||
using SepCore.CustomUtility;
|
||||
using SepCore.Definition;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace SepCore.SpriteCache
|
||||
{
|
||||
public class SpriteCacheComponent : GameFrameworkComponent
|
||||
{
|
||||
[SerializeField] private float _pixelsPerUnit = 100f;
|
||||
[SerializeField] private Vector2 _defaultPivot = new(0.5f, 0.5f);
|
||||
|
||||
private Dictionary<string, Sprite> _spriteCache;
|
||||
private ResourceComponent _resource;
|
||||
|
||||
void Start()
|
||||
{
|
||||
_spriteCache = new Dictionary<string, Sprite>();
|
||||
_resource = GameEntry.Resource;
|
||||
}
|
||||
|
||||
public async UniTask<Sprite> GetSprite(string assetName)
|
||||
{
|
||||
if (_spriteCache.TryGetValue(assetName, out var sprite))
|
||||
return sprite;
|
||||
|
||||
var texture = await _resource.LoadAssetAsync<Texture2D>(
|
||||
AssetUtility.GetUITextureIconAsset(assetName),
|
||||
Constant.AssetPriority.UIFormAsset);
|
||||
|
||||
var newSprite = Sprite.Create(
|
||||
texture,
|
||||
new Rect(0, 0, texture.width, texture.height),
|
||||
_defaultPivot,
|
||||
_pixelsPerUnit);
|
||||
_spriteCache.TryAdd(assetName, newSprite);
|
||||
return newSprite;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
_spriteCache.Clear();
|
||||
_resource = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aae7fd2af99064a4088471109952ad96
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user