狗屎Minimax坏我代码
This commit is contained in:
670
docs/架构改进建议.md
Normal file
670
docs/架构改进建议.md
Normal file
@@ -0,0 +1,670 @@
|
||||
# Cielonos 项目架构改进建议
|
||||
|
||||
## 一、整体架构评估
|
||||
|
||||
### 当前架构优势
|
||||
1. **模块化设计**: Submodule/Subcontroller架构将逻辑和表现分离,提供了良好的可扩展性
|
||||
2. **组件化思想**: 大量使用字典存储子模块,便于动态增删功能
|
||||
3. **事件驱动**: 使用UniRx实现响应式事件系统,解耦了系统间的依赖
|
||||
4. **系统完整性**: 战斗、Buff、状态、动画等核心系统已经具备完整的基础架构
|
||||
|
||||
### 当前架构不足
|
||||
1. **职责边界模糊**: 部分类承担了过多职责
|
||||
2. **代码组织混乱**: 部分脚本放置位置不合理
|
||||
3. **抽象程度不足**: 部分核心逻辑缺少接口抽象
|
||||
4. **文档注释缺失**: 代码缺少必要的注释和说明
|
||||
5. **配置化程度低**: 硬编码问题较多
|
||||
|
||||
---
|
||||
|
||||
## 二、具体改进建议
|
||||
|
||||
### 1. 核心架构层
|
||||
|
||||
#### 1.1 建立核心接口层
|
||||
**问题**: 当前系统之间直接依赖具体实现,缺乏抽象层
|
||||
|
||||
**建议**:
|
||||
```
|
||||
Core/Interfaces/
|
||||
├── ICharacter.cs # 角色接口
|
||||
├── IAttackable.cs # 可攻击对象接口
|
||||
├── IBuffable.cs # 可附魔Buff对象接口
|
||||
├── IItem.cs # 物品接口
|
||||
├── IWeapon.cs # 武器接口
|
||||
├── IDamageable.cs # 可受伤害对象接口
|
||||
└── ITeamMember.cs # 阵营成员接口
|
||||
```
|
||||
|
||||
**示例代码**:
|
||||
```csharp
|
||||
public interface ICharacter
|
||||
{
|
||||
Fraction Team { get; }
|
||||
bool IsDead { get; }
|
||||
float Health { get; }
|
||||
float MaxHealth { get; }
|
||||
|
||||
void TakeDamage(DamageInfo damageInfo);
|
||||
void ApplyBuff(IBuff buff);
|
||||
void Heal(float amount);
|
||||
}
|
||||
|
||||
public interface IDamageSource
|
||||
{
|
||||
DamageInfo CreateDamage();
|
||||
AttackType DamageType { get; }
|
||||
float DamageValue { get; }
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.2 引入服务定位器模式
|
||||
**问题**: Manager类直接持有引用,系统间耦合度高
|
||||
|
||||
**建议**:
|
||||
```csharp
|
||||
public static class GameServices
|
||||
{
|
||||
private static readonly Dictionary<Type, object> services = new Dictionary<Type, object>();
|
||||
|
||||
public static void Register<T>(T service) where T : class
|
||||
{
|
||||
services[typeof(T)] = service;
|
||||
}
|
||||
|
||||
public static T Get<T>() where T : class
|
||||
{
|
||||
if (services.TryGetValue(typeof(T), out var service))
|
||||
{
|
||||
return service as T;
|
||||
}
|
||||
|
||||
Debug.LogError($"Service {typeof(T)} not found!");
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
services.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
public class BattleManager : MonoBehaviour
|
||||
{
|
||||
public void Initialize()
|
||||
{
|
||||
GameServices.Register<IBattleService>(this);
|
||||
GameServices.Register<ICharacterService>(new CharacterService());
|
||||
GameServices.Register<IBuffService>(new BuffService());
|
||||
}
|
||||
}
|
||||
|
||||
// 在其他类中使用
|
||||
var battleService = GameServices.Get<IBattleService>();
|
||||
```
|
||||
|
||||
#### 1.3 建立消息总线系统
|
||||
**问题**: 当前事件系统分散在各个类中,难以追踪和调试
|
||||
|
||||
**建议**:
|
||||
```csharp
|
||||
public enum GameEvent
|
||||
{
|
||||
// 角色事件
|
||||
CharacterDied,
|
||||
CharacterSpawned,
|
||||
CharacterRevived,
|
||||
|
||||
// 战斗事件
|
||||
DamageDealt,
|
||||
DamageTaken,
|
||||
AttackBlocked,
|
||||
AttackDodged,
|
||||
CriticalHit,
|
||||
|
||||
// 物品事件
|
||||
ItemAcquired,
|
||||
ItemUsed,
|
||||
ItemDiscarded,
|
||||
WeaponSwitched,
|
||||
|
||||
// Buff事件
|
||||
BuffApplied,
|
||||
BuffRemoved,
|
||||
BuffExpired,
|
||||
|
||||
// 游戏状态事件
|
||||
WaveStarted,
|
||||
WaveCleared,
|
||||
BossAppeared,
|
||||
BossDefeated,
|
||||
|
||||
// 系统事件
|
||||
GamePaused,
|
||||
GameResumed,
|
||||
CheckpointReached
|
||||
}
|
||||
|
||||
public class GameEventBus
|
||||
{
|
||||
private static readonly Dictionary<GameEvent, Action<GameEventArgs>>
|
||||
eventHandlers = new Dictionary<GameEvent, Action<GameEventArgs>>();
|
||||
|
||||
public static void Subscribe(GameEvent eventType, Action<GameEventArgs> handler)
|
||||
{
|
||||
if (!eventHandlers.ContainsKey(eventType))
|
||||
{
|
||||
eventHandlers[eventType] = handler;
|
||||
}
|
||||
else
|
||||
{
|
||||
eventHandlers[eventType] += handler;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Unsubscribe(GameEvent eventType, Action<GameEventArgs> handler)
|
||||
{
|
||||
if (eventHandlers.ContainsKey(eventType))
|
||||
{
|
||||
eventHandlers[eventType] -= handler;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Publish(GameEvent eventType, GameEventArgs args = null)
|
||||
{
|
||||
if (eventHandlers.TryGetValue(eventType, out var handler))
|
||||
{
|
||||
handler?.Invoke(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class GameEventArgs
|
||||
{
|
||||
public object Sender { get; set; }
|
||||
public Dictionary<string, object> Data { get; set; } = new Dictionary<string, object>();
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 角色系统改进
|
||||
|
||||
#### 2.1 拆分CharacterBase
|
||||
**问题**: CharacterBase类过于庞大,承担了太多职责
|
||||
|
||||
**建议**: 将其拆分为多个专门类
|
||||
```csharp
|
||||
// 核心角色数据
|
||||
public class CharacterData : ScriptableObject
|
||||
{
|
||||
public string characterId;
|
||||
public string characterName;
|
||||
public Fraction defaultFaction;
|
||||
public AttributeData baseAttributes;
|
||||
public VFXData vfxData;
|
||||
public AudioContainer audioData;
|
||||
public List<SerializableType> availableBuffs;
|
||||
}
|
||||
|
||||
// 角色配置器
|
||||
public class CharacterBuilder
|
||||
{
|
||||
private CharacterData data;
|
||||
private List<ICharacterComponent> components = new List<ICharacterComponent>();
|
||||
|
||||
public CharacterBuilder SetData(CharacterData data) { ... }
|
||||
public CharacterBuilder AddComponent<T>() where T : ICharacterComponent { ... }
|
||||
public ICharacter Build() { ... }
|
||||
}
|
||||
|
||||
// 组件接口
|
||||
public interface ICharacterComponent
|
||||
{
|
||||
void Initialize(ICharacter character);
|
||||
void Update(float deltaTime);
|
||||
void Cleanup();
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2 改进属性系统
|
||||
**问题**: 当前属性使用字符串字典,缺少类型安全和IDE支持
|
||||
|
||||
**建议**:
|
||||
```csharp
|
||||
// 属性ID枚举
|
||||
public enum AttributeId
|
||||
{
|
||||
// 基础属性
|
||||
MaxHealth,
|
||||
CurrentHealth,
|
||||
MaxEnergy,
|
||||
CurrentEnergy,
|
||||
MovementSpeed,
|
||||
AttackSpeed,
|
||||
|
||||
// 战斗属性
|
||||
PhysicalAttack,
|
||||
PhysicalDefense,
|
||||
EnergyAttack,
|
||||
EnergyDefense,
|
||||
CriticalRate,
|
||||
CriticalDamage,
|
||||
|
||||
// 抗性
|
||||
FireResistance,
|
||||
IceResistance,
|
||||
LightningResistance,
|
||||
|
||||
// 特殊属性
|
||||
LifeSteal,
|
||||
CooldownReduction,
|
||||
}
|
||||
|
||||
// 属性修饰器
|
||||
public interface IAttributeModifier
|
||||
{
|
||||
int Priority { get; }
|
||||
AttributeId TargetAttribute { get; }
|
||||
float Modify(float originalValue);
|
||||
}
|
||||
|
||||
// 属性计算器
|
||||
public class AttributeCalculator
|
||||
{
|
||||
private List<IAttributeModifier> modifiers = new List<IAttributeModifier>();
|
||||
|
||||
public float Calculate(AttributeId attributeId, float baseValue)
|
||||
{
|
||||
var applicableModifiers = modifiers
|
||||
.Where(m => m.TargetAttribute == attributeId)
|
||||
.OrderBy(m => m.Priority);
|
||||
|
||||
float result = baseValue;
|
||||
foreach (var modifier in applicableModifiers)
|
||||
{
|
||||
result = modifier.Modify(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 战斗系统改进
|
||||
|
||||
#### 3.1 建立战斗配置系统
|
||||
**问题**: 战斗参数硬编码,难以平衡调整
|
||||
|
||||
**建议**:
|
||||
```csharp
|
||||
[CreateAssetMenu(fileName = "BattleConfig", menuName = "Cielonos/Config/BattleConfig")]
|
||||
public class BattleConfig : ScriptableObject
|
||||
{
|
||||
[Header("Damage Calculation")]
|
||||
public float baseCriticalMultiplier = 1.5f;
|
||||
public float maxCriticalMultiplier = 3.0f;
|
||||
public float levelDamageBonus = 0.1f;
|
||||
|
||||
[Header("Breakthrough Thresholds")]
|
||||
public float weakBreakthroughThreshold = 0.5f;
|
||||
public float mediumBreakthroughThreshold = 0.75f;
|
||||
public float heavyBreakthroughThreshold = 1.0f;
|
||||
|
||||
[Header("Hit Detection")]
|
||||
public float hitstopDuration = 0.05f;
|
||||
public float screenShakeIntensity = 0.1f;
|
||||
|
||||
[Header("Damage Numbers")]
|
||||
public float damageNumberScale = 1.0f;
|
||||
public float criticalScale = 1.5f;
|
||||
public float damageNumberLifetime = 1.0f;
|
||||
}
|
||||
|
||||
public class BattleConfigProvider
|
||||
{
|
||||
public static BattleConfig Config =>
|
||||
Resources.Load<BattleConfig>("Config/BattleConfig");
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.2 改进攻击判定系统
|
||||
**问题**: AttackArea承担了过多职责
|
||||
|
||||
**建议**:
|
||||
```csharp
|
||||
// 攻击配置
|
||||
[CreateAssetMenu(fileName = "AttackConfig", menuName = "Cielonos/Attack/AttackConfig")]
|
||||
public class AttackConfig : ScriptableObject
|
||||
{
|
||||
public LayerMask targetLayers;
|
||||
public float hitboxActiveDuration;
|
||||
public Vector3 hitboxSize;
|
||||
public Vector3 hitboxOffset;
|
||||
public bool useRaycast;
|
||||
public float raycastDistance;
|
||||
}
|
||||
|
||||
// 命中结果
|
||||
public struct HitResult
|
||||
{
|
||||
public ICharacter Target;
|
||||
public Vector3 HitPoint;
|
||||
public Vector3 HitNormal;
|
||||
public bool IsCritical;
|
||||
public float FinalDamage;
|
||||
public DamageType DamageType;
|
||||
}
|
||||
|
||||
// 命中事件
|
||||
public class HitEventArgs : GameEventArgs
|
||||
{
|
||||
public HitResult HitResult { get; set; }
|
||||
public ICharacter Attacker { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 物品系统改进
|
||||
|
||||
#### 4.1 建立物品数据库
|
||||
**问题**: 物品管理分散在各处
|
||||
|
||||
**建议**:
|
||||
```csharp
|
||||
[CreateAssetMenu(fileName = "ItemDatabase", menuName = "Cielonos/Items/Database")]
|
||||
public class ItemDatabase : ScriptableObject
|
||||
{
|
||||
[SerializeField] private List<WeaponData> weapons = new List<WeaponData>();
|
||||
[SerializeField] private List<ArmorData> armors = new List<ArmorData>();
|
||||
[SerializeField] private List<ConsumableData> consumables = new List<ConsumableData>>();
|
||||
|
||||
public WeaponData GetWeapon(string id) => weapons.FirstOrDefault(w => w.Id == id);
|
||||
public T GetItem<T>(string id) where T : ItemData
|
||||
{
|
||||
var field = typeof(ItemDatabase).GetField(typeof(T).Name.ToLower() + "s",
|
||||
BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
var list = field?.GetValue(this) as IEnumerable<ItemData>;
|
||||
return list?.FirstOrDefault(i => i.Id == id) as T;
|
||||
}
|
||||
}
|
||||
|
||||
// 物品生成器
|
||||
public static class ItemFactory
|
||||
{
|
||||
public static IItem Create(ItemData data, int level = 1)
|
||||
{
|
||||
return data switch
|
||||
{
|
||||
WeaponData weaponData => CreateWeapon(weaponData, level),
|
||||
ArmorData armorData => CreateArmor(armorData, level),
|
||||
ConsumableData consumableData => CreateConsumable(consumableData),
|
||||
_ => throw new ArgumentException($"Unknown item type: {data.GetType()}")
|
||||
};
|
||||
}
|
||||
|
||||
private static Weapon CreateWeapon(WeaponData data, int level)
|
||||
{
|
||||
var weapon = new Weapon();
|
||||
weapon.Initialize(data, level);
|
||||
return weapon;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. AI系统改进
|
||||
|
||||
#### 5.1 建立AI配置系统
|
||||
**问题**: AI行为硬编码,缺乏配置化
|
||||
|
||||
**建议**:
|
||||
```csharp
|
||||
[CreateAssetMenu(fileName = "AIConfig", menuName = "Cielonos/AI/AIConfig")]
|
||||
public class AIConfig : ScriptableObject
|
||||
{
|
||||
[Header("Detection")]
|
||||
public float detectionRange = 10f;
|
||||
public float attackRange = 2f;
|
||||
public float loseInterestRange = 20f;
|
||||
|
||||
[Header("Movement")]
|
||||
public float preferredDistance = 5f;
|
||||
public float strafeSpeed = 2f;
|
||||
|
||||
[Header("Decision Making")]
|
||||
public float decisionInterval = 0.5f;
|
||||
public float healthThresholdForRetreat = 0.3f;
|
||||
public float energyThresholdForSpecial = 0.7f;
|
||||
|
||||
[Header("Behavior Weights")]
|
||||
public float attackWeight = 1.0f;
|
||||
public float defendWeight = 0.5f;
|
||||
public float retreatWeight = 0.3f;
|
||||
public float supportWeight = 0.4f;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class BehaviorState
|
||||
{
|
||||
public string stateName;
|
||||
public BehaviorTree tree;
|
||||
public List<Transition> transitions = new List<Transition>();
|
||||
public float enterDelay;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Transition
|
||||
{
|
||||
public string targetState;
|
||||
public List<Condition> conditions = new List<Condition>();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public abstract class Condition
|
||||
{
|
||||
public abstract bool Evaluate(IAIController controller);
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 数据持久化改进
|
||||
|
||||
#### 6.1 建立游戏存档系统
|
||||
**问题**: 缺乏统一的存档管理
|
||||
|
||||
**建议**:
|
||||
```csharp
|
||||
[System.Serializable]
|
||||
public class GameSaveData
|
||||
{
|
||||
public string saveId;
|
||||
public DateTime saveTime;
|
||||
public int playerLevel;
|
||||
public Vector3 playerPosition;
|
||||
public List<ItemSaveData> inventory;
|
||||
public List<string> unlockedAbilities;
|
||||
public int currentZoneIndex;
|
||||
public int currentScore;
|
||||
public List<AchievementSaveData> achievements;
|
||||
}
|
||||
|
||||
public interface ISaveSystem
|
||||
{
|
||||
void Save(GameSaveData data);
|
||||
GameSaveData Load(string saveId);
|
||||
List<string> GetAllSaves();
|
||||
void DeleteSave(string saveId);
|
||||
}
|
||||
|
||||
public class EasySaveAdapter : ISaveSystem
|
||||
{
|
||||
public void Save(GameSaveData data)
|
||||
{
|
||||
ES3.Save("save_" + data.saveId, data);
|
||||
}
|
||||
|
||||
public GameSaveData Load(string saveId)
|
||||
{
|
||||
return ES3.Load<GameSaveData>("save_" + saveId);
|
||||
}
|
||||
|
||||
public List<string> GetAllSaves()
|
||||
{
|
||||
// 实现保存文件列表获取
|
||||
}
|
||||
|
||||
public void DeleteSave(string saveId)
|
||||
{
|
||||
ES3.DeleteKey("save_" + saveId);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7. UI系统改进
|
||||
|
||||
#### 7.1 建立UI框架
|
||||
**问题**: UI组件耦合度高,难以复用
|
||||
|
||||
**建议**:
|
||||
```csharp
|
||||
public abstract class UIScreen : MonoBehaviour
|
||||
{
|
||||
protected bool isVisible;
|
||||
|
||||
public virtual void Show()
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
OnShow();
|
||||
isVisible = true;
|
||||
}
|
||||
|
||||
public virtual void Hide()
|
||||
{
|
||||
OnHide();
|
||||
gameObject.SetActive(false);
|
||||
isVisible = false;
|
||||
}
|
||||
|
||||
protected abstract void OnShow();
|
||||
protected abstract void OnHide();
|
||||
}
|
||||
|
||||
public class UIManager
|
||||
{
|
||||
private Stack<UIScreen> screenStack = new Stack<UIScreen>();
|
||||
|
||||
public void ShowScreen<T>() where T : UIScreen
|
||||
{
|
||||
var screen = GetScreen<T>();
|
||||
if (screen != null)
|
||||
{
|
||||
screen.Show();
|
||||
screenStack.Push(screen);
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseCurrentScreen()
|
||||
{
|
||||
if (screenStack.Count > 0)
|
||||
{
|
||||
var screen = screenStack.Pop();
|
||||
screen.Hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8. 代码规范与工具
|
||||
|
||||
#### 8.1 增加代码注释
|
||||
**建议**: 在关键类和方法添加XML文档注释
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// 伤害信息结构体,包含所有与伤害计算相关的参数
|
||||
/// </summary>
|
||||
public struct DamageInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 伤害来源
|
||||
/// </summary>
|
||||
public IDamageSource Source;
|
||||
|
||||
/// <summary>
|
||||
/// 伤害值基数
|
||||
/// </summary>
|
||||
public float BaseDamage;
|
||||
|
||||
/// <summary>
|
||||
/// 伤害类型
|
||||
/// </summary>
|
||||
public DamageType Type;
|
||||
}
|
||||
```
|
||||
|
||||
#### 8.2 建立自定义编辑器工具
|
||||
**建议**: 为复杂系统创建编辑器窗口
|
||||
```csharp
|
||||
#if UNITY_EDITOR
|
||||
public class CharacterEditorWindow : EditorWindow
|
||||
{
|
||||
[MenuItem("Cielonos/Character Editor")]
|
||||
public static void OpenWindow()
|
||||
{
|
||||
GetWindow<CharacterEditorWindow>("Character Editor");
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
// 创建角色编辑器UI
|
||||
}
|
||||
}
|
||||
|
||||
public class BuffEditorWindow : EditorWindow
|
||||
{
|
||||
[MenuItem("Cielonos/Buff Editor")]
|
||||
public static void OpenWindow()
|
||||
{
|
||||
GetWindow<BuffEditorWindow>("Buff Editor");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、改进优先级
|
||||
|
||||
### P0 - 必须改进(阻塞性问题)
|
||||
1. 建立核心接口层
|
||||
2. 改进属性系统类型安全
|
||||
3. 建立消息总线
|
||||
|
||||
### P1 - 重要改进(核心功能)
|
||||
1. 拆分CharacterBase
|
||||
2. 建立战斗配置系统
|
||||
3. 建立物品数据库
|
||||
4. 建立AI配置系统
|
||||
|
||||
### P2 - 优化改进(提升开发效率)
|
||||
1. 建立存档系统
|
||||
2. 建立UI框架
|
||||
3. 增加代码注释
|
||||
4. 创建编辑器工具
|
||||
|
||||
### P3 - 长期改进(架构优化)
|
||||
1. 服务定位器模式
|
||||
2. 组件化重构
|
||||
3. 配置化完善
|
||||
|
||||
---
|
||||
|
||||
## 四、总结
|
||||
|
||||
当前项目在架构上已经奠定了良好的基础,核心系统基本完备。要构建完善的Roguelike ARPG框架,重点需要:
|
||||
|
||||
1. **抽象接口层**: 建立清晰的接口边界,提高系统可测试性和可替换性
|
||||
2. **配置驱动**: 将硬编码转为配置化,提高设计迭代效率
|
||||
3. **数据管理**: 建立统一的数据管理系统,包括物品、敌人、AI等
|
||||
4. **代码规范**: 增加注释和文档,提高代码可维护性
|
||||
5. **工具支持**: 开发自定义编辑器工具,提高开发效率
|
||||
|
||||
---
|
||||
|
||||
*文档生成日期: 2026-04-17*
|
||||
*生成者: Game Designer Agent*
|
||||
Reference in New Issue
Block a user