实体属性
概述
实体属性(Attribute)是 Minecraft 实体系统的核心组成部分,用于定义和动态控制实体的各项数值特征(如生命值、攻击力、移动速度等)。属性系统由 AttributeMap(属性映射表)、AttributeInstance(属性实例)、AttributeModifier(属性修饰符)等底层结构组成,支持高度可扩展和事件驱动。
适用范围
属性机制与生命周期
- 每个 LivingEntity 拥有 AttributeMap,管理所有 AttributeInstance。
- AttributeInstance 负责属性的基础值、修饰符集合、缓存值,属性变更时 setDirty(),自动刷新缓存并通过 onDirty 回调触发同步。
- 支持持久化(save/load NBT),装备/药水等变更时自动序列化。
- 仅 isClientSyncable() 的属性会同步到客户端。
- 属性变更流程:
- setBaseValue/setModifier → setDirty()
- setDirty() → 缓存失效,onDirty 回调
- onDirty → 属性同步、事件触发
属性修饰符机制
- AttributeModifier 用于动态调整属性值,字段包括:
UUID
:唯一标识,决定叠加/覆盖行为Name
:修饰符名称Amount
:数值,支持正负Operation
:操作符(0=ADDITION,1=MULTIPLY_BASE,2=MULTIPLY_TOTAL)
- 三种 Operation 的叠加顺序与底层计算:
- 伪代码示例:
js
let value = baseValue;
value += sum(additionModifiers);
value *= (1 + sum(multiplyBaseModifiers));
value *= (1 + sum(multiplyTotalModifiers));
value = attribute.sanitizeValue(value);
事件驱动与自动管理
- LivingEntity tick 时自动检测装备、药水、事件等变更,动态添加/移除修饰符。
- 装备切换时,旧装备的修饰符会被移除,新装备的修饰符通过 addTransientAttributeModifiers 自动应用。
- 药水生效/失效时,MobEffectInstance 会自动调用 add/removeAttributeModifiers。
- 属性变更会自动触发同步与缓存刷新,无需手动管理。
典型用法与脚本接口
获取/设置属性基础值
js
const maxHealth = entity.getAttribute('generic.max_health').getBaseValue();
entity.getAttribute('generic.max_health').setBaseValue(30);
添加/移除属性修饰符
js
// 增加最大生命值(如装备特殊护甲时)
entity.modifyAttribute('generic.max_health', 'kubejs:armor_bonus', 8, 'addition');
// 增加移动速度(如获得速度药水时)
entity.modifyAttribute('generic.movement_speed', 'kubejs:speed_potion', 0.2, 'multiply_total');
// 移除修饰符(如脱下装备或药水失效)
entity.removeAttributeModifier('generic.max_health', 'kubejs:armor_bonus');
获取所有修饰符
js
const modifiers = entity.getAttribute('generic.max_health').getModifiers();
modifiers.forEach(mod => {
console.log(mod.id, mod.name, mod.amount, mod.operation);
});
小贴士
- 唯一标识符:每个修饰符应使用唯一字符串(如
kubejs:xxx
),便于后续精确移除和管理。 - 叠加与覆盖:同一属性的不同修饰符可叠加,标识符重复会覆盖。
- 事件驱动:推荐在装备穿戴、药水生效、事件触发等时动态添加/移除修饰符。
- 常见误区:
- 忽略 UUID 唯一性,导致修饰符覆盖或属性异常。
- 直接修改基础值而非用修饰符,导致属性动态性丧失。
- 忽略属性同步,导致客户端显示与实际不符。
如需更深入的底层机制或脚本批量管理示例,可参考 及 KubeJS 官方文档。
修饰符类型与生命周期
在 Minecraft 属性系统中,AttributeModifier(属性修饰符)根据生命周期和持久化方式分为三类:
类型 | 说明 | 生命周期 | 典型场景 |
---|---|---|---|
permanent | 永久修饰符,随实体存档持久化 | 装备、物品等 | 装备加成 |
transient | 临时修饰符,仅内存存在,不持久化 | 事件、Buff等 | 临时增益 |
普通 | 取决于调用方式,既可持久化也可临时 | 混合 | 通用 |
底层机制
permanentModifiers
集合:存储所有永久修饰符,随实体存档持久化(如装备、物品 NBT 修饰符)。transientModifiers
集合:存储所有临时修饰符,仅在内存中存在,适合事件驱动、临时增益。modifierById
:所有当前生效的修饰符(无论类型),以 UUID 为索引,便于查找和覆盖。- 修饰符的添加/移除会自动触发 setDirty(),刷新属性缓存并同步到客户端。
源码伪代码示例
js
// 添加永久修饰符(如装备)
attributeInstance.addPermanentModifier(modifier);
// 添加临时修饰符(如事件Buff)
attributeInstance.addTransientModifier(modifier);
// 获取所有修饰符
attributeInstance.getModifiers(); // 包含所有类型
KubeJS 脚本接口与用法
modifyAttribute
(KubeJS):默认等价于 transient 修饰符,适合事件、临时增益。removeAttributeModifier
:可移除任意类型的修饰符(需指定 UUID/标识符)。- 若需实现永久修饰符,推荐通过装备/物品 AttributeModifiers NBT 或自定义事件持久化管理。
- 典型用法:
js
// 临时增益(事件触发,随事件结束自动移除)
entity.modifyAttribute('generic.attack_damage', 'kubejs:event_buff', 2, 'addition');
// 永久加成(通过装备 NBT 或物品 AttributeModifiers 实现)
const attribute = entity.getAttribute("minecraft:generic.max_health")
attribute.addPermanentModifier(new AttributeModifier('generic.attack_damage', 'kubejs:event_buff', 2, 'addition'))
// 移除修饰符
entity.removeAttributeModifier('generic.attack_damage', 'kubejs:event_buff');
建议
- 唯一标识符:每个修饰符应使用唯一字符串(如
kubejs:xxx
),便于后续精确移除和管理。 - 生命周期选择:临时增益用 transient,永久加成用装备/物品 NBT。
- 批量管理:可封装统一的修饰符管理工具,便于事件驱动和装备切换。
- 常见误区:忽略 UUID 唯一性、混用生命周期、未同步属性等。