NPC对话系统
非玩家角色(NPC)是类似村民的实体,可以为其配置带有消息和多个按钮的对话界面。最初设计用于冒险地图,但随着/dialogue命令的引入,现在也可用于常规附加包中。
对话文件
NPC对话数据存储在行为包根目录下dialogue文件夹中的对话文件里。以下是一个基础NPC对话文件示例:
{
"format_version": "1.17",
"minecraft:npc_dialogue": {
"scenes": [
{
"scene_tag": "example",
"npc_name": "Steve",
"text": "Hello"
}
]
}
}该文件中包含场景数组,每个场景代表独立对话。所有对话可集中在一个文件,也可分散存储。每个场景对象包含以下可配置属性:
scene_tag
场景标识符,用于定位特定场景。
npc_name
NPC显示名称(可选)。若未指定,将使用NPC实体默认名称§eNPC。
text
对话气泡中显示的文本内容(可选)。
on_open_commands
对话打开时执行的命令数组(可选)。
"on_open_commands": [
"/say Hello"
]on_close_commands
对话关闭时执行的命令数组(可选)。
"on_close_commands": [
"/say Goodbye"
]buttons
对话框中显示的按钮配置数组(可选)。
"buttons": [
{
"name": "Button One",
"commands": [
"/say Button One Pressed!"
]
},
{
"name": "Button Two",
"commands": [
"/say Button Two Pressed!",
"/say Secondary Command for Button Two"
]
}
]玩家选择机制
在on_open_commands、on_close_commands及按钮命令中,可使用常规选择器(如@p选择最近玩家)。但注意这些选择器以NPC实体为基准执行,多人游戏时可能造成混淆。为此引入特殊选择器@initiator,始终指向当前打开对话的玩家。
"buttons": [
{
"name": "Levitation Please",
"commands": [
"/effect @initiator levitation"
]
}
]该选择器仅限NPC对话中使用,不可用于其他场景。
多语言支持
所有面向用户的对话属性均可实现本地化:
"npc_name": {
"rawtext": [
{
"translate": "entity.endermite.name"
}
]
}需在资源包语言文件中指定对应翻译键值。例如entity.endermite.name会被翻译为"末影螨"。
打开对话
使用/dialogue命令控制对话界面,语法如下: /dialogue open <npc: target> <player: target> [sceneName:string]
<npc: target>:指向具有minecraft:npc组件的实体选择器(如原版NPC),决定命令执行位置及对话NPC外观。<player: target>:指向接收对话的玩家选择器。[sceneName:string]:匹配scene_tag的字符串(可选),未指定时将显示该NPC上次使用的对话。
示例命令(为最近玩家打开最近NPC的"example"对话):
/dialogue open @e[type=npc,c=1] @p example修改对话
/dialogue change命令可变更NPC对话配置(需玩家手动打开后生效),语法: /dialogue change <npc: target> <sceneName:string> [player: target]
<npc: target>:目标NPC选择器。<sceneName:string>:匹配scene_tag的字符串。[player: target]:目标玩家选择器(可选),未指定时影响所有玩家。
示例命令(将最近NPC对话改为"example"并随机选择玩家):
/dialogue change @e[type=npc,c=1] example @r完整示例
本示例将创建实现右键传送功能的物品。GitHub源码包含完整实现,需使用本文档顶部的清单文件。
创建NPC实体
即使NPC不可见,仍需通过以下命令创建并保持常加载状态:
tickingarea add 0 1 0 0 2 0
summon npc "§r" 0 1 0该函数在坐标(0,0)创建常加载区,并在基岩层生成无名NPC。可通过player.json或tick.json自动执行,或手动运行。
TIP
无需预生成NPC的替代方案:
- 在玩家行为中添加
minecraft:npc组件 - 指定BP/dialogue文件夹中的场景
- 从玩家实体执行命令:
/dialogue open @s @s <scene_tag>优劣分析:
+无需处理NPC隐藏问题+免除常加载区维护-非设计用途可能导致不稳定-其他玩家点击该玩家也会触发对话
可通过添加minecraft:interaction组件避免此问题:
"minecraft:interact": {
"interactions": [
{
"on_interact": {
"filters": {
"all_of": [
{
"test": "is_family",
"subject": "other",
"value": "player"
}
]
}
}
}
]
}对话文件配置
包含两个传送菜单场景的对话文件:
{
"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"]
}
]
}
]
}
}创建功能物品
使用末影珍珠纹理创建触发对话的自定义物品:
物品JSON
{
"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"]
}
}
}自定义组件脚本
import { 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);
});测试流程
- 打包文件并导入Minecraft
- 创建新超平坦世界(需开启作弊和实验性玩法)
- 执行
/function setup初始化NPC - 通过
/give @s wiki:teleport_menu获取物品 - 切换生存模式(创造模式无法触发对话)
- 手持物品右键使用
鸣谢
本教程基于Minecraft创作者文档相关内容编写。








