Skip to content
On this page

物品槽组件

物品槽组件用于显示并交互一份由服务端管理的物品状态。槽位身份固定由“玩家 + mode + bind”决定,不绑定页面或页面会话;不同页面、HUD 和世界页面只要打开了相同 mode + bind,就会自动显示并同步同一份槽位数据。客户端只提交点击意图,最终物品、光标、版本和背包变化都由服务端裁决。

物品槽默认不绘制底框、填充或边框。这样可以直接放到自定义界面素材上;如果需要独立槽位背景,可配置一张静态图片。

适用场景

  • 临时合成、提交和操作槽
  • 按玩家长期保存、可跨页面使用的物品槽
  • 映射玩家真实背包位置
  • 多个界面位置同步显示同一个槽位

服务端始终权威

客户端不能提交最终物品内容。过期版本、重复操作、伪造会话和无效映射都会被拒绝,避免不同步或重复物品。

通用配置

配置项编辑器名称类型默认值可选值或格式说明
idID字符串自动生成 item_slot_N页面内唯一 ID只标识页面组件本身,不等同于槽位绑定 ID。
type类型只读字符串item_slot固定值创建后不能修改。
parent父级字符串布局组件 ID为空表示根级元素。
z层级整数0任意整数控制槽位绘制顺序。
visible显示布尔值truetruefalse静态显隐开关。
enabled启用布尔值truetruefalse为假时不能进行槽位交互。
pointerEvents指针处理枚举autoautoblockpass槽位在 auto 下天然参与命中;pass 会关闭槽位交互。
scale缩放数字或公式1非负值以槽位中心缩放画面和命中范围,不改变布局值。
opacity背景透明度数字或公式101只影响槽位背景和边框,物品、数量与附魔效果保持不透明。
visibleWhen显示条件条件表达式只读条件条件为假时隐藏。
enabledWhen启用条件条件表达式只读条件条件为假时禁用。
containerBinding容器绑定字符串当前容器的语义槽位 ID仅容器替换页面使用;绑定后委托原版容器保留完整槽位交互。
containerTooltip容器提示布尔值truetruefalse是否显示绑定原版物品的完整提示。
layout.xX数字或公式创建时画布位置合法布局公式槽位左上角 X。
layout.yY数字或公式创建时画布位置合法布局公式槽位左上角 Y。
layout.width数字或公式18合法布局公式推荐保持原版槽位附近尺寸。
layout.height数字或公式18合法布局公式推荐保持原版槽位附近尺寸。
events.leftPress
/rightPress/middlePress
按下脚本ChaUI Script多行脚本对应按键按下时触发。
events.leftRelease
/rightRelease/middleRelease
松开脚本ChaUI Script多行脚本对应按键捕获仍有效并松开时触发。
events.leftClick左键脚本ChaUI Script多行脚本组件左键事件;物品交换本身仍由槽位交互处理。
events.rightClick右键脚本ChaUI Script多行脚本右键事件。
events.middleClick中键脚本ChaUI Script多行脚本中键事件。
events.hoverEnter悬浮进入脚本ChaUI Script多行脚本鼠标进入时触发。
events.hoverLeave悬浮离开脚本ChaUI Script多行脚本鼠标离开时触发。

物品槽不支持自定义 tooltip。鼠标悬浮信息固定来自当前槽位物品自身,保存时写入 tooltip 会被拒绝。容器替换页面可用 containerTooltip: false 关闭绑定原版物品的提示。enabled: falseenabledWhen 结果为假时,槽内物品仍会绘制,但不会显示 Tooltip 或响应物品操作。

物品槽也不支持 dragMode。拖动物品、拆分堆叠和容器替换页面中的原版槽位操作都需要完整使用鼠标拖动手势;如果还允许拖动物品槽组件本体,两种行为会发生冲突。需要玩家移动一组槽位时,可以把它们放进可拖动的布局组件中,让布局负责整体移动。

专属配置

配置项编辑器名称类型默认值可选值或格式说明
itemSlot.bind绑定字符串组件 ID安全绑定 ID标识槽位对应的物品状态;不同页面的相同 mode + bind 也会同步刷新。
itemSlot.mode模式枚举temporarypersistenttemporarymapped决定物品状态的存储和来源。
itemSlot.closePolicy关闭枚举return_to_playerreturn_to_playercommitdiscardtemporary 显示和生效;persistentmapped 不允许配置。
itemSlot.check操作条件条件表达式visibleWhen 相同的只读条件语法空白表示允许;结果为假、表达式无效或求值失败时不发送槽位操作包,但 events.leftClick 仍会执行。
itemSlot.allowPut放入布尔值truetruefalse是否允许把 ChaUI 会话光标中的物品放入槽位。
itemSlot.allowTake取出布尔值truetruefalse是否允许把槽位物品取到 ChaUI 会话光标。
itemSlot.path背景路径字符串ChaUI 安全相对路径;仅 pngjpgjpeg可使用 {vars.xxx} 等响应式路径模板;留空时槽位背景透明。
itemSlot.sourceX背景源X非负整数或公式0源图像素坐标或数字公式背景选区左上角 X。
itemSlot.sourceY背景源Y非负整数或公式0源图像素坐标或数字公式背景选区左上角 Y。
itemSlot.sourceWidth背景源宽非负整数或公式整张图片剩余宽度像素尺寸或数字公式背景选区宽度;为 0 时背景不绘制。
itemSlot.sourceHeight背景源高非负整数或公式整张图片剩余高度像素尺寸或数字公式背景选区高度;为 0 时背景不绘制。

背景选区公式每次渲染重新计算并向下取整。公式无效或越界时只隐藏槽位背景,槽位中的物品、数量、提示和交互仍然正常。

三种槽位模式

模式状态位置关闭后行为常见用途
persistent服务端按玩家与 bind 保存不执行关闭策略;之后打开任意相同 bind 页面都会恢复长期存储、跨页面玩家专属槽位
temporary玩家当前 ChaUI 运行期,按 bind 保存最后一个运行时页面关闭时执行关闭策略并清理合成、提交、跨当前打开页面的临时操作
mapped服务端真实映射槽位直接使用真实容器状态,无关闭策略backpack_0 等玩家背包映射

三种模式的数据、版本和收尾逻辑彼此独立。即使 persistenttemporary 使用完全相同的 bind,也不会读取或影响对方的物品。

临时槽位关闭策略

  • return_to_player:关闭时尝试返还玩家,背包满时必须使用安全保护,不能吞物品或刷物品。
  • commit:把最终物品交给其他业务逻辑处理。
  • discard:明确丢弃,适合受控的特殊页面,使用前应确认业务风险。

同一个 temporary + bind 如果出现在多个已保存页面中,这些页面必须配置相同的 closePolicy,否则页面加载或保存会被拒绝。临时槽位会一直保留到玩家最后一个 ChaUI 运行时页面关闭;只关闭其中一个页面不会提前收尾。

操作条件

“操作条件”是客户端发包前的便捷判断,适合根据当前页面变量或只读常量暂时禁止槽位交换。没配置或留空时直接允许;条件为假、语法无效或运行时求值失败时,只阻止内置槽位操作包,组件自己的 events.leftClick 仍按原顺序执行。

这个字段不能替代服务端权限和物品安全校验。客户端状态可能被修改,真正的权限、物品合法性和业务条件仍应在服务端事件中检查。

背包映射

mapped 使用显式白名单。backpack_0backpack_35 映射 36 格主背包,另外支持 backpack_mainhandbackpack_offhandbackpack_helmetbackpack_chestplatebackpack_leggingsbackpack_boots。点击时服务端会用 ChaUI 会话光标与真实背包槽执行权威交换。

完整编号、动态主手语义和只读背包常量见背包映射表

配置示例

yaml
- id: submit_slot
  type: item_slot
  parent: ""
  visible: true
  enabled: true
  pointerEvents: auto
  scale: 1
  opacity: 0.85
  z: 10
  layout:
    x: 40
    y: 40
    width: 18
    height: 18
  itemSlot:
    bind: quest_submit
    mode: temporary
    closePolicy: return_to_player
    check: vars.questReady && vals.player.health > 0  # 操作条件:任务就绪且玩家存活
    allowPut: true
    allowTake: true
    path: gui/item_slot.png     # 可选;不写时背景完全透明
    sourceX: 0
    sourceY: 0
    sourceWidth: 18
    sourceHeight: 18
  events: {}

槽位对象的配置可以安全读取,但物品交换结果仍由服务端裁决。下面的事件只读取绑定 ID,不会直接修改槽位物品:

yaml
events:
  rightClick: |-
    vars.slotBind = component("submit_slot").itemSlot.bind
    log("当前槽位绑定:{vars.slotBind}")

映射背包示例:

yaml
itemSlot:
    bind: backpack_0
    mode: mapped
    allowPut: true
    allowTake: true

mapped 模式不要写 closePolicy

相同 bind、不同模式仍是两份独立数据:

yaml
- id: saved_reward
  type: item_slot
  layout: {x: 20, y: 20, width: 18, height: 18}
  itemSlot:
    bind: reward
    mode: persistent

- id: current_reward
  type: item_slot
  layout: {x: 44, y: 20, width: 18, height: 18}
  itemSlot:
    bind: reward
    mode: temporary
    closePolicy: return_to_player

上面的两个槽位虽然都叫 reward,但永久槽位和临时槽位不会互相显示、覆盖或同步物品。

背景图片只负责装饰,不参与服务端物品裁决,也不会改变槽位的点击区域。物品槽背景不支持 GIF。

常见问题

两个槽位为什么同时变化

它们使用了相同的 itemSlot.mode + itemSlot.bind,因此绑定同一份玩家级服务端状态。这个规则也适用于不同页面、HUD 和世界页面。不需要同步时请更换 bind;需要同名但数据隔离时请使用不同 mode。

操作条件没通过,为什么左键脚本还执行

itemSlot.check 只控制内置槽位操作是否发包,不控制组件事件。这样可以在禁止交换时仍播放提示、修改页面变量或记录本地日志。需要阻止脚本逻辑时,请在 events.leftClick 内使用同样的条件自行分支。

点击后提示版本过期

服务端状态已经变化,客户端提交的是旧版本操作。等待最新同步结果后重新操作,不要让客户端自行构造物品结果。

mapped 为什么只能使用白名单 bind

真实容器映射必须经过服务端白名单,避免客户端构造危险槽位地址。未记录的映射会被拒绝。

创建事件

item_slot 支持 events.create,可在槽位组件实例创建时设置说明变量、显隐或周边组件状态。初始槽位和动态槽位实例各触发一次,但脚本不能伪造最终物品结果;槽位内容仍以服务端同步为准,关闭或 reload 时继续执行既定的持久化、返还或映射策略。