自定义盔甲
自定义盔甲属于特殊的自定义物品,在支持自定义物品所有特性的基础上,还具有盔甲相关的防御功能。本文将详细介绍如何通过 custom_item_type: "armor" 和 netease:armor 组件来创建头盔、胸甲、护腿和靴子,包括模型贴图绑定与 attachable 配置。
前置条件
请先阅读 自定义基础物品 了解物品注册的基础流程(步骤 1-6)。盔甲注册需要额外配置 attachables 目录和几何模型。format_version 使用 1.10(物品 JSON)和 1.8.0(attachable JSON)。
概述
自定义盔甲的核心要求:
- 在行为包的物品 JSON 中,将
description.custom_item_type设为"armor" - 在
components中添加netease:armor组件,指定防御值、槽位等属性 - 在资源包中配置
attachables目录下的 JSON 文件,定义盔甲穿戴后的模型与贴图渲染
与基础物品不同,盔甲的默认 category 为 Equipment,会自动归类到创造背包的装备分页。盔甲支持 ModAPI 中与物品相关的所有事件及接口,同时还支持盔甲专属的 Python 事件(如 OnNewArmorExchangeServerEvent)和 armorSlot 组件。
注册流程
盔甲的注册在基础物品的 1-6 步基础上进行扩展:
- 步骤 1-6:与 自定义基础物品 注册流程完全相同(创建行为包/资源包 JSON、贴图、本地化等)
- 设置 custom_item_type:在行为包 JSON 的
description中添加"custom_item_type": "armor" - 添加 netease:armor 组件:在
components中配置防御值、盔甲槽位等参数 - 添加盔甲模型贴图:将盔甲穿戴贴图放入资源包的
textures/models目录 - 创建 attachable 文件:在资源包的
attachables目录下创建 JSON 描述文件,配置模型、贴图和渲染方式 - 创建几何模型(可选):若需要自定义外形,在
resource/models/entity下添加几何模型文件
行为包 JSON 配置
在 behavior/netease_items_beh 目录下创建物品 JSON:
{
"format_version": "1.10",
"minecraft:item": {
"description": {
"identifier": "mymod:ruby_helmet",
"custom_item_type": "armor"
},
"components": {
"netease:armor": {
"defense": 3,
"enchantment": 10,
"armor_slot": 0,
"toughness": 2,
"knockback_resistance": 0.0
}
}
}
}资源包 JSON 配置
在 resource/netease_items_res 目录下创建对应的资源 JSON:
{
"format_version": "1.10",
"minecraft:item": {
"description": {
"identifier": "mymod:ruby_helmet",
"category": "Equipment"
},
"components": {
"minecraft:icon": "mymod:ruby_helmet"
}
}
}同时在 textures/item_texture.json 中添加物品图标的贴图映射,在 texts/zh_CN.lang 中添加本地化条目:
item.mymod:ruby_helmet.name=红宝石头盔netease:armor 组件详解
netease:armor 是盔甲的核心行为包组件,定义了盔甲的所有防御属性。
| 键 | 类型 | 默认值 | 说明 |
|---|---|---|---|
defense | int | 0 | 盔甲的防御值(护甲点数),决定伤害减免比例 |
enchantment | int | 0 | 盔甲的附魔能力值,数值越高越容易获得高级附魔 |
armor_slot | int | — | 盔甲槽位,决定穿戴位置。参见 ArmorSlotType 枚举 |
toughness | int | 0 | 盔甲韧性,范围 0~20。韧性越高,面对高伤害时防御效果越稳定 |
knockback_resistance | float | 0.0 | 击退抗性,范围 0~1。穿戴下界合金盔甲时每件提供 0.1 |
ArmorSlotType 枚举
盔甲槽位由 armor_slot 字段指定,对应 mod.common.minecraftEnum.ArmorSlotType:
| 枚举值 | 数值 | 说明 |
|---|---|---|
HEAD | 0 | 头盔 |
BODY | 1 | 胸甲 |
LEG | 2 | 护腿 |
FOOT | 3 | 靴子 |
示例——定义一件胸甲:
"netease:armor": {
"defense": 8,
"enchantment": 10,
"armor_slot": 1,
"toughness": 2,
"knockback_resistance": 0.0
}护甲值与韧性
防御值(defense)
defense 表示该盔甲件提供的护甲点数。玩家穿戴所有盔甲后的总护甲点数上限为 20。
原版盔甲的防御值参考:
| 材质 | 头盔 | 胸甲 | 护腿 | 靴子 | 总计 |
|---|---|---|---|---|---|
| 皮革 | 1 | 3 | 2 | 1 | 7 |
| 锁链 | 2 | 5 | 4 | 1 | 12 |
| 铁 | 2 | 6 | 5 | 2 | 15 |
| 钻石 | 3 | 8 | 6 | 3 | 20 |
| 下界合金 | 3 | 8 | 6 | 3 | 20 |
伤害减免公式
基岩版的伤害减免计算公式如下:
实际伤害 = 原始伤害 × (1 - min(20, max(defense / 5, defense - 4 × 原始伤害 / (toughness + 8))) / 25)- 当
toughness为 0 时,高伤害攻击会显著降低护甲的减伤效果 - 韧性越高,护甲在面对高伤害时越"坚韧",减伤比例越稳定
击退抗性(knockback_resistance)
knockback_resistance 减少玩家受到攻击时的击退距离。每件下界合金盔甲提供 0.1 的击退抗性,穿满一套为 0.4(减少 40% 击退距离)。
盔甲渲染(Attachables)
盔甲物品注册完成后,仅能在背包中显示图标并穿戴到对应槽位,但穿戴后不会在玩家身上显示模型。要让盔甲在玩家身上可见,需要在资源包中配置 attachable 文件。
目录结构
resource/
├── attachables/
│ └── ruby_helmet.json # attachable 描述文件
├── models/
│ └── entity/
│ └── ruby_helmet.geo.json # 自定义几何模型(可选)
└── textures/
└── models/
└── armor/
└── ruby_main.png # 盔甲穿戴贴图attachable JSON 配置
attachable 文件是盔甲渲染的核心,使用 format_version: "1.8.0" 格式。以下是一个完整的头盔 attachable 配置:
{
"format_version": "1.8.0",
"minecraft:attachable": {
"description": {
"identifier": "mymod:ruby_helmet",
"materials": {
"default": "armor",
"enchanted": "armor_enchanted"
},
"textures": {
"default": "textures/models/armor/ruby_main",
"enchanted": "textures/misc/enchanted_item_glint"
},
"geometry": {
"default": "geometry.humanoid.armor.helmet"
},
"scripts": {
"parent_setup": "variable.helmet_layer_visible = 0.0;"
},
"render_controllers": [
"controller.render.armor"
]
}
}
}各字段说明:
| 键 | 类型 | 说明 |
|---|---|---|
identifier | str | 必须与行为包物品 JSON 中的 identifier 完全一致 |
materials/default | str | 材质,通常为 "armor" |
materials/enchanted | str | 附魔材质,固定为 "armor_enchanted" |
textures/default | str | 盔甲穿戴贴图路径(不含扩展名) |
textures/enchanted | str | 附魔光效贴图,固定为 "textures/misc/enchanted_item_glint" |
geometry/default | str | 几何模型标识符,可使用预设模型或自定义模型 |
scripts/parent_setup | str | 控制玩家皮肤层显隐,避免穿模 |
render_controllers | array | 渲染控制器,通常为 ["controller.render.armor"] |
预设几何模型
游戏内置了四种盔甲预设几何模型,可直接使用:
| 几何标识符 | 对应部位 |
|---|---|
geometry.humanoid.armor.helmet | 头盔 |
geometry.humanoid.armor.chestplate | 胸甲 |
geometry.humanoid.armor.leggings | 护腿 |
geometry.humanoid.armor.boots | 靴子 |
贴图说明
盔甲穿戴贴图(放在 textures/models/armor/ 下)与物品图标贴图(放在 textures/items/ 下)是两套不同的贴图。穿戴贴图应参考原版盔甲贴图的 UV 布局,头盔和胸甲通常使用同一张贴图(如 ruby_main.png),护腿单独一张(如 ruby_legs.png)。
parent_setup 皮肤层控制
为避免玩家皮肤外层(第二层 skin layer)与盔甲模型发生穿模,游戏使用了 4 个变量来控制皮肤外层的显隐。在 scripts/parent_setup 中将对应变量设为 0.0 即可隐藏该部位的皮肤外层。
| 变量名 | 控制部位 | 适用盔甲类型 |
|---|---|---|
variable.helmet_layer_visible | 玩家头部皮肤外层 | 头盔 |
variable.chest_layer_visible | 玩家上半身皮肤外层 | 胸甲 |
variable.leg_layer_visible | 玩家腿部皮肤外层 | 护腿 |
variable.boot_layer_visible | 玩家脚部皮肤外层 | 靴子 |
各部位的 parent_setup 写法:
// 头盔
"parent_setup": "variable.helmet_layer_visible = 0.0;"
// 胸甲
"parent_setup": "variable.chest_layer_visible = 0.0;"
// 护腿
"parent_setup": "variable.leg_layer_visible = 0.0;"
// 靴子
"parent_setup": "variable.boot_layer_visible = 0.0;"也可使用简写 v. 代替 variable.:
"parent_setup": "v.helmet_layer_visible = 0.0;"TIP
如果不设置 parent_setup,穿戴盔甲时皮肤外层仍会渲染,可能导致盔甲模型与皮肤发生重叠闪烁。
盔甲材质与自定义模型
使用预设模型
对于外形与原版盔甲一致的自定义盔甲,直接在 attachable 的 geometry/default 中引用预设模型即可,只需替换贴图。
使用自定义几何模型
若需要独特的盔甲外形(如带翅膀的头盔、带披风的胸甲),可以创建自定义几何模型:
- 使用 Blockbench 创建模型,选择 Bedrock Entity Model 类型
- 骨骼名称必须与原版盔甲骨骼对应(如头盔的骨骼名为
head,胸甲为body等) - 导出为 JSON 格式,放入
resource/models/entity/目录
自定义头盔几何模型示例:
{
"geometry.mymod_ruby_helmet": {
"texturewidth": 64,
"textureheight": 32,
"visible_bounds_width": 2,
"visible_bounds_height": 2,
"visible_bounds_offset": [0, 1, 0],
"bones": [
{
"name": "head",
"parent": null,
"pivot": [0.0, 24.0, 0.0],
"cubes": [
{
"origin": [-4, 24, -4],
"size": [8, 8, 8],
"uv": [0, 0],
"inflate": 1.0
},
{
"origin": [4, 30, -1],
"size": [2, 2, 2],
"uv": [47, 0]
},
{
"origin": [-6, 30, -1],
"size": [2, 2, 2],
"uv": [47, 0]
}
]
}
]
}
}使用自定义模型时,attachable 中的 geometry/default 改为自定义标识符:
"geometry": {
"default": "geometry.mymod_ruby_helmet"
}模型制作建议
- 盔甲模型的基础参考文件为
data/resource_packs/vanilla/models目录下的mobs.json中的geometry.humanoid - 推荐使用 Blockbench 制作模型,导出的 JSON 格式与要求格式接近
- 导出后按照装备物品 Demo 的 JSON 样式进行调整,尽量保持字段顺序一致
- 如果 Cube 之间有重叠的面,重叠部分可能无法显示或出现闪烁;可通过调整
inflate值(可为负数)来避免穿模。inflate使 Cube 向各方向膨胀指定数值,不影响贴图坐标 - 通常头盔模型的
inflate设为1.0左右,避免与头部模型完全重叠
注意
对于溺尸实体,不能使用已废弃的 SetArmorNew 接口装备自定义盔甲,该操作会导致游戏闪退。
附魔兼容
netease:armor 组件中的 enchantment 字段决定了盔甲的附魔能力值(Enchantability)。该值影响在附魔台上附魔时获得高等级附魔的概率。
数值越高,越容易获得多个高等级附魔。原版盔甲的附魔能力值参考:
| 材质 | 附魔能力值 |
|---|---|
| 皮革 | 15 |
| 锁链 | 12 |
| 铁 | 9 |
| 钻石 | 10 |
| 下界合金 | 15 |
| 金 | 25 |
盔甲类型的物品在附魔台上只能获得盔甲类附魔(保护、火焰保护、摔落保护、弹射物保护等),具体可获得的附魔类型由 armor_slot 决定:
- 头盔(HEAD):可获得水下呼吸、水下速掘等专属附魔
- 靴子(FOOT):可获得摔落保护、深海探索者、冰霜行者等专属附魔
套装效果(脚本实现)
游戏本身不内置"套装效果"机制,但可以通过 Python 脚本检测玩家是否穿戴了完整的一套自定义盔甲,并据此施加特殊效果。
实现思路
- 监听
OnNewArmorExchangeServerEvent事件,每当玩家更换盔甲时触发 - 使用
armorSlot组件或GetEntityItem接口检查玩家四个盔甲槽位 - 若四件均为同一套盔甲,则给予 buff 效果;否则移除
示例代码
# -*- coding: utf-8 -*-
import server.extraServerApi as serverApi
ServerSystem = serverApi.GetServerSystemCls()
compFactory = serverApi.GetEngineCompFactory()
class ArmorSetServer(ServerSystem):
def __init__(self, namespace, systemName):
ServerSystem.__init__(self, namespace, systemName)
self.ListenForEvent(
serverApi.EngineNamespace,
serverApi.EngineSystemName,
'OnNewArmorExchangeServerEvent',
self,
self.OnArmorChange
)
def OnArmorChange(self, args):
playerId = args['playerId']
self.CheckArmorSet(playerId)
def CheckArmorSet(self, playerId):
"""检测玩家是否穿戴完整的红宝石套装"""
itemComp = compFactory.CreateItem(playerId)
setItems = [
'mymod:ruby_helmet',
'mymod:ruby_chestplate',
'mymod:ruby_leggings',
'mymod:ruby_boots'
]
# 检查四个盔甲槽位(0=头盔, 1=胸甲, 2=护腿, 3=靴子)
fullSet = True
for slot in range(4):
armorItem = itemComp.GetArmorItem(slot)
if not armorItem or armorItem.get('itemName') != setItems[slot]:
fullSet = False
break
effectComp = compFactory.CreateEffect(playerId)
if fullSet:
# 穿戴完整套装:给予抗性提升 II 效果(持续999999秒)
effectComp.AddEffectToEntity('resistance', 999999, 1)
effectComp.AddEffectToEntity('fire_resistance', 999999, 0)
else:
# 不完整:移除套装效果
effectComp.RemoveEffectFromEntity('resistance')
effectComp.RemoveEffectFromEntity('fire_resistance')TIP
上述代码监听 OnNewArmorExchangeServerEvent 事件即可覆盖玩家穿上/脱下盔甲的所有场景。该事件在盔甲槽位发生变化时触发。
完整示例
以下是一个完整的自定义头盔(红宝石头盔)的所有文件配置。
行为包物品 JSON
{
"format_version": "1.10",
"minecraft:item": {
"description": {
"identifier": "mymod:ruby_helmet",
"custom_item_type": "armor"
},
"components": {
"netease:armor": {
"defense": 3,
"enchantment": 10,
"armor_slot": 0,
"toughness": 2,
"knockback_resistance": 0.0
}
}
}
}资源包物品 JSON
{
"format_version": "1.10",
"minecraft:item": {
"description": {
"identifier": "mymod:ruby_helmet",
"category": "Equipment"
},
"components": {
"minecraft:icon": "mymod:ruby_helmet"
}
}
}Attachable JSON
{
"format_version": "1.8.0",
"minecraft:attachable": {
"description": {
"identifier": "mymod:ruby_helmet",
"materials": {
"default": "armor",
"enchanted": "armor_enchanted"
},
"textures": {
"default": "textures/models/armor/ruby_main",
"enchanted": "textures/misc/enchanted_item_glint"
},
"geometry": {
"default": "geometry.humanoid.armor.helmet"
},
"scripts": {
"parent_setup": "variable.helmet_layer_visible = 0.0;"
},
"render_controllers": [
"controller.render.armor"
]
}
}
}自定义几何模型(可选)
如果使用自定义模型替代预设的 geometry.humanoid.armor.helmet:
{
"geometry.mymod_ruby_helmet": {
"texturewidth": 64,
"textureheight": 32,
"visible_bounds_width": 2,
"visible_bounds_height": 2,
"visible_bounds_offset": [0, 1, 0],
"bones": [
{
"name": "head",
"parent": null,
"pivot": [0.0, 24.0, 0.0],
"cubes": [
{
"origin": [-4, 24, -4],
"size": [8, 8, 8],
"uv": [0, 0],
"inflate": 1.0
},
{
"origin": [4, 30, -1],
"size": [2, 2, 2],
"uv": [47, 0]
},
{
"origin": [-6, 30, -1],
"size": [2, 2, 2],
"uv": [47, 0]
},
{
"origin": [6, 31, -1],
"size": [2, 2, 2],
"uv": [42, 8]
},
{
"origin": [-8, 31, -1],
"size": [2, 2, 2],
"uv": [42, 8]
},
{
"origin": [8, 32, -1],
"size": [2, 4, 2],
"uv": [41, 0]
},
{
"origin": [-10, 32, -1],
"size": [2, 4, 2],
"uv": [41, 0]
},
{
"origin": [-8, 36, -1],
"size": [16, 2, 2],
"uv": [28, 28]
}
]
}
]
}
}此时 attachable 中需修改 geometry 引用:
"geometry": {
"default": "geometry.mymod_ruby_helmet"
}本地化
item.mymod:ruby_helmet.name=红宝石头盔物品图标贴图
在 resource/textures/item_texture.json 中注册物品图标:
{
"resource_pack_name": "mymod",
"texture_data": {
"mymod:ruby_helmet": {
"textures": "textures/items/ruby_helmet"
}
}
}将物品图标文件放在 resource/textures/items/ruby_helmet.png,穿戴贴图放在 resource/textures/models/armor/ruby_main.png。
常见问题
穿戴后模型不显示
- 确认
resource/attachables/目录下存在与物品identifier同名的 JSON 文件 - 确认 attachable JSON 中的
identifier与行为包物品 JSON 中的identifier完全一致(包括命名空间) - 确认
geometry/default引用的几何模型标识符正确存在
贴图显示为紫黑色方块
- 检查
textures/default路径是否正确,路径不含.png扩展名 - 确认贴图文件实际存在于
resource/textures/models/armor/目录下 - 贴图尺寸应为 2 的幂次方(如 64x32、128x64)
盔甲穿戴到错误槽位
- 检查
netease:armor组件中的armor_slot值是否正确(0=头盔, 1=胸甲, 2=护腿, 3=靴子) armor_slot必须为整数类型,不能使用字符串
盔甲与皮肤穿模闪烁
- 在 attachable 的
scripts/parent_setup中设置对应部位的variable.*_layer_visible = 0.0 - 如果自定义模型 Cube 之间有重叠,调整
inflate值(可为负数)来解决
附魔光效不显示
- 确认
materials中包含"enchanted": "armor_enchanted" - 确认
textures中包含"enchanted": "textures/misc/enchanted_item_glint" - 两者缺一不可
自定义模型骨骼不跟随玩家动作
- 骨骼的
name必须与原版盔甲骨骼名称对应:头盔为head,胸甲为body,护腿为leftLeg/rightLeg,靴子为leftLeg/rightLeg pivot坐标需与原版骨骼一致
