跳转至

虚拟实体生成(展示实体 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 机制。