# 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 services = new Dictionary(); public static void Register(T service) where T : class { services[typeof(T)] = service; } public static T Get() 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(this); GameServices.Register(new CharacterService()); GameServices.Register(new BuffService()); } } // 在其他类中使用 var battleService = GameServices.Get(); ``` #### 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> eventHandlers = new Dictionary>(); public static void Subscribe(GameEvent eventType, Action handler) { if (!eventHandlers.ContainsKey(eventType)) { eventHandlers[eventType] = handler; } else { eventHandlers[eventType] += handler; } } public static void Unsubscribe(GameEvent eventType, Action 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 Data { get; set; } = new Dictionary(); } ``` ### 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 availableBuffs; } // 角色配置器 public class CharacterBuilder { private CharacterData data; private List components = new List(); public CharacterBuilder SetData(CharacterData data) { ... } public CharacterBuilder AddComponent() 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 modifiers = new List(); 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("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 weapons = new List(); [SerializeField] private List armors = new List(); [SerializeField] private List consumables = new List>(); public WeaponData GetWeapon(string id) => weapons.FirstOrDefault(w => w.Id == id); public T GetItem(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; 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 transitions = new List(); public float enterDelay; } [Serializable] public class Transition { public string targetState; public List conditions = new List(); } [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 inventory; public List unlockedAbilities; public int currentZoneIndex; public int currentScore; public List achievements; } public interface ISaveSystem { void Save(GameSaveData data); GameSaveData Load(string saveId); List 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("save_" + saveId); } public List 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 screenStack = new Stack(); public void ShowScreen() where T : UIScreen { var screen = GetScreen(); 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 /// /// 伤害信息结构体,包含所有与伤害计算相关的参数 /// public struct DamageInfo { /// /// 伤害来源 /// public IDamageSource Source; /// /// 伤害值基数 /// public float BaseDamage; /// /// 伤害类型 /// public DamageType Type; } ``` #### 8.2 建立自定义编辑器工具 **建议**: 为复杂系统创建编辑器窗口 ```csharp #if UNITY_EDITOR public class CharacterEditorWindow : EditorWindow { [MenuItem("Cielonos/Character Editor")] public static void OpenWindow() { GetWindow("Character Editor"); } private void OnGUI() { // 创建角色编辑器UI } } public class BuffEditorWindow : EditorWindow { [MenuItem("Cielonos/Buff Editor")] public static void OpenWindow() { GetWindow("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*