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

10 KiB
Raw Blame History

战斗系统优化建议

1. 状态管理优化

1.1 当前实现

// 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. 优化状态管理和更新逻辑:
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. 实现类型安全的事件系统:
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;
    }
}
  1. 优化单位更新逻辑:
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. 分离技能效果和表现:
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);
        }
    }
}
  1. 使用对象池优化技能特效:
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

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优化区域计算

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优化配置数据

[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 运行时数据管理

使用对象池和组件池优化内存:

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. 内存优化

    • 实现资源预加载策略
    • 优化对象池系统
    • 增加内存监控工具