变量与条件
变量可以让页面记住当前会话中的选择、计数和开关状态。页面根级 vars 提供默认值,脚本使用 vars.<名称> 读取或修改它们;中文写法为 变量.<名称>。
页面变量
变量名称可以使用 Unicode 字母、数字和下划线,但必须以字母或下划线开头。变量值支持字符串、数字和布尔值。
vars:
page: 1 # 当前页码
selected: "none" # 当前选择
ready: false # 是否准备完成
计数: 0 # 中文变量名同样可用vars.page = vars.page + 1
vars.selected = "item_a"
变量.ready = true
变量.计数 = 变量.计数 + 1变量修改只影响当前打开的页面会话。重新打开页面后,会重新使用页面文件中的默认值,除非服务端业务再次下发新的变量状态。
页面 open、组件 create、页面 close 和自定义方法共享同一份会话变量。因此可以在 open 中准备默认状态,在方法中集中修改,再让文字、布局和条件自动响应。
方法.初始化()methods:
初始化: |-
vars.ready = true
vars.title = "加载完成"响应式文字
文本组件的 text.value 与按钮的 button.label 可以使用 {...} 读取变量。变量变化后,文字会自动显示最新值。
当前页:{vars.page}
当前选择:{vars.selected}
已完成:{vars.ready}花括号内支持四则运算和括号,例如 {vars.current / vars.total * 100}%。需要显示普通花括号时,连续写两个左花括号或两个右花括号。
完整用法请阅读响应式变量与实时文字。
只读数据
vals 是 ChaUI 提供的只读常量,适合在条件和赋值右侧读取。它包含玩家状态、36 格背包汇总、主手/副手/盔甲物品、鼠标状态和 PlaceholderAPI 结果。
例如,可以根据玩家当前生命值切换警告文字:
if vals.player.health < vals.player.maxHealth * 0.3 {
component("health_warning").visible = true
} else {
component("health_warning").visible = false
}鼠标常量也能直接用于条件:
if vals.mouse.leftDown {
vars.status = "鼠标左键正按下"
}所有玩家、背包、装备、鼠标和 PAPI 字段及中文写法统一收录在只读常量。
值类型与真值
页面根级 vars 正式支持字符串、数字和布尔值。列表和组件对象不是可保存的页面默认值,它们只会由 item.lore、组件引用等只读或运行时上下文提供。
当一个值不写 == true,而是直接用于 if、visibleWhen 或 enabledWhen 时,ChaUI 会按下表判断真假:
| 值类型 | 页面变量示例 | 直接用于条件时 | 常用转换 |
|---|---|---|---|
| 字符串 | title: "商店" | 空白、"0"、忽略大小写和首尾空白后的 "false" 为假;其他非空字符串为真 | 四种转换均可按规则使用 |
| 数字 | amount: 12.5 | 0 为假,其他有限数字为真 | 四种转换均可用 |
| 布尔值 | ready: true | 保持原值 | 四种转换均可用 |
null | 列表越界等只读结果 | 假 | 可稳定转为字符串 "null" 或布尔值 false |
| 列表 | item.lore | 非空运行时对象沿用真值语义 | 不支持转字符串、数字或整数 |
| 对象 | component("id") | 非空运行时对象沿用真值语义 | 不支持标量转换 |
所以 PlaceholderAPI 返回的文本可以直接控制显示,例如 visibleWhen: vals.papi.enabled 会正确识别 0、1、"true" 和 "false"。其他普通非空文本仍为真。
条件表达式是只读判断。需要改变状态时,应在条件块内写入赋值语句。
类型转换函数
转换函数适合把 PAPI 文本或已有变量明确变成后续脚本需要的类型。英文名和中文名完全等价。
| 英文写法 | 中文写法 | 接受的输入 | 返回结果 | 失败情况 |
|---|---|---|---|---|
toString(value) | 转字符串(value) | 字符串、有限数字、布尔值、null | 字符串;整数数字不会多出 .0,null 得到 "null" | 列表、组件对象等非标量值会失败 |
toNumber(value) | 转数字(value) | 有限数字、布尔值、可解析的非空数字字符串 | 数字;true 为 1,false 为 0 | 空白、普通文本、null、NaN 和无限值会失败 |
toInteger(value) | 转整数(value) | toNumber 可接受的值 | 向 0 截断后的安全整数,例如 -12.9 得到 -12 | 超出 ±9007199254740991 的安全整数范围会失败 |
toBoolean(value) | 转布尔(value) | 任意运行时值 | 使用上方真值表得到布尔值 | 非有限数字会失败 |
下面是可直接保存的完整页面示例。假设两个 PAPI 分别返回 "true" 和 "12",页面打开后 vars.enabled 会成为布尔值 true,vars.amount 会成为整数 12:
id: papi_conversion_demo
version: 1
title: "PAPI 类型转换"
size:
width: 220
height: 80
display:
mode: screen
papi:
refreshTicks: 20
values:
enabled: "%example_enabled%"
amount: "%example_amount%"
vars:
enabled: false
amount: 0
events:
open: |-
vars.enabled = toBoolean(vals.papi.enabled)
vars.amount = toInteger(vals.papi.amount)
methods: {}
elements:
- id: result
type: text
visibleWhen: vals.papi.enabled
layout:
x: 10
y: 10
width: 200
height: 40
text:
value: "启用={vars.enabled},数量={vars.amount}"
textSize: 1如果转换失败,只会终止当前脚本语句,后续语句仍然继续;保存阶段能够确定的错误参数则会直接阻止保存。
字符串与列表的通用方法
ChaUI 条件和执行脚本共用一套字符串与列表能力。字符串可以判断包含、前缀和后缀,列表可以判断是否存在某个完整元素:
vars.title.contains("宝石")
vars.title.startsWith("精炼")
vars.title.endsWith("核心")
vars.tags.contains("不可交易")也可以使用函数式兼容写法 contains(value, part)、startsWith(value, prefix) 与 endsWith(value, suffix)。新脚本优先使用对象方法,连续阅读时更容易看出正在检查哪个值。所有判断都区分大小写。
在槽位接收条件和 Tooltip 物品条件中,item.lore 是 List<String>:每个元素对应一条去样式后的原 Lore。item.loreText 则是把全部行使用 \n 拼接出的兼容字符串。
名称包含:
item.name.contains("宝石")名称不包含:
!item.name.contains("赝品")Lore 存在一条完全相同的行:
item.lore.contains("不可交易")第一行包含一段文字:
item.lore[0] != null && item.lore[0].contains("史诗")列表索引从 0 开始,索引越界返回 null。负数、小数或非数字索引属于错误;需要继续调用字符串方法时,应像上例一样先判断该行不为 null。item.* 只在明确提供物品上下文的条件中可用,例如 slot.yml 的 acceptWhen 和 Tooltip 的 when,普通页面事件不会凭空获得当前物品。
数字表达式
数字变量和布局属性支持四则运算及括号。建议使用括号明确运算顺序;取整、限制范围、插值和小数格式化请查看数学函数。
vars.total = (vars.base + 5) * 2
component("panel").layout.width = formula(window.width * 0.5)
component("panel").layout.x = formula((window.width - self.width) * 0.5)这里必须区分两种赋值:vars.total = ... 会立即算出一个普通变量值;layout.width = formula(...) 会保存响应式布局公式。若写成 component("panel").layout.width = window.width * 0.5,脚本只会保存执行当时算出的固定宽度,之后调整窗口不会继续变化。
组件也可以读取其他组件的当前值或原始公式:
events:
leftClick: |-
vars.panelWidth = component("panel").layout.width
vars.panelWidthFormula = component("panel").layout.expression("width").source布局公式中还可以使用以下上下文:
| 英文写法 | 中文写法 | 含义 |
|---|---|---|
window.width | 窗口.宽 | 当前 GUI 缩放坐标宽度 |
window.height | 窗口.高 | 当前 GUI 缩放坐标高度 |
parent.x / parent.y | 父级.x / 父级.y | 父布局的位置 |
parent.width / parent.height | 父级.宽 / 父级.高 | 父布局的尺寸 |
self.width / self.height | 自身.宽 / 自身.高 | 当前组件自身尺寸 |
变量变化后,引用该变量的布局公式、显隐条件、文本内容和按钮文字会重新计算并刷新。
循环次数和计时器间隔也可以使用数字表达式,并在启动时读取一次当前值:
repeat(vars.pageSize * 2, vars.i) { vars.total = vars.total + vars.i }
timer("refresh", vars.refreshTicks) { vars.refreshCount = vars.refreshCount + 1 }完整限制和生命周期请阅读循环与计时器。
页面条件字段与脚本条件
如果组件需要长期跟随变量自动显隐,优先使用组件的 visibleWhen 或 enabledWhen。如果只需要在某次点击时执行一组动作,则使用脚本 if。
- id: ready_tip
type: text
visibleWhen: "vars.ready == true" # 变量变化后自动重新判断
enabledWhen: "vars.page >= 1"
layout:
x: 20
y: 20
width: 120
height: 20
text:
value: "准备完成"
猹件开发组