Skip to content
On this page

变量与条件

变量可以让页面记住当前会话中的选择、计数和开关状态。页面根级 vars 提供默认值,脚本使用 vars.<名称> 读取或修改它们;中文写法为 变量.<名称>

页面变量

变量名称可以使用 Unicode 字母、数字和下划线,但必须以字母或下划线开头。变量值支持字符串、数字和布尔值。

yaml
vars:
  page: 1 # 当前页码
  selected: "none" # 当前选择
  ready: false # 是否准备完成
  计数: 0 # 中文变量名同样可用
text
vars.page = vars.page + 1
vars.selected = "item_a"
变量.ready = true
变量.计数 = 变量.计数 + 1

变量修改只影响当前打开的页面会话。重新打开页面后,会重新使用页面文件中的默认值,除非服务端业务再次下发新的变量状态。

页面 open、组件 create、页面 close 和自定义方法共享同一份会话变量。因此可以在 open 中准备默认状态,在方法中集中修改,再让文字、布局和条件自动响应。

text
方法.初始化()
yaml
methods:
  初始化: |-
    vars.ready = true
    vars.title = "加载完成"

响应式文字

文本组件的 text.value 与按钮的 button.label 可以使用 {...} 读取变量。变量变化后,文字会自动显示最新值。

text
当前页:{vars.page}
当前选择:{vars.selected}
已完成:{vars.ready}

花括号内支持四则运算和括号,例如 {vars.current / vars.total * 100}%。需要显示普通花括号时,连续写两个左花括号或两个右花括号。

完整用法请阅读响应式变量与实时文字

只读数据

vals 是 ChaUI 提供的只读常量,适合在条件和赋值右侧读取。它包含玩家状态、36 格背包汇总、主手/副手/盔甲物品、鼠标状态和 PlaceholderAPI 结果。

例如,可以根据玩家当前生命值切换警告文字:

text
if vals.player.health < vals.player.maxHealth * 0.3 {
  component("health_warning").visible = true
} else {
  component("health_warning").visible = false
}

鼠标常量也能直接用于条件:

text
if vals.mouse.leftDown {
  vars.status = "鼠标左键正按下"
}

所有玩家、背包、装备、鼠标和 PAPI 字段及中文写法统一收录在只读常量

值类型与真值

页面根级 vars 正式支持字符串、数字和布尔值。列表和组件对象不是可保存的页面默认值,它们只会由 item.lore、组件引用等只读或运行时上下文提供。

当一个值不写 == true,而是直接用于 ifvisibleWhenenabledWhen 时,ChaUI 会按下表判断真假:

值类型页面变量示例直接用于条件时常用转换
字符串title: "商店"空白、"0"、忽略大小写和首尾空白后的 "false" 为假;其他非空字符串为真四种转换均可按规则使用
数字amount: 12.50 为假,其他有限数字为真四种转换均可用
布尔值ready: true保持原值四种转换均可用
null列表越界等只读结果可稳定转为字符串 "null" 或布尔值 false
列表item.lore非空运行时对象沿用真值语义不支持转字符串、数字或整数
对象component("id")非空运行时对象沿用真值语义不支持标量转换

所以 PlaceholderAPI 返回的文本可以直接控制显示,例如 visibleWhen: vals.papi.enabled 会正确识别 01"true""false"。其他普通非空文本仍为真。

条件表达式是只读判断。需要改变状态时,应在条件块内写入赋值语句。

类型转换函数

转换函数适合把 PAPI 文本或已有变量明确变成后续脚本需要的类型。英文名和中文名完全等价。

英文写法中文写法接受的输入返回结果失败情况
toString(value)转字符串(value)字符串、有限数字、布尔值、null字符串;整数数字不会多出 .0null 得到 "null"列表、组件对象等非标量值会失败
toNumber(value)转数字(value)有限数字、布尔值、可解析的非空数字字符串数字;true1false0空白、普通文本、nullNaN 和无限值会失败
toInteger(value)转整数(value)toNumber 可接受的值向 0 截断后的安全整数,例如 -12.9 得到 -12超出 ±9007199254740991 的安全整数范围会失败
toBoolean(value)转布尔(value)任意运行时值使用上方真值表得到布尔值非有限数字会失败

下面是可直接保存的完整页面示例。假设两个 PAPI 分别返回 "true""12",页面打开后 vars.enabled 会成为布尔值 truevars.amount 会成为整数 12

yaml
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 条件和执行脚本共用一套字符串与列表能力。字符串可以判断包含、前缀和后缀,列表可以判断是否存在某个完整元素:

text
vars.title.contains("宝石")
vars.title.startsWith("精炼")
vars.title.endsWith("核心")
vars.tags.contains("不可交易")

也可以使用函数式兼容写法 contains(value, part)startsWith(value, prefix)endsWith(value, suffix)。新脚本优先使用对象方法,连续阅读时更容易看出正在检查哪个值。所有判断都区分大小写。

在槽位接收条件和 Tooltip 物品条件中,item.loreList<String>:每个元素对应一条去样式后的原 Lore。item.loreText 则是把全部行使用 \n 拼接出的兼容字符串。

名称包含:

text
item.name.contains("宝石")

名称不包含:

text
!item.name.contains("赝品")

Lore 存在一条完全相同的行:

text
item.lore.contains("不可交易")

第一行包含一段文字:

text
item.lore[0] != null && item.lore[0].contains("史诗")

列表索引从 0 开始,索引越界返回 null。负数、小数或非数字索引属于错误;需要继续调用字符串方法时,应像上例一样先判断该行不为 nullitem.* 只在明确提供物品上下文的条件中可用,例如 slot.ymlacceptWhen 和 Tooltip 的 when,普通页面事件不会凭空获得当前物品。

数字表达式

数字变量和布局属性支持四则运算及括号。建议使用括号明确运算顺序;取整、限制范围、插值和小数格式化请查看数学函数

text
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,脚本只会保存执行当时算出的固定宽度,之后调整窗口不会继续变化。

组件也可以读取其他组件的当前值或原始公式:

yaml
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自身.宽 / 自身.高当前组件自身尺寸

变量变化后,引用该变量的布局公式、显隐条件、文本内容和按钮文字会重新计算并刷新。

循环次数和计时器间隔也可以使用数字表达式,并在启动时读取一次当前值:

text
repeat(vars.pageSize * 2, vars.i) { vars.total = vars.total + vars.i }
timer("refresh", vars.refreshTicks) { vars.refreshCount = vars.refreshCount + 1 }

完整限制和生命周期请阅读循环与计时器

页面条件字段与脚本条件

如果组件需要长期跟随变量自动显隐,优先使用组件的 visibleWhenenabledWhen。如果只需要在某次点击时执行一组动作,则使用脚本 if

yaml
- id: ready_tip
  type: text
  visibleWhen: "vars.ready == true" # 变量变化后自动重新判断
  enabledWhen: "vars.page >= 1"
  layout:
    x: 20
    y: 20
    width: 120
    height: 20
  text:
    value: "准备完成"

下一页只读常量列出了页面能读取的玩家、背包、鼠标和 PAPI 数据;语法与事件介绍脚本可以在哪些事件中执行。