Files
Cielonos/docs/架构改进建议.md
2026-04-18 13:57:19 -04:00

671 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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*