语法与事件
ChaUI Script 使用接近 JavaScript 的简洁写法,但它不是完整的 JavaScript。页面只接受 ChaUI 明确支持的赋值、条件和内置动作,无法识别的语句会被安全跳过,不会允许任意客户端代码运行。
基本规则
- 换行和结构外的分号都可以分隔语句。
- 字符串可以使用双引号或单引号。
- 数字可以是整数或小数,布尔值使用
true、false。 - 函数参数使用逗号分隔。
- 条件分支使用
if condition { ... } else { ... }。 - 有界循环使用
repeat(count) { ... },周期任务使用强制命名的timer("name", ticks) { ... }。 component("id")返回当前页面会话中的安全组件对象,可以继续读取.parent、.layout和对应类型的数据块。- 给布局属性使用普通
=时保存当前计算结果;使用formula(...)时保存会持续重新计算的公式。 - 取整、保留小数、限制范围、插值、三角函数和随机数见数学函数。
- 组件 ID 建议只使用英文字母、数字、下划线和连字符。
vars.count = 1
vars.message = "欢迎回来"
vars.ready = true
component("title").visible = false
sound("sounds/click.ogg")编辑器脚本输入框适合使用分号在一行中组合多个动作:
vars.count = vars.count + 1; component("counter").visible = true; sound("sounds/click.ogg")字符串内部的分号不会被切开:
vars.message = "第一段;第二段"; packet("dialog:reply", vars.message)事件触发名
| 编辑器字段 | 含义 | 常见用途 |
|---|---|---|
leftPress / rightPress / middlePress | 对应按键在当前组件上按下时立即触发 | 按压动画、开始拖动、播放按下音效 |
leftRelease / rightRelease / middleRelease | 按下捕获仍有效时,松开对应按键触发 | 恢复缩放、结束拖动、停止持续状态 |
leftClick / rightClick / middleClick | 在同一组件上完成按下和松开后触发 | 确认、关闭、业务操作 |
hoverEnter | 指针第一次进入组件范围时触发 | 悬浮说明、路径切换、音效提示 |
hoverLeave | 指针离开组件范围时触发 | 恢复默认图片或隐藏提示 |
create | 当前组件实例创建时触发一次 | 初始化组件状态、动态复制后的设置 |
hoverEnter 不会在鼠标停留期间每帧重复运行;离开后再次进入,才会再次触发。
一次完整左键操作的顺序是 leftPress → leftRelease → leftClick。如果按下后把鼠标移到别处再松开,原组件可以收到 leftRelease,但不会收到 leftClick。组件在期间被隐藏、删除或禁用时,捕获会清理,不再继续触发。
按钮的选中变量、输入框焦点和物品槽交换都发生在有效的左键 Click 阶段。Press 和 Release 只执行各自脚本,不会提前完成点击行为。
唯一目标与防穿透
ChaUI 会从最前面的组件向后查找,每次只选一个组件作为当前目标。普通页面、世界页面和编辑器预览使用同一套规则,因此预览中验证通过的遮挡关系不会在实际打开后改变。
pointerEvents: auto:交互组件天然命中;普通展示组件只有配置事件或提示时才命中。pointerEvents: block:无论有没有事件,都挡住后方组件。pointerEvents: pass:完全忽略该组件,让指针继续寻找后方目标。visible: false:不显示也不遮挡。enabled: false:不执行自身行为,但仍然遮挡。
下面是一份可以直接复制的按钮配置。按下时缩小,松开时恢复,只有完整点击才执行确认动作:
vars:
confirmScale: 1
elements:
- id: confirm_button
type: button
parent: ""
visible: true
enabled: true
pointerEvents: auto
scale: vars.confirmScale
opacity: 1
z: 20
layout:
x: window.width * 0.5 - 45
y: window.height * 0.5 - 12
width: 90
height: 24
button:
label: "确认"
path: gui/default/confirm.png
hoverPath: gui/default/confirm_hover.png
events:
leftPress: |-
vars.confirmScale = 0.96
leftRelease: |-
vars.confirmScale = 1
leftClick: |-
log("确认完成")执行结果:鼠标按下时按钮围绕中心缩小;松开后恢复。只有按下和松开都落在同一个按钮上,聊天栏才会出现“确认完成”。
页面根级还支持 events.open、events.close、events.key.<按键名> 与 events.mouse.*。页面打开先执行 open,再按顺序执行所有初始组件的 create;普通关闭和 reload 关闭旧页面都会执行 close。键盘、鼠标和滚轮事件的配置表与示例见页面组件,完整按键名称和键盘 ID 见键盘对照表。
方法调用
页面根级 methods 中的脚本使用零参数调用:
methods.refresh()
方法.刷新()方法共享当前页面变量和组件状态,可以互相调用,但不能递归,也不接收参数或返回值。
字符串与参数
函数参数中的逗号和引号需要保留在字符串内。需要在双引号字符串中写入双引号时,可以使用反斜杠转义。
vars.message = "他说:\"欢迎回来\""
packet("dialog:reply", "同意,并继续", "第二项数据")复杂数据可以先整理为 JSON 字符串,再作为自定义包的一项数据发送:
packet("shop:select", "{\"item\":\"example\",\"amount\":2}")packet() 可以写在任何真实运行时会执行的事件、方法或计时器脚本中,不要求必须是点击事件。方法和计时器继承创建它们的原始页面或组件上下文;编辑器编辑状态与隔离预览不会发送。
条件分支
条件成立时执行 if 内的语句,否则执行 else。不需要其他分支时可以省略 else。
if vars.confirmed == true {
component("status").text.value = "已经确认"
component("confirm_button").enabled = false
} else {
component("status").text.value = "请先确认"
}中文别名同样可以用于条件和动作:
if 变量.confirmed == true {
组件("status").文本.内容 = "已经确认"
} else {
组件("status").文本.内容 = "请先确认"
}多步事件示例
下面的按钮会在第一次点击时显示详情区,再次点击时隐藏详情区。
vars:
detailsOpen: false # 记录当前详情区是否打开
elements:
- id: toggle_button
type: button
layout:
x: 20
y: 20
width: 100
height: 20
button:
label: "展开或收起"
events:
leftClick: |
if vars.detailsOpen == true {
vars.detailsOpen = false
component("details").visible = false
} else {
vars.detailsOpen = true
component("details").visible = true
}动作使用函数写法
页面动作统一使用 close()、open("detail_page")、sound("sounds/click.ogg") 这类函数写法。函数参数、字符串转义、条件块与分号组合都使用同一套规则,方便页面继续扩展。
函数参数是文字时要放在引号中;无参数动作也必须保留括号。例如关闭当前页面写 close(),打开另一页面写 open("detail_page")。
继续阅读变量与条件,可以了解页面变量、玩家状态和动态公式;循环与计时器则介绍 repeat、命名 timer 和页面关闭时的自动清理。
猹件开发组