Skip to content

自定义远程武器 ​

自定义远程武器由蓄力物品与抛射物实体两部分组成。玩家右键按下时开始蓄力,右键抬起(或蓄力完成后自动发射)时发射抛射物。本文将详细介绍远程武器的行为包配置、蓄力机制、抛射物定义、模型渲染以及完整的自定义弓示例。

前置条件

请先阅读 自定义基础物品,了解物品注册的基础流程(步骤 1-6)。远程武器的 custom_item_type 需设为 ranged_weapon,format_version 使用 1.10。

概述 ​

远程武器的核心工作流程如下:

  1. 在行为包中将物品的 custom_item_type 设为 ranged_weapon,并配置 netease:ranged_weapon 组件
  2. 定义蓄力参数(蓄力时间、蓄力类型、是否自动发射等)
  3. 在行为包中创建一个抛射物实体(netease:custom_entity_type: projectile_entity),定义其飞行物理参数
  4. 在资源包中为抛射物配置客户端实体定义(模型、贴图、动画等)
  5. 可选:通过 netease:render_offsets 调整手持瞄准姿态,通过脚本控制视野(FOV)变化

远程武器与普通蓄力物品的主要区别在于:远程武器内置了发射抛射物的能力,并且在第三人称下会自动播放类似原版弓的抬手瞄准动作。

identifier 命名要求

远程武器物品的 identifier 冒号后部分必须以 bow 结尾(例如 mymod:custom_bow),否则第三人称抬手动作不会正常播放。

行为包物品配置 ​

在 behavior_pack/netease_items_beh/ 目录下创建物品 JSON 文件。远程武器需要设置 custom_item_type 为 ranged_weapon,并添加 netease:ranged_weapon 组件。

json
{
  "format_version": "1.10",
  "minecraft:item": {
    "description": {
      "identifier": "mymod:custom_bow",
      "custom_item_type": "ranged_weapon",
      "category": "equipment"
    },
    "components": {
      "minecraft:max_stack_size": 1,
      "minecraft:max_damage": 385,
      "minecraft:hand_equipped": true,
      "minecraft:use_animation": "bow",
      "minecraft:use_duration": 72000,
      "netease:ranged_weapon": {
        "charge_type": "default",
        "charge_time": 1.0,
        "auto_shoot": false,
        "charge_on_draw": true,
        "projectile": "mymod:custom_arrow",
        "launch_power": 3.0,
        "draw_sound": "bow.pull",
        "shoot_sound": "bow.hit"
      },
      "netease:render_offsets": {
        "controller_position_adjust": [0.0, 0.0, 0.0],
        "controller_rotation_adjust": [0.0, 0.0, 0.0],
        "controller_scale": 1.0
      }
    }
  }
}

netease:ranged_weapon 组件字段 ​

字段类型默认值说明
charge_typestring"default"蓄力类型。"default" 为普通弓蓄力,"crossbow" 为弩式蓄力(蓄满后锁定)
charge_timefloat1.0蓄力满所需时间,单位秒。决定了从开始蓄力到完全蓄满的时长
auto_shootboolfalse蓄满后是否自动发射。为 true 时蓄力完成后立即发射抛射物
charge_on_drawbooltrue右键按下时是否立即开始蓄力。为 true 时按下即蓄力,为 false 时需要额外触发
projectilestring—发射的抛射物实体 identifier(需要在行为包中定义对应实体)
launch_powerfloat3.0抛射物的初始发射速度,值越大飞行速度越快
draw_soundstring""拉弓蓄力时播放的音效
shoot_soundstring""发射时播放的音效

其他常用组件搭配 ​

  • minecraft:use_duration:控制最大蓄力时长(单位 tick),设置为 72000(约 1 小时)即表示可以无限期保持蓄力状态
  • minecraft:use_animation:设为 "bow" 使物品在使用时播放弓的手持动画
  • minecraft:max_damage:耐久度,每次发射消耗 1 点耐久
  • minecraft:hand_equipped:设为 true 让物品在手中以手持武器姿态显示

蓄力机制 ​

蓄力是远程武器的核心特性。当 charge_on_draw 设为 true 时,玩家右键按下即开始蓄力,蓄力进度从 0 线性增长到 1。

蓄力流程 ​

右键按下 → 开始蓄力(进度 0%)→ 持续蓄力中... → 蓄力完成(进度 100%)
                                                          ↓
                            auto_shoot = true?  →  自动发射抛射物
                            auto_shoot = false? →  等待右键抬起后发射

蓄力类型区别 ​

default 类型(普通弓):

  • 右键按下开始蓄力,蓄力进度影响抛射物的发射速度和伤害
  • 右键抬起时根据当前蓄力进度发射,未蓄满也可以发射(但威力较低)
  • 蓄力进度越高,抛射物速度越快、伤害越高

crossbow 类型(弩):

  • 右键按下开始蓄力,蓄满后进入"装填完成"状态
  • 装填完成后可以松开右键,抛射物保持就绪状态
  • 再次右键时才发射抛射物,且始终以满蓄力状态发射

相关事件 ​

蓄力过程中可以通过 Python 脚本监听以下事件:

事件触发时机说明
ItemStartUsingClientEvent右键按下客户端事件,蓄力开始
ItemStartUsingServerEvent右键按下服务端事件,蓄力开始
ItemReleaseUsingClientEvent右键抬起客户端事件,释放蓄力(发射)
ItemReleaseUsingServerEvent右键抬起服务端事件,释放蓄力(发射)
ItemStopUsingClientEvent使用中断客户端事件,非主动释放的中断

蓄力序列帧动画 ​

远程武器在蓄力过程中通常需要显示不同阶段的贴图(例如弓拉开的不同阶段)。通过 netease:frame_animation 组件可以实现蓄力序列帧动画。

在行为包物品 JSON 的 components 中添加:

json
"netease:frame_animation": {
  "frame_count": 3,
  "texture_name": "custom_bow_pulling",
  "animate_in_toolbar": false
}
字段类型说明
frame_countint帧数,蓄力过程中会根据进度在这些帧之间切换
texture_namestring在 item_texture.json 中定义的序列帧贴图资源名
animate_in_toolbarbool是否在快捷栏中也播放序列帧动画

在资源包的 textures/item_texture.json 中配置序列帧贴图数组:

json
{
  "resource_pack_name": "mymod",
  "texture_data": {
    "custom_bow_pulling": {
      "textures": [
        "textures/items/custom_bow_pulling_0",
        "textures/items/custom_bow_pulling_1",
        "textures/items/custom_bow_pulling_2"
      ]
    }
  }
}

蓄力进度与帧的对应关系为:蓄力进度 [0, 1] 区间均匀映射到 [0, frame_count-1] 帧。

抛射物实体定义 ​

抛射物是一种特殊实体,需要在行为包的 entities/ 目录下创建实体 JSON 文件。

json
{
  "format_version": "1.10.0",
  "minecraft:entity": {
    "description": {
      "identifier": "mymod:custom_arrow",
      "is_spawnable": false,
      "is_summonable": true,
      "netease:custom_entity_type": "projectile_entity"
    },
    "components": {
      "netease:projectile": {
        "power": 1.6,
        "gravity": 0.05,
        "uncertainty": 1.0,
        "anchor": 1,
        "damage": 6,
        "is_dangerous": true,
        "knock_back_force": 0.5,
        "particle": "minecraft:critical_hit_emitter",
        "hit_sound": "bow.hit",
        "shoot_sound": "bow.release"
      },
      "netease:pick_up": {
        "item": "mymod:custom_arrow_item"
      },
      "minecraft:collision_box": {
        "width": 0.25,
        "height": 0.25
      },
      "minecraft:physics": {}
    }
  }
}

netease:projectile 组件字段 ​

字段类型默认值说明
powerfloat1.6抛射物基础飞行动力
gravityfloat0.05重力加速度。值越大下坠越快,设为 0 则直线飞行
uncertaintyfloat1.0飞行方向随机偏移量。值越大散布越大
anchorint1发射锚点。0 为脚部,1 为眼部
damageint6基础伤害值
is_dangerousbooltrue是否对实体造成伤害
knock_back_forcefloat0.0击退力度
particlestring""飞行过程中的粒子效果
hit_soundstring""命中时音效
shoot_soundstring""发射时音效

netease:pick_up 组件 ​

配置抛射物落地后是否可以被玩家拾取以及拾取后获得的物品:

json
"netease:pick_up": {
  "item": "mymod:custom_arrow_item"
}

如果不需要拾取功能,可以省略此组件。

抛射物事件 ​

通过 Python 脚本可以监听以下抛射物相关事件:

事件说明
ProjectileDoHitEffectEvent抛射物命中实体或方块时触发
ProjectileCritHitEvent抛射物暴击时触发
EntityDieEvent实体被抛射物击杀时触发

抛射物模型与贴图 ​

抛射物的视觉表现通过资源包中的客户端实体定义文件配置,放置于 resource_pack/entity/ 目录下。

json
{
  "format_version": "1.10.0",
  "minecraft:client_entity": {
    "description": {
      "identifier": "mymod:custom_arrow",
      "materials": {
        "default": "entity_alphatest"
      },
      "textures": {
        "default": "textures/entity/custom_arrow"
      },
      "geometry": {
        "default": "geometry.custom_arrow"
      },
      "animations": {
        "move": "animation.custom_arrow.move"
      },
      "scripts": {
        "animate": ["move"]
      },
      "render_controllers": [
        "controller.render.default"
      ]
    }
  }
}

抛射物朝向动画 ​

抛射物在飞行过程中需要朝向飞行方向。通过动画控制抛射物的旋转:

json
{
  "format_version": "1.8.0",
  "animations": {
    "animation.custom_arrow.move": {
      "loop": true,
      "bones": {
        "body": {
          "rotation": [
            "query.target_x_rotation",
            "query.target_y_rotation",
            0
          ]
        }
      }
    }
  }
}

query.target_x_rotation 和 query.target_y_rotation 会自动返回抛射物当前飞行方向的俯仰角和偏航角,使模型始终面朝飞行方向。

模型制作建议 ​

抛射物模型通常较小(箭、飞镖等),制作时注意:

  • 模型原点应位于抛射物中心
  • 模型前端(飞行方向)朝 Z 轴正方向
  • 建议使用 entity_alphatest 材质以支持透明区域

渲染偏移与视野 ​

渲染偏移(netease:render_offsets) ​

通过 netease:render_offsets 组件可以调整物品在手中的位置、旋转和缩放,使瞄准姿态更加自然:

json
"netease:render_offsets": {
  "controller_position_adjust": [0.0, 0.2, -0.1],
  "controller_rotation_adjust": [0.0, 0.0, -5.0],
  "controller_scale": 1.0
}
字段类型说明
controller_position_adjustarray[3]位置偏移 [x, y, z],单位为方块
controller_rotation_adjustarray[3]旋转偏移 [rx, ry, rz],单位为度
controller_scalefloat缩放倍率

视野变化(FOV) ​

原版弓在蓄力时会有视野缩小(拉近)的效果。自定义远程武器可以通过 Python 脚本中的 Camera 组件实现类似效果:

python
import mod.client.extraClientApi as clientApi

comp = clientApi.GetEngineCompFactory().CreateCamera(playerId)
# 蓄力过程中逐渐缩小 FOV
comp.SetFov(60.0)  # 默认 FOV 约为 70

# 发射后恢复
comp.SetFov(70.0)

建议在 ItemStartUsingClientEvent 中开始渐变缩小 FOV,在 ItemReleaseUsingClientEvent 中恢复默认 FOV。

脚本发射抛射物 ​

除了通过 netease:ranged_weapon 组件自动发射外,也可以通过 Python 脚本手动创建并发射抛射物:

python
import mod.server.extraServerApi as serverApi

comp = serverApi.GetEngineCompFactory().CreateProjectile(playerId)
param = {
    "position": (x, y, z),
    "direction": (dx, dy, dz),
    "power": 2.0,
    "gravity": 0.05,
    "damage": 8,
    "targetId": ""
}
projectileId = comp.CreateProjectileEntity(playerId, "mymod:custom_arrow", param)

脚本发射方式更加灵活,可以实现散射、追踪、延迟发射等高级效果。

完整示例 ​

以下是一个完整的自定义弓示例,包含所有必要的 JSON 配置文件。

文件结构 ​

behavior_pack/
├── netease_items_beh/
│   └── custom_bow.json          # 物品行为定义
├── entities/
│   └── custom_arrow.json        # 抛射物实体定义
resource_pack/
├── netease_items_res/
│   └── custom_bow.json          # 物品资源定义
├── textures/
│   ├── items/
│   │   ├── custom_bow.png           # 默认贴图
│   │   ├── custom_bow_pulling_0.png # 蓄力帧 0
│   │   ├── custom_bow_pulling_1.png # 蓄力帧 1
│   │   └── custom_bow_pulling_2.png # 蓄力帧 2
│   ├── item_texture.json
│   └── entity/
│       └── custom_arrow.png     # 抛射物贴图
├── entity/
│   └── custom_arrow.entity.json # 抛射物客户端实体
├── models/entity/
│   └── custom_arrow.geo.json    # 抛射物模型
├── animations/
│   └── custom_arrow.animation.json # 抛射物动画
└── texts/
    └── zh_CN.lang

1. 行为包 - 物品定义 ​

behavior_pack/netease_items_beh/custom_bow.json:

json
{
  "format_version": "1.10",
  "minecraft:item": {
    "description": {
      "identifier": "mymod:custom_bow",
      "custom_item_type": "ranged_weapon",
      "category": "equipment"
    },
    "components": {
      "minecraft:max_stack_size": 1,
      "minecraft:max_damage": 500,
      "minecraft:hand_equipped": true,
      "minecraft:use_animation": "bow",
      "minecraft:use_duration": 72000,
      "netease:ranged_weapon": {
        "charge_type": "default",
        "charge_time": 1.0,
        "auto_shoot": false,
        "charge_on_draw": true,
        "projectile": "mymod:custom_arrow",
        "launch_power": 3.0,
        "draw_sound": "bow.pull",
        "shoot_sound": "bow.hit"
      },
      "netease:frame_animation": {
        "frame_count": 3,
        "texture_name": "custom_bow_pulling",
        "animate_in_toolbar": false
      },
      "netease:render_offsets": {
        "controller_position_adjust": [0.0, 0.0, 0.0],
        "controller_rotation_adjust": [0.0, 0.0, 0.0],
        "controller_scale": 1.0
      }
    }
  }
}

2. 行为包 - 抛射物实体 ​

behavior_pack/entities/custom_arrow.json:

json
{
  "format_version": "1.10.0",
  "minecraft:entity": {
    "description": {
      "identifier": "mymod:custom_arrow",
      "is_spawnable": false,
      "is_summonable": true,
      "netease:custom_entity_type": "projectile_entity"
    },
    "components": {
      "netease:projectile": {
        "power": 1.6,
        "gravity": 0.05,
        "uncertainty": 1.0,
        "anchor": 1,
        "damage": 8,
        "is_dangerous": true,
        "knock_back_force": 0.5,
        "particle": "minecraft:critical_hit_emitter",
        "hit_sound": "bow.hit",
        "shoot_sound": "bow.release"
      },
      "minecraft:collision_box": {
        "width": 0.25,
        "height": 0.25
      },
      "minecraft:physics": {}
    }
  }
}

3. 资源包 - 物品资源定义 ​

resource_pack/netease_items_res/custom_bow.json:

json
{
  "format_version": "1.10",
  "minecraft:item": {
    "description": {
      "identifier": "mymod:custom_bow",
      "texture": "custom_bow"
    }
  }
}

4. 资源包 - 贴图映射 ​

resource_pack/textures/item_texture.json(追加内容):

json
{
  "resource_pack_name": "mymod",
  "texture_data": {
    "custom_bow": {
      "textures": "textures/items/custom_bow"
    },
    "custom_bow_pulling": {
      "textures": [
        "textures/items/custom_bow_pulling_0",
        "textures/items/custom_bow_pulling_1",
        "textures/items/custom_bow_pulling_2"
      ]
    }
  }
}

5. 资源包 - 抛射物客户端实体 ​

resource_pack/entity/custom_arrow.entity.json:

json
{
  "format_version": "1.10.0",
  "minecraft:client_entity": {
    "description": {
      "identifier": "mymod:custom_arrow",
      "materials": {
        "default": "entity_alphatest"
      },
      "textures": {
        "default": "textures/entity/custom_arrow"
      },
      "geometry": {
        "default": "geometry.custom_arrow"
      },
      "animations": {
        "move": "animation.custom_arrow.move"
      },
      "scripts": {
        "animate": ["move"]
      },
      "render_controllers": [
        "controller.render.default"
      ]
    }
  }
}

6. 资源包 - 抛射物飞行动画 ​

resource_pack/animations/custom_arrow.animation.json:

json
{
  "format_version": "1.8.0",
  "animations": {
    "animation.custom_arrow.move": {
      "loop": true,
      "bones": {
        "body": {
          "rotation": [
            "query.target_x_rotation",
            "query.target_y_rotation",
            0
          ]
        }
      }
    }
  }
}

7. 本地化 ​

resource_pack/texts/zh_CN.lang:

item.mymod:custom_bow.name=自定义弓
entity.mymod:custom_arrow.name=自定义箭

常见问题 ​

第三人称没有抬手动画 ​

确认物品 identifier 冒号后部分以 bow 结尾(如 mymod:custom_bow),这是触发第三人称弓瞄准动画的必要条件。

蓄力过程中无动画 ​

检查是否正确配置了 netease:frame_animation 组件,并确认 item_texture.json 中的序列帧贴图数组与 texture_name 字段对应。

抛射物不飞行 ​

确认抛射物实体的 netease:custom_entity_type 设为 projectile_entity,并且 netease:projectile 组件中的 power 值大于 0。

抛射物不造成伤害 ​

检查 netease:projectile 中的 is_dangerous 是否设为 true,以及 damage 值是否大于 0。

下一步 ​