NLDClient-yudde/ProjectNLD/Assets/Code/Scripts/Modules/BattleSystem.md

411 lines
10 KiB
Markdown
Raw Normal View History

2025-03-03 14:49:20 +08:00
# 战斗系统优化建议
## 1. 状态管理优化
### 1.1 当前实现
```csharp
// LevelStateBattle.cs 中的状态管理
public class LevelStateBattle : BaseLevelState
{
private bool _canUpdate;
private bool _oldPauseStatus;
protected override void _OnRunning()
{
base._OnRunning();
PauseManager.instance.LogicUpdate(deltaTime);
SkillManager.instance.LogicUpdate(deltaTime);
if (AreaManager.instance.isInSkillPreview) return;
_level.LevelTime += deltaTime;
BulletManager.instance.LogicUpdate(deltaTime);
GameUnitManager.instance.LogicUpdate(deltaTime);
BuffManager.instance.LogicUpdate(deltaTime);
ExtLogicManager.instance.LogicUpdate(deltaTime);
AreaManager.instance.LogicUpdate(deltaTime);
// ...其他更新
}
}
```
### 1.2 优化建议
1. 优化状态管理和更新逻辑:
```csharp
public class LevelStateBattle : BaseLevelState
{
// 将更新逻辑分组
private readonly List<ILogicUpdate> _basicUpdaters = new();
private readonly List<ILogicUpdate> _battleUpdaters = new();
private void InitializeUpdaters()
{
// 基础更新组(无条件更新)
_basicUpdaters.Add(PauseManager.instance);
_basicUpdaters.Add(SkillManager.instance);
// 战斗更新组(非技能预览时更新)
_battleUpdaters.Add(BulletManager.instance);
_battleUpdaters.Add(GameUnitManager.instance);
_battleUpdaters.Add(BuffManager.instance);
_battleUpdaters.Add(AreaManager.instance);
}
protected override void _OnRunning()
{
base._OnRunning();
// 更新基础系统
foreach (var updater in _basicUpdaters)
{
updater.LogicUpdate(deltaTime);
}
// 技能预览时不更新战斗
if (AreaManager.instance.isInSkillPreview)
return;
// 更新战斗系统
foreach (var updater in _battleUpdaters)
{
updater.LogicUpdate(deltaTime);
}
// 更新战斗时间和剧情
UpdateBattleTime();
UpdateStory();
}
}
public class LevelStateBattle : BaseLevelState
{
private BattlePhase _currentPhase;
private Dictionary<BattlePhase, Action<float>> _phaseUpdaters;
private void InitializePhaseUpdaters()
{
_phaseUpdaters = new Dictionary<BattlePhase, Action<float>>
{
{ BattlePhase.Preparation, UpdatePreparationPhase },
{ BattlePhase.UnitMovement, UpdateMovementPhase },
{ BattlePhase.SkillExecution, UpdateSkillPhase },
{ BattlePhase.PostProcess, UpdatePostProcessPhase }
};
}
protected override void _OnRunning()
{
if (_phaseUpdaters.TryGetValue(_currentPhase, out var updater))
{
updater(deltaTime);
}
}
}
```
## 2. 事件系统优化
### 2.1 当前实现存在的问题
1. 事件注册和注销分散
2. 事件名称字符串容易写错
3. 缺乏事件参数类型安全检查
### 2.2 优化建议
1. 实现类型安全的事件系统:
```csharp
public class BattleEventSystem
{
private readonly Dictionary<Type, Delegate> _eventHandlers = new();
public void Register<TEvent>(Action<TEvent> handler)
where TEvent : IBattleEvent
{
var type = typeof(TEvent);
if (_eventHandlers.TryGetValue(type, out var existing))
{
_eventHandlers[type] = Delegate.Combine(existing, handler);
}
else
{
_eventHandlers[type] = handler;
}
}
public void Send<TEvent>(TEvent eventData) where TEvent : IBattleEvent
{
if (_eventHandlers.TryGetValue(typeof(TEvent), out var handler))
{
((Action<TEvent>)handler)(eventData);
}
}
}
public void UpdateUnit(GameUnit unit)
{
var gridPos = WorldToGrid(unit.transform.position);
// 更新单位所在网格
}
public List<GameUnit> GetUnitsInRange(Vector3 position, float radius)
{
var result = new List<GameUnit>();
var gridPos = WorldToGrid(position);
// 返回范围内的单位
return result;
}
}
```
2. 优化单位更新逻辑:
```csharp
public class GameUnitManager
{
private SpatialHashGrid _spatialGrid;
public void LogicUpdate(float dt)
{
// 使用Job System进行并行更新
var unitUpdateJob = new UnitUpdateJob
{
deltaTime = dt,
units = infightUnits.ToNativeArray()
};
// 执行Job
var handle = unitUpdateJob.Schedule(infightUnits.count, 64);
handle.Complete();
// 更新空间网格
foreach (var unit in infightUnits)
{
_spatialGrid.UpdateUnit(unit);
}
}
}
```
## 3. 交互系统优化
### 3.1 当前问题
- 点击处理逻辑分散在多处
- 状态判断条件复杂
- 缺乏统一的输入管理
### 3.2 优化建议
1. 分离技能效果和表现:
```csharp
public abstract class SkillEffect
{
public abstract void Apply(GameUnit caster, GameUnit target);
}
public class DamageEffect : SkillEffect
{
public float damageAmount;
public override void Apply(GameUnit caster, GameUnit target)
{
var finalDamage = CalculateDamage(caster, target, damageAmount);
target.TakeDamage(finalDamage);
}
}
public class Skill
{
private List<SkillEffect> _effects;
private SkillVisual _visual;
public async UniTask Execute(GameUnit caster, GameUnit target)
{
// 播放技能表现
await _visual.PlayAsync();
// 应用技能效果
foreach (var effect in _effects)
{
effect.Apply(caster, target);
}
}
}
```
2. 使用对象池优化技能特效:
```csharp
public class SkillEffectPool : MonoBehaviour
{
private Dictionary<string, Queue<GameObject>> _effectPools;
public GameObject Get(string effectId)
{
if (!_effectPools.ContainsKey(effectId))
{
CreatePool(effectId);
}
var pool = _effectPools[effectId];
if (pool.Count > 0)
{
var effect = pool.Dequeue();
effect.SetActive(true);
return effect;
}
return CreateNewEffect(effectId);
}
public void Return(string effectId, GameObject effect)
{
effect.SetActive(false);
_effectPools[effectId].Enqueue(effect);
}
}
```
## 4. 性能优化建议
### 4.1 批处理渲染
对于相同材质的单位模型使用GPU Instancing
```csharp
public class UnitRenderer : MonoBehaviour
{
private static MaterialPropertyBlock _propertyBlock;
private static List<UnitRenderer> _instances = new List<UnitRenderer>();
private void OnEnable()
{
_instances.Add(this);
}
private void OnDisable()
{
_instances.Remove(this);
}
public static void UpdateAllInstances()
{
// 使用GPU Instancing进行批量渲染
if (_propertyBlock == null)
_propertyBlock = new MaterialPropertyBlock();
foreach (var instance in _instances)
{
// 更新材质属性
instance.UpdateProperties(_propertyBlock);
}
}
}
```
### 4.2 区域计算优化
使用Job System优化区域计算
```csharp
public struct AreaCalculationJob : IJobParallelFor
{
[ReadOnly] public NativeArray<int> CenterCells;
[ReadOnly] public int Range;
public NativeArray<bool> Results;
public void Execute(int index)
{
var centerCell = CenterCells[index];
// 计算范围内的格子
Results[index] = CalculateArea(centerCell, Range);
}
}
public class AreaManager
{
public void CalculateAreas(List<int> centerCells, int range)
{
var job = new AreaCalculationJob
{
CenterCells = new NativeArray<int>(centerCells.ToArray(), Allocator.TempJob),
Range = range,
Results = new NativeArray<bool>(centerCells.Count, Allocator.TempJob)
};
// 执行Job
var handle = job.Schedule(centerCells.Count, 64);
handle.Complete();
// 使用结果
ProcessResults(job.Results);
// 释放资源
job.CenterCells.Dispose();
job.Results.Dispose();
}
}
```
## 5. 数据管理优化
### 5.1 配置数据加载
使用ScriptableObject优化配置数据
```csharp
[CreateAssetMenu(fileName = "UnitConfig", menuName = "Battle/UnitConfig")]
public class UnitConfig : ScriptableObject
{
public List<UnitData> unitDataList;
// 使用字典缓存数据
private Dictionary<int, UnitData> _unitDataCache;
public UnitData GetUnitData(int id)
{
if (_unitDataCache == null)
{
_unitDataCache = unitDataList.ToDictionary(data => data.id);
}
return _unitDataCache.TryGetValue(id, out var data) ? data : null;
}
}
```
### 5.2 运行时数据管理
使用对象池和组件池优化内存:
```csharp
public class ComponentPool<T> where T : Component
{
private Queue<T> _pool;
private T _prefab;
private Transform _parent;
public T Get()
{
if (_pool.Count > 0)
{
var component = _pool.Dequeue();
component.gameObject.SetActive(true);
return component;
}
return GameObject.Instantiate(_prefab, _parent);
}
public void Return(T component)
{
component.gameObject.SetActive(false);
_pool.Enqueue(component);
}
}
```
## 6. 后续优化方向
1. 战斗逻辑
- 实现更细粒度的状态管理
- 优化单位间的交互逻辑
- 增加战斗回放功能
2. 性能优化
- 使用ECS重构部分热点逻辑
- 优化寻路算法
- 实现LOD系统
3. 内存优化
- 实现资源预加载策略
- 优化对象池系统
- 增加内存监控工具