50行代码实现魔兽级属性系统:ET数值组件设计解密

50行代码实现魔兽级属性系统:ET数值组件设计解密

【免费下载链接】ET Unity3D 客户端和 C# 服务器框架。 【免费下载链接】ET 项目地址: https://gitcode.com/GitHub_Trending/et/ET

你还在为角色属性系统臃肿不堪而烦恼?传统OOP设计让每个职业都需要单独的数值类,新增属性要改十几个文件?本文将带你拆解ET框架的KeyValue数值设计方案,用不到50行核心代码实现可无限扩展的复杂属性系统,彻底解决MMO/RPG游戏开发中的数值管理难题。

读完本文你将掌握:

  • 如何用枚举定义属性类型避免魔法值
  • KeyValue结构如何支撑5层数值叠加计算
  • 一行代码实现属性变化事件监听
  • 跨职业/种族的数值系统通用方案

传统数值设计的3大痛点

普通游戏开发中,我们习惯用这样的类定义角色属性:

class Numeric {
    public int Speed;
    public int SpeedInit;
    public int SpeedAdd;
    public int SpeedPct;
    // ... 其他30+属性
}

这种设计在《魔兽世界》级别的复杂游戏中会迅速崩溃:

痛点1:职业差异化导致类爆炸

法师需要Mp属性,盗贼需要Energy属性,10个职业就会衍生出10个数值子类。当新增"怒气值"系统时,所有近战职业的数值类都要修改。

痛点2:属性计算逻辑重复

每种属性都需要类似Speed = (SpeedInit + SpeedAdd) * (100 + SpeedPct) / 100的计算代码,30种属性就要写30遍重复逻辑。

痛点3:Buff系统难以维护

给角色添加"增加20%移动速度"的Buff时,需要专门编写代码找到SpeedPct字段并修改,新增Buff类型就要新增处理逻辑。

ET的KeyValue设计革命

ET框架采用枚举+字典的创新结构,彻底解决了传统设计的痛点。核心代码位于Book/5.6数值组件设计.md,让我们逐层拆解实现原理。

1. 枚举定义属性类型体系

ET用NumericType枚举构建了属性的"基因序列",每个主属性派生出5个子属性:

public enum NumericType {
    Speed = 1000,              // 最终速度值
    SpeedBase = Speed * 10 + 1, // 基础值
    SpeedAdd = Speed * 10 + 2,  // 增加值
    SpeedPct = Speed * 10 + 3,  // 百分比增加值
    SpeedFinalAdd = Speed * 10 + 4, // 最终增加值
    SpeedFinalPct = Speed * 10 + 5  // 最终百分比值
}

这种设计让每个属性自动拥有5层计算维度,新增"暴击率"只需添加:

Crit = 1005,
CritBase = Crit * 10 + 1,
// ... 其他4个子属性

2. 字典存储实现动态属性

NumericComponent使用字典存储所有属性值,避免了类字段膨胀:

public class NumericComponent: Component {
    public readonly Dictionary<int, int> NumericDic = new Dictionary<int, int>();
    
    public int this[NumericType numericType] {
        get => GetByKey((int) numericType);
        set {
            NumericDic[(int)numericType] = value;
            Update(numericType); // 自动触发计算
        }
    }
}

法师角色不会存储Energy相关的键值对,盗贼不会存储Mp相关键值,实现了零冗余存储

3. 万能计算公式统一逻辑

通过数学规律将所有属性计算统一为一个公式:

final = (((base + add) * (100 + pct) / 100) + finalAdd) * (100 + finalPct) / 100;

对应代码实现:

public void Update(NumericType numericType) {
    int final = (int) numericType / 10; // 获取主属性ID
    int bas = final * 10 + 1;  // 基础值ID
    int add = final * 10 + 2;  // 增加值ID
    // ... 其他子属性ID
    
    NumericDic[final] = ((GetByKey(bas) + GetByKey(add)) * 
                        (100 + GetByKey(pct)) / 100 + 
                        GetByKey(finalAdd)) * 
                        (100 + GetByKey(finalPct)) / 100;
}

这行代码让所有属性自动支持5层叠加计算,无论是速度、生命值还是魔法值,都遵循同一套计算逻辑。

实战:3步实现Buff系统

基于ET数值组件,给角色添加"增加20%移动速度"的Buff只需3步:

1. 定义Buff配置

在配置表中指定Buff影响的数值类型和值:

{
  "Id": 1001,
  "Name": "疾跑",
  "NumericType": "SpeedPct",
  "Value": 20
}

2. 应用Buff效果

当Buff激活时,直接修改对应子属性:

NumericComponent numeric = unit.GetComponent<NumericComponent>();
numeric[NumericType.SpeedPct] += 20; // 自动触发Update计算

3. 监听属性变化

成就系统通过事件监听属性变化:

[NumericWatcher(NumericType.Hp)]
public class NumericWatcher_Hp : INumericWatcher {
    public void Run(long id, int value) {
        if (value > 1000) {
            // 触发"长寿大师"成就
        }
    }
}

性能对比:传统设计 vs ET设计

指标传统OOP设计ET KeyValue设计
新增属性代码量10+文件修改1行枚举定义
内存占用固定30+字段按需存储
Buff系统复杂度O(n)O(1)
跨职业兼容性需继承扩展天然支持

扩展阅读与资源

掌握这套设计后,无论是《原神》的元素反应系统,还是《英雄联盟》的装备属性叠加,都能通过扩展NumericType枚举轻松实现。下一篇我们将深入探讨如何基于此系统实现技能效果的实时计算,敬请关注。

【免费下载链接】ET Unity3D 客户端和 C# 服务器框架。 【免费下载链接】ET 项目地址: https://gitcode.com/GitHub_Trending/et/ET

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值