非玩家角色(NPC)是类似村民的实体,可以为其配置带有消息和多个按钮的对话界面。最初设计用于冒险地图,但随着/dialogue命令的引入,现在也可用于常规附加包中。
对话文件 NPC对话数据存储在行为包根目录下dialogue文件夹中的对话文件里。以下是一个基础NPC对话文件示例:
dialogue/example.diag.jsonjson{
"format_version": "1.17",
"minecraft:npc_dialogue": {
"scenes": [
{
"scene_tag": "example",
"npc_name": "Steve",
"text": "Hello"
}
]
}
}123456789101112该文件中包含场景数组,每个场景代表独立对话。所有对话可集中在一个文件,也可分散存储。每个场景对象包含以下可配置属性:
scene_tag 场景标识符,用于定位特定场景。
npc_name NPC显示名称(可选)。若未指定,将使用NPC实体默认名称§eNPC。
text 对话气泡中显示的文本内容(可选)。
on_open_commands 对话打开时执行的命令数组(可选)。
json"on_open_commands": [
"/say Hello"
]123on_close_commands 对话关闭时执行的命令数组(可选)。
json"on_close_commands": [
"/say Goodbye"
]123buttons 对话框中显示的按钮配置数组(可选)。
json"buttons": [
{
"name": "Button One",
"commands": [
"/say Button One Pressed!"
]
},
{
"name": "Button Two",
"commands": [
"/say Button Two Pressed!",
"/say Secondary Command for Button Two"
]
}
]123456789101112131415玩家选择机制 在on_open_commands、on_close_commands及按钮命令中,可使用常规选择器(如@p选择最近玩家)。但注意这些选择器以NPC实体为基准执行,多人游戏时可能造成混淆。为此引入特殊选择器@initiator,始终指向当前打开对话的玩家。
json"buttons": [
{
"name": "Levitation Please",
"commands": [
"/effect @initiator levitation"
]
}
]12345678该选择器仅限NPC对话中使用,不可用于其他场景。
多语言支持 所有面向用户的对话属性均可实现本地化:
json"npc_name": {
"rawtext": [
{
"translate": "entity.endermite.name"
}
]
}1234567需在资源包语言文件中指定对应翻译键值。例如entity.endermite.name会被翻译为"末影螨"。
打开对话 使用/dialogue命令控制对话界面,语法如下: /dialogue open
/dialogue open @e[type=npc,c=1] @p example1修改对话 /dialogue change命令可变更NPC对话配置(需玩家手动打开后生效),语法: /dialogue change
/dialogue change @e[type=npc,c=1] example @r1完整示例 本示例将创建实现右键传送功能的物品。GitHub源码包含完整实现,需使用本文档顶部的清单文件。
创建NPC实体 即使NPC不可见,仍需通过以下命令创建并保持常加载状态:
functions/setup.mcfunctiontickingarea add 0 1 0 0 2 0
summon npc "§r" 0 1 012该函数在坐标(0,0)创建常加载区,并在基岩层生成无名NPC。可通过player.json或tick.json自动执行,或手动运行。
TIP
无需预生成NPC的替代方案:
在玩家行为中添加minecraft:npc组件指定BP/dialogue文件夹中的场景从玩家实体执行命令:/dialogue open @s @s
json"minecraft:interact": {
"interactions": [
{
"on_interact": {
"filters": {
"all_of": [
{
"test": "is_family",
"subject": "other",
"value": "player"
}
]
}
}
}
]
}1234567891011121314151617对话文件配置 包含两个传送菜单场景的对话文件:
dialogue/example.diag.jsonjson{
"format_version": "1.17",
"minecraft:npc_dialogue": {
"scenes": [
{
"scene_tag": "main_teleport_menu",
"npc_name": "Teleport",
"text": "Where would you like to teleport?",
"buttons": [
{
"name": "Districts",
"commands": [
"/dialogue open @e[type=npc,c=1] @initiator districts_teleport_menu"
]
},
{
"name": "My Base",
"commands": ["/tp @initiator -20 4 -20"]
},
{
"name": "World Spawn",
"commands": ["/tp @initiator 0 4 0"]
}
]
},
{
"scene_tag": "districts_teleport_menu",
"npc_name": "District Teleport",
"text": "What district would you like to teleport to?",
"buttons": [
{
"name": "< Back",
"commands": [
"/dialogue open @e[type=npc,c=1] @initiator main_teleport_menu"
]
},
{
"name": "Shop District",
"commands": ["/tp @initiator 20 4 20"]
},
{
"name": "Gaming District",
"commands": ["/tp @initiator 20 4 -20"]
}
]
}
]
}
}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849创建功能物品 使用末影珍珠纹理创建触发对话的自定义物品:
物品JSON BP/items/teleport_menu.jsonjson{
"format_version": "1.21.70",
"minecraft:item": {
"description": {
"identifier": "wiki:teleport_menu",
"menu_category": {
"category": "items"
}
},
"components": {
"minecraft:icon": "ender_pearl",
"minecraft:glint": true,
"minecraft:display_name": {
"value": "Teleport Menu"
},
"minecraft:custom_components": ["wiki:teleport_menu"]
}
}
}12345678910111213141516171819自定义组件脚本 BP/scripts/teleportMenu.jsjsimport { world } from "@minecraft/server";
const ItemTeleportMenuComponent = {
onUse({ source }) {
source.runCommand("dialogue open @e[type=npc, c=1] @s main_teleport_menu");
},
};
world.beforeEvents.worldInitialize.subscribe(({ itemComponentRegistry }) => {
itemComponentRegistry.registerCustomComponent("wiki:teleport_menu", ItemTeleportMenuComponent);
});1234567891011测试流程 打包文件并导入Minecraft创建新超平坦世界(需开启作弊和实验性玩法)执行/function setup初始化NPC通过/give @s wiki:teleport_menu获取物品切换生存模式(创造模式无法触发对话)手持物品右键使用鸣谢 本教程基于Minecraft创作者文档相关内容编写。