虚拟实体生成(展示实体 Display Entity)¶
原文:原创教程(ぴよまる),API 依据 KubeJS 6.1(1.20.1)源码与 Minecraft 1.19.4+ 展示实体机制
「虚拟实体」= 展示实体(Display Entity):一种没有 AI、没有碰撞、不参与战斗的纯展示实体。它们不会移动、不会攻击、不会掉落,只负责「显示东西」——非常适合做全息文字、悬浮物品、装饰方块、虚拟按钮等,是整合包里做场景装饰和交互的利器。
四种展示实体一览:
| 实体 ID | 作用 | 典型用途 |
|---|---|---|
minecraft:item_display |
展示一个物品(可旋转/缩放/发光) | 悬浮神器、展示柜里的宝物 |
minecraft:block_display |
展示一个方块(含方块状态) | 虚拟建筑、装饰方块 |
minecraft:text_display |
展示一段文字(全息文字) | 公告牌、地标名称、价格牌 |
minecraft:interaction |
一个无形的交互区域(可被点击/击中) | 虚拟按钮、传送点触发器 |
1. 生成虚拟实体(summon 命令)¶
KubeJS 生成实体最通用的方式就是执行 summon 命令(服务器脚本):
// server_scripts/spawn_display.js
ServerEvents.loaded(event => { // 服务器加载完成后执行
let server = event.server
// 生成一个悬浮的钻石(item_display)
server.runCommandSilent(
'summon minecraft:item_display 100 80 100 ' +
'{item:{id:"minecraft:diamond",Count:1},billboard:"center",glow:1b}'
)
// 生成一块全息文字(text_display)
server.runCommandSilent(
'summon minecraft:text_display 100 85 100 ' +
'{text:\'{"text":"欢迎来到落英服","color":"gold"}\',billboard:"center",line_width:300,background:0}'
)
})
💡
billboard:"center"让展示面始终正对玩家(像公告牌);glow:1b发光;background:0文字背景透明。坐标用绝对坐标x y z。
常用 NBT 字段¶
| 字段 | 作用 | 示例 |
|---|---|---|
item |
item_display 展示的物品 | {id:"minecraft:diamond",Count:1} |
block_state |
block_display 展示的方块 | {Name:"minecraft:stone"} |
text |
text_display 的文字(JSON 文本) | '{"text":"你好"}' |
billboard |
朝向模式:fixed / vertical / horizontal / center |
"center" |
glow |
是否发光(0b/1b) | 1b |
line_width |
text_display 换行宽度 | 300 |
background |
text_display 背景色(ARGB,0=透明) | 0 |
see_through |
文字是否隔墙可见 | 1b |
transformation |
位移/旋转/缩放矩阵(11 个数字) | 见下方示例 |
width / height |
interaction 交互区域大小 | 1f / 1f |
response |
interaction 是否响应点击(1b/0b) | 1b |
Tags |
给实体打标签(方便批量管理) | ["my_display"] |
缩放 / 旋转(transformation)¶
transformation 用 3×3 矩阵 + 平移共 12 个数字表示,前 9 个是旋转/缩放,后 3 个是平移。缩放 2 倍:
// 一个放大 2 倍的悬浮钻石
server.runCommandSilent(
'summon minecraft:item_display 100 80 100 ' +
'{item:{id:"minecraft:diamond",Count:1},billboard:"center",' +
'transformation:[2f,0f,0f,0f, 0f,2f,0f,0f, 0f,0f,2f,0f, 0f,0f,0f,1f]}'
)
2. 虚拟交互区域(interaction 实体)¶
interaction 实体是无形的点击区域,放一个在位置上,玩家左键/右键它就会触发实体事件,是 KubeJS 做「虚拟按钮」的标准姿势:
// server_scripts/virtual_button.js
ServerEvents.loaded(event => {
// 在 (100, 80, 100) 生成一个 2×2 的虚拟按钮区域
event.server.runCommandSilent(
'summon minecraft:interaction 100 80 100 ' +
'{width:2f,height:2f,response:1b,Tags:["virtual_btn"]}'
)
})
// 玩家右键虚拟按钮 → 发奖励
EntityEvents.interact('minecraft:interaction', event => { // 交互事件(1.20.1 可用)
let entity = event.entity
if (!entity.tags.contains('virtual_btn')) return // 只响应我们打的标签
event.player.tell('§a你按下了虚拟按钮!送你一颗钻石')
event.player.give('minecraft:diamond')
})
⚠️ 虚拟实体没有碰撞箱(interaction 只有交互判定、不挡路),玩家可以直接穿过去;做「真的挡路」的装饰请用方块而不是展示实体。
3. 管理虚拟实体(查找 / 清除 / 批量操作)¶
给虚拟实体打上 Tags 标签后,可以批量查找和清理:
// server_scripts/manage_displays.js
function killVirtualEntities(server, tag) { // 清除所有带指定标签的展示实体
server.runCommandSilent(`kill @e[type=minecraft:item_display,tag=${tag}]`)
server.runCommandSilent(`kill @e[type=minecraft:text_display,tag=${tag}]`)
server.runCommandSilent(`kill @e[type=minecraft:block_display,tag=${tag}]`)
server.runCommandSilent(`kill @e[type=minecraft:interaction,tag=${tag}]`)
}
// 玩家输入 !清场 时,清掉所有虚拟装饰
PlayerEvents.chat(event => {
if (event.message !== '!清场') return
killVirtualEntities(event.server, 'my_display')
event.player.tell('已清除所有虚拟装饰')
})
4. 与数据存储联动:重启后自动恢复虚拟实体¶
虚拟实体不会跟随存档保存(展示实体默认不写入区块),服务器一重启就全没了。想让它「永久存在」,就把生成信息存进文件,启动时读出来重新生成——这就是和「数据存储」章节的联动。
完整案例:服务器启动时自动恢复全息公告牌(重启不丢)
// server_scripts/virtual_entities_save.js
// ① 定义:保存虚拟实体配置到 JSON 文件(先读 → 改 → 写,避免覆盖)
function saveVirtualEntities(server) {
let data = JsonIO.read('kubejs/config/virtual_entities.json') // 读现有配置
if (!data || !data.displays) data = { displays: [] } // 没有就初始化
data.displays.push({ // 追加一条虚拟实体配置
type: 'minecraft:text_display', // 实体类型
x: 100, y: 85, z: 100, // 坐标
nbt: '{"text":"欢迎来到落英服","billboard":"center"}' // NBT(字符串形式)
})
JsonIO.write('kubejs/config/virtual_entities.json', data) // 写回
}
// ② 定义:读取配置并重新生成所有虚拟实体
function loadVirtualEntities(server) {
let data = JsonIO.read('kubejs/config/virtual_entities.json') // 读配置
if (!data || !data.displays) return // 没有配置就直接返回
data.displays.forEach(d => { // 遍历每条配置
server.runCommandSilent(`summon ${d.type} ${d.x} ${d.y} ${d.z} ${d.nbt}`) // 重新生成
})
console.log(`已恢复 ${data.displays.length} 个虚拟实体`)
}
// ③ 服务器加载时:先恢复,再保存示例
ServerEvents.loaded(event => {
loadVirtualEntities(event.server) // 读取存档 → 重新生成虚拟实体(重启不丢)
saveVirtualEntities(event.server) // 把当前要展示的虚拟实体写进存档
})
💡 思路总结:虚拟实体 = 一次性生成;数据存储 = 让它持久。生成信息存
kubejs/config/下的 JSON 文件(JsonIO 读写,详见「配置文件与数据储存」篇第 5 节),每次服务器启动ServerEvents.loaded时读档重建,完美解决重启消失问题。
联动速查¶
| 需求 | 写法 | 对应章节 |
|---|---|---|
| 临时生成虚拟实体(不保存) | server.runCommandSilent('summon ...') |
本文第 1 节 |
| 重启后恢复虚拟实体 | JsonIO 存配置 + ServerEvents.loaded 读档重建 |
本文第 4 节 |
| 存玩家/实体状态数据 | player.persistentData / entity.persistentData |
「配置文件与数据储存」第 3 节 |
| 存服务器级全局数据 | server.getData() / JsonIO 写文件 |
「配置文件与数据储存」第 4-5 节 |
本文为 KubeJS 1.20.1 中文文档原创篇目。API 依据 KubeJS 6.1 源码与 Minecraft 1.19.4+ Display Entity 机制。