gui
菜单 UI + 配置写入(唯一写路径)。容器创建后保存返回的 对象 引用,通过其方法挂载子元素。
顶层创建 + 查找
gui.tab(name) → Tab
参数:name : string —— 同时作为 id 和 label。
gui.sub_tab(parent, id, label) → Tab
参数:parent : Tab, id : string, label : string
gui.window(id, title, w, h, flags?) → Window
参数:id : string, title : string, w : number, h : number, flags? : int = 0
flags 用 gui.WINDOW.* 按位 OR / 直接相加组合。常用:
| 常量 | 作用 |
|---|---|
NoTitleBar | 无标题栏 |
NoResize | 禁止拖角缩放 |
NoMove | 禁止拖动 |
NoScrollbar / NoScrollWithMouse | 无滚动条 / 禁滚轮滚动 |
NoCollapse | 不可折叠 |
NoBackground | 透明(无底/无边框线) |
AlwaysAutoResize | 按内容自适应大小 |
NoSavedSettings | 不记忆位置/大小 |
NoMouseInputs / NoInputs | 鼠标穿透 / 完全不接收输入 |
NoFocusOnAppearing / NoBringToFrontOnFocus | 出现/点击不抢焦点 |
NoDecoration | = NoTitleBar+NoResize+NoScrollbar+NoCollapse(无边框 HUD 常用) |
无边框可拖 HUD:gui.window("hud", "", 250, 112, gui.WINDOW.NoDecoration + gui.WINDOW.NoFocusOnAppearing)。 窗口内自绘进度条/图形用 Window:custom(id, proto, h) 的 on_render(self,x,y,w,h)(窗口内容区屏幕坐标,随窗口移动);纯展示 custom(无鼠标 hook)不吃输入,无边框窗口可直接拖动 body 定位。
gui.find(path) → GUIElement | nil
参数:path : string —— full_path(点号分隔,如 "aimbot.master")
返回:派生类型 对象(Checkbox / Slider / Combobox / Window / Groupbox / Tab / …)。nil 表示路径不存在。
gui.children(path) → table<GUIElement>
参数:path : string —— 容器 full_path(Tab / Groupbox / Window / SettingsPopup)
返回:该容器直接子控件数组(类型透明,每项可直接 :get()/:set()/:set_hint())。非容器或路径不存在返回空表 {}。遍历某容器下控件(如做联动显隐)时用。
gui.get(path, fallback?) → value | fallback
参数:path : string, fallback? : any = nil
内部 = gui.find(path):get(),带 nil 检查。
gui.set(path, value)
参数:path : string, value : any
内部 = gui.find(path):set(value)。
gui.show(paths) / gui.hide(paths)
参数:paths : table<string> —— 控件 full_path 列表。
gui.set_enabled(paths, state) / gui.set_visible(paths, state)
参数:paths : table<string>, state : bool
主菜单状态
gui.is_visible() → bool
菜单当前是否打开(同步查询,跟 event.on("menu_toggled", fn) 等价但无需自维护 bool)。
gui.list_hotkeys() → table<GUIElement>
返实际绑了热键的全部 Checkbox + KeybindControl (vk = 0 的未绑控件不返)。顺序按内部插入序,跟 menu 显示顺序相同。
返的元素是类型透明的 (Checkbox / KeybindControl userdata),可直接调子类方法:
:get_full_path() → string— 用于input.is_active(path)查当前激活态:get_label() → string— 显示用 label:get() → bool— checkbox 当前值
配 input.format(path) 拿 "Ctrl+F1" 这种显示字符串。
-- 自定义热键 HUD:列当前所有热键控件 + 激活态 + 显示键
for _, elem in ipairs(gui.list_hotkeys()) do
local path = elem:get_full_path()
local key = input.format(path) -- "Ctrl+F1"
local on = input.is_active(path) -- 当前激活?
log.info((on and "[ON] " or "[off] ") .. elem:get_label() .. " " .. key)
end跟 fatality gui.GetHotkeyList() 对齐。
gui.get_main_window() → table { x, y, w, h, visible }
主菜单 ImGui 窗口的屏幕位置 + 大小 + 可见性。
| 字段 | 说明 |
|---|---|
x, y | 屏幕左上角坐标(像素,跟 draw.* 同坐标系) |
w, h | 当前显示大小(含淡入淡出动画过程的实时大小) |
visible | 等价 gui.is_visible() |
菜单完全关闭时 x/y/w/h 保留上次值,visible=false。菜单可拖动,x/y 会跟用户拖动更新(如拖到副屏)。
-- 附加浮窗跟随主菜单右侧
local win = gui.window("dock", "工具栏", 200, 400)
event.on("frame_update", function()
local m = gui.get_main_window()
if m.visible then
win:set_pos(m.x + m.w + 10, m.y)
win:show()
else
win:hide()
end
end)
-- 只在菜单关时画 ESP(避免菜单遮挡)
event.on("frame_update", function()
if gui.is_visible() then return end
draw.text(...)
end)Scenario-aware paths(自动链接图标)
任何 menu 控件的 full_path 中段含 .hidden. / .visible. / .knocked. / .teammate. 之一,引擎自动识别为 ESP scenario 字段,控件左侧画上链接图标(⛓️ linked / ⛓️💥 unlinked),切换时把当前值广播给其他 3 个 scenario 路径。链接状态持久化进 cfg.visual.esp_linked_fields,跨 plan 保存。
示例:
local tab = gui.tab("MyESP")
local scenarios = {"hidden", "visible", "knocked", "teammate"}
for _, sc in ipairs(scenarios) do
local g = tab:group(sc, sc, 0, 0, 0, 0)
g:color_edit("tint", "Tint", 1, 0, 0, 1)
g:slider_float("radius", "Radius", 1, 20, 5)
end
-- 4 个 "MyESP.<sc>.tint" / "MyESP.<sc>.radius" 自动获得链接图标
-- 点 ⛓️💥 → ⛓️ 时把当前 scenario 的值同步到其他 3 个路径读 scenario 值的两种姿态:
-- (A) ESP 绘制回调里:ctx.scenario 是引擎按"当前玩家"算好的(per-player)
esp.add({
id = "my_module",
fn = function(ctx)
local sc_name = ({[0]="hidden",[1]="visible",[2]="knocked",[3]="teammate"})[ctx.scenario]
local tint = gui.get("MyESP." .. sc_name .. ".tint")
return { text = "x", text_color = tint }
end,
})
-- (B) 非绘制上下文:脚本明示要读哪个 scenario
local visible_tint = gui.get("MyESP.visible.tint")不存在全局"当前 scenario" —— ESP 4 个 scenario 是对每个玩家的状态分类,N 个玩家可同时处于不同 scenario。esp.scenario 是菜单预览用的索引,不是任何玩家的 scenario,绘制逻辑请用 ctx.scenario 而非 esp.scenario。
限制:Lua 控件的链接传播只在用户点链接图标"切到链接"那一刻执行一次广播;之后改源值不会自动同步给其他 3 个路径(real-time per-frame propagation TODO)。C++ BIND_SCENARIO_FIELD 绑定的控件没有这个限制(每次写入都走 post_write 自动广播)。
武器配置读写
武器配置统一通过 gui.set / gui.get 访问,有两种路径,编辑同一份 WeaponConfig:
| 路径形态 | 编辑哪把武器 | 用例 |
|---|---|---|
菜单路径:aimbot.legit.fov.dead | 菜单当前选中武器(跟 UI 一致) | 跟 UI 交互一致,开"显示组件路径"复制即用 |
存储路径:aimbot.weapon.<id>.aim.fov_dead | 指定 <id> 那把(无视 UI 选中) | 批量改多把武器、跑预设、当前未存活也能写 |
菜单 tooltip:开"显示组件路径"后,per-weapon 控件 hover 时显示
Storage: aimbot.weapon.<id>.<field>+Menu: aimbot.legit.<...>,右键复制存储路径。batch(多选)模式额外显示(batch: N weapons)。全局控件(非 per-weapon)只显单行 menu 路径。
菜单路径(推荐日常用)
gui.set("aimbot.legit.fov.dead", 0.5) -- 当前选中武器:死区
gui.set("aimbot.legit.fov.hip", 12.0) -- 当前选中武器:腰射 FOV
gui.set("aimbot.legit.smoothadv.kp", 1.8)菜单选了什么武器,写到那把。default 选中时改 default;r301 选中时改 r301。
两个注意点:
- batch 模式只改第一把:UI 多选时 Lua 走菜单路径只写
selected_weapon_ids的第一把,不像手拖 slider 那样真批量。要批量改请改用存储路径加循环。 @weapon_id后缀强制指定:aimbot.legit.fov.dead@r301绕过 UI 选中,临时把这一行的 groupbox bind 到 r301。一次性写多把武器时这个比循环存储路径更接近 UI 心智模型。
存储路径(指定武器)
格式:aimbot.weapon.<weapon_id>.<sub_path>
<weapon_id>:字符串武器 ID,如"r301"/"flatline";"default"是 baseline<sub_path>:WeaponConfig 字段(嵌套 dot + 数组 1-based[n])
-- 指定武器:写死 ID(不受 UI 选中影响)
gui.set("aimbot.weapon.r301.aim.fov_hip", 12.5)
gui.set("aimbot.weapon.flatline.aim.fov_hip", 12.5)
gui.set("aimbot.weapon.default.filter_tags[3]", true)
-- 嵌套字段 / 数组
gui.set("aimbot.weapon.r301.aim.pid.kp", 1.8)
gui.get("aimbot.weapon.r301.aim.max_dist_range[2]")字段名跟 C++ 端 SCHEMA 同步,添 / 改 / 删字段后这里自动跟,wiki 不列字段穷举。
写入失败语义:以下三种情况都 silently no-op,不抛 Lua 错、不发布 config 快照:
- 武器 ID 未加进 armory(如
aimbot.weapon.unknown.aim.fov_hip)—— 不会静默 fallback 到 default - 字段不存在(typo,如
aimbot.weapon.r301.aim.fov_hipx) - 数组下标越界 / 类型错(如把 string 写进 float 字段)
读取(gui.get)同样:上述情况返 nil(或 fallback 参数)。
gui.get_active_override_path() → string
返当前手持武器实际生效的配置存储路径前缀。语义跟 aim 线程内部解析 (resolve_active_weapon) 完全对齐:
| 当前状态 | 返回 |
|---|---|
| 手持武器在编组 + 编组在 armory | "aimbot.weapon.<group_id>" |
| 手持武器独立 + 在 armory | "aimbot.weapon.<weapon_id>" |
| 手持武器未启用武器库(不在 armory) | "aimbot.weapon.default" |
| ClientData snapshot 不可用(DMA 未连 / 加载中) | "" |
local p = gui.get_active_override_path()
if p ~= "" then
gui.set(p .. ".aim.bone_target", 2) -- 改当前生效配置
end跟"菜单选中"不同:取的是游戏内手持的武器(lp.weapon_enum 经 enum_to_weapon_id 查表 + armory 校验),菜单里选 default 不影响。空串只在玩家死亡 / 加载中等 client_data 不可用时出现——其它任何活着的状态都至少能返 aimbot.weapon.default。
gui.get_selected_weapon() → string
返回武器库当前选中配置的武器 id(不是手持武器;手持武器用 gui.get_active_override_path())。配 aimbot.weapon.<wid>.lua.<id> 寻址 per-weapon Lua 值用。未选时返回 "default"。
local wid = gui.get_selected_weapon()
gui.set("aimbot.weapon." .. wid .. ".lua.my_gain", 1.5)通知(gui.notify)
gui.notify 是子表,按 : 调用:
gui.notify:info(text, dur?) / :success / :warn / :error
参数:text : string, dur? : number = 4.0(持续秒)
gui.notify:info("hello")
gui.notify:success("已应用预设", 2.5)
gui.notify:warn("距离过远", 1.5)
gui.notify:error("HTTP 失败:" .. err, 3.0)| level | 色 | 适合 |
|---|---|---|
| info | 白 | 普通操作反馈 |
| success | 绿 | 正向确认 |
| warn | 黄 | 软警告 |
| error | 红 | 错误告警 |
容器方法(Tab / Window / Groupbox 共享)
:group(id, label, x, y, w, h) → Groupbox
参数:id : string, label : string, x/y/w/h : number
:button(id, label, callback?) → Button
参数:id : string, label : string, callback? : function()
:checkbox(id, label, default) → Checkbox
参数:id : string, label : string, default : bool
:slider(id, label, min_v, max_v, def) → Slider (整型)
参数:id : string, label : string, min_v / max_v / def : int
:slider_float(id, label, min_v, max_v, def) → SliderFloat
参数:id : string, label : string, min_v / max_v / def : number
:range_slider_float(id, label, min_v, max_v, def_v1, def_v2, min_range?) → RangeSliderFloat
参数:5 个 number + min_range? : number = 0
:range_slider_int(id, label, min_v, max_v, def_v1, def_v2, min_range?) → RangeSliderInt
参数:5 个 int + min_range? : int = 0
:dropdown(id, label, items, def) → Combobox
参数:id : string, label : string, items : table<string>, def : int (1-based 默认索引;binding 层 def-1 转 0-based 内部存储。gui.get/set 直接读写内部字段所以是 0-based int)
(usertype 名仍叫 Combobox——历史命名,控件方法节用这个名字。多选版本是 :multi_dropdown。)
:input_text(id, label, def) → InputText
参数:id : string, label : string, def : string
:color_edit(id, label, r, g, b, a?) → ColorEdit
参数:id : string, label : string, r / g / b : number, a? : number = 1.0
:multi_dropdown(id, label, items, defaults?) → MultiDropdown
参数:id : string, label : string, items : table, defaults? : table<bool>
:keybind_control(id, label, def_key?, def_mode?) → KeybindControl
参数:id : string, label : string, def_key? : int = 0, def_mode? : int = 0
:live_table(id, headers, provider, height?) (Window / Groupbox only)
参数:id : string, headers : table<string>, provider : function() → table<row>, height? : number = 0
row 形态:{cell1, cell2, ...} 数组 或 {cells = {...}, color = {r,g,b,a}} 表
:tips(id, text, icon?, color?) (Window / Groupbox / SettingsPopup)
参数:id : string, text : string, icon? : string, color? : table<r,g,b,a>
:settings(id, label, icon?) → SettingsPopup
参数:id : string, label : string(齿轮左侧文字,可空), icon? : string(齿轮图标,默认 ⚙)
齿轮折叠容器(对标 fatality gui.Settings):行上 label ⚙,点齿轮弹 popup,子控件画在 popup 里。详见下方「设置齿轮容器」。
自定义控件 (LuaControlProto 风格)
container:custom(id, proto, height?) → CustomControl
参数:
id : string— 控件 idproto : table— 控件原型,持有 on_* lifecycle callback 跟initial_dataheight? : number = 24— 控件高度像素
返回 CustomControl userdata。允许同一个 proto 实例化多个控件,initial_data 自动深拷贝避免共享。
proto 表里所有 lifecycle 字段都可选:
| 字段 | 签名 | 触发时机 |
|---|---|---|
initial_data | table | 实例 data 初始值,深拷贝到 self.data |
on_render | fn(self, x, y, w, h) | 每帧绘制,box 是 (x, y) → (x+w, y+h) 屏幕坐标 |
on_first_render | fn(self) | 首帧 (data 从持久化加载完后调) |
on_mouse_down | fn(self, btn) | 鼠标按下 (0=left, 1=right, 2=middle, 3=x1, 4=x2),hover 时触发 |
on_mouse_up | fn(self, btn) | 鼠标松开 (不要求 hover) |
on_mouse_move | fn(self, dx, dy) | hover 时鼠标坐标 (相对控件左上角) |
on_focus | fn(self) | 控件 active (持有鼠标) 边沿 |
on_blur | fn(self) | active 失去边沿 |
on_key | fn(self, imgui_key) | hover 时键盘按下边沿 (no-repeat) |
on_reset | fn(self) | self:reset() 主动调时 |
CustomControl 实例方法
| 方法 | 说明 |
|---|---|
self.data : table | 实例数据,read/write。整体替换或 self.data.foo = x 都 OK |
self:lock_input() | 标记输入锁定 (持有鼠标时 ImGui 自动锁,这里只是 hint) |
self:unlock_input() | 释放锁 |
self:is_hovered() → bool | 上一帧鼠标是否 hover 在控件内 |
self:is_focused() → bool | 上一帧是否持有鼠标 (active) |
self:is_input_locked() → bool | lock_input 状态查询 |
self:get_height() → number / :set_height(h) | 控件高度 |
self:reset() | 触发 on_reset callback |
持久化
self.data 自动保存到 cfg.lua.<full_path> (跟 lua-created checkbox 同套机制)。脚本 reload / plan 切换都恢复上次 data。 on_first_render 在 data 加载完后调,允许用持久化数据初始化。
-- Counter — 点击 +1 右键 -1,关菜单重开 count 不丢
local Counter = {
initial_data = { count = 0 },
on_render = function(self, x, y, w, h)
local bg = self:is_hovered() and draw.rgba(0.25, 0.30, 0.40, 1)
or draw.rgba(0.15, 0.18, 0.22, 1)
draw.rect(x, y, x+w, y+h, bg, { filled = true, rounding = 3 })
draw.text(x + 8, y + 8, draw.rgba(1, 1, 1, 1),
"Count: " .. tostring(self.data.count), { outline = true })
end,
on_mouse_down = function(self, btn)
if btn == 0 then self.data.count = self.data.count + 1
elseif btn == 1 then self.data.count = self.data.count - 1 end
end,
}
local grp = gui.tab("misc"):group("g", "demo", 0, 0, 350, 0)
grp:custom("counter1", Counter, 28)完整 demo 见 out/Debug/scripts/custom_control_demo.lua (Counter / Pulse / Bar 3 例)。
设置齿轮容器 (SettingsPopup)
container:settings(id, label, icon?) → SettingsPopup 创建一个齿轮折叠容器(对标 fatality gui.Settings / cogwheel):行上显示 label ⚙,点齿轮弹 popup,子控件画在 popup 里。齿轮 + popup 全由 C++ 框架绘制,Lua 只负责创建 + 加子控件。
适合把"次要 / 高级设置"折叠进齿轮——主菜单只留一行,不用一堆参数铺开,也省去按选择逐帧 set_visible 显隐。
子控件工厂(与 Groupbox 同套;子控件的持久化 / 热键 / per-weapon 写入全自动): button / checkbox / slider / slider_float / dropdown / input_text / color_edit / range_slider_float / range_slider_int / multi_dropdown / keybind_control / tips / custom
实例方法:
| 方法 | 说明 |
|---|---|
s:add_child(elem) / s:remove_child(elem) / s:clear_children() / s:remove_children_by_owner(path) | 子控件增删(同其它容器, 但 remove_child / clear_children 返回 self 可链式) |
s:set_gear_icon(icon) → self | 换齿轮图标 |
s:set_popup_width(px) → self | popup 逻辑宽度(默认 260) |
local grp = gui.tab("misc"):group("g", "demo", 0, 0, 350, 0)
local adv = grp:settings("adv", "高级设置") -- 行上 "高级设置 ⚙"
adv:slider("speed", "速度", 0, 100, 50)
adv:slider_float("ratio", "比例", 0.0, 1.0, 0.5):set_format("%.2f")
adv:checkbox("smooth", "平滑", true)
adv:set_popup_width(220)容器通用方法
Tab / Groupbox / Window 共有的子节点操作。多数脚本不用碰 —— 控件创建用 :checkbox / :slider / :group 等更简洁;这套低层 API 给动态增删场景(hot-reload 自维护、运行时按条件加控件)。
:add_child(elem)
手动挂一个 GUI element, 无返回值。
:remove_child(elem)
删一个直接子节点, 传元素对象(不是 id 字符串), 无返回值。
:remove_children_by_owner(script_path)
删除该 owner 创建的全部子节点, 无返回值。脚本卸载会自动跑这条, 手动调通常不必要。
:clear_children()
清空所有子节点。
Tab:is_lua_tab() → bool
是否是 Lua 脚本通过 gui.tab(...) 创建的(区分 cpp 内置 tab)。脚本想避开内置 tab 时用。
Window 独有方法
Window:is_open() → bool / Window:set_open(bool)
Window:bind_visible(checkbox) → Window
参数:checkbox : Checkbox —— 引用任一 Checkbox 对象(来自 :checkbox(...) 返回值)
每帧自动同步 Window.open = checkbox.value,省去手写 live_table provider 里 set_open 的麻烦。
Checkbox / Slider / Combobox 等控件方法
Checkbox / Slider / SliderFloat 多热键
2026-05-25 UX 重设计:每个 Checkbox / Slider 都支持多条热键,右键控件打开 popup 管理。Switch / Slider 右上角显示首条热键 + 计数 (Ctrl+F1 +2)。Popup 内每条热键含 [主键][模式][🗑],Slider 多一个 [⚙] 设触发时的独立 value (拨回该值)。
-- Checkbox 多热键: 任一激活 → checkbox = true
local cb = group:checkbox("aim", "Aimbot", false)
cb:add_hotkey({ vk = 0x70, mode = 1 }) -- F1 Hold
cb:add_hotkey({ vk = 0x71, mode = 0, modifier = 0x11 }) -- Ctrl+F2 Toggle
cb:clear_hotkeys() -- 清空
-- Slider 多热键 + 独立 value: 触发 F3 把 slider 写为 50
local sl = group:slider("fov", "FOV", 0, 100, 30)
sl:add_hotkey({ vk = 0x72, mode = 0, value = 50 }) -- F3 Toggle → write 50
sl:add_hotkey({ vk = 0x73, mode = 0, value = 80 }) -- F4 Toggle → write 80热键模式:0=Toggle / 1=Hold / 2=Always。Modifier 用 0x10=Shift / 0x11=Ctrl / 0x12=Alt。
Checkbox:set_keybind(vk, mode, modifier?)
参数:
vk : int— 主键虚拟键码mode : int— 0=Toggle / 1=Hold / 2=Alwaysmodifier : int?— 可选修饰键,VK_CONTROL(0x11) /VK_SHIFT(0x10) /VK_MENU(0x12,即 Alt);不传或 0 = 无修饰键
示例:
cb:set_keybind(0x70, 0) -- F1 单键,Toggle
cb:set_keybind(0x70, 1, 0x11) -- Ctrl + F1,HoldCheckbox:set_colors(table) / Checkbox:get_colors() → table
为带 keybind 状态的 checkbox 配色(当前/inactive/hover/...),table 见源码。
:set_hint(text) → self
有此方法的控件:Checkbox / Slider / SliderFloat / RangeSliderFloat / RangeSliderInt / InputText / KeybindControl。Combobox / MultiDropdown / ColorEdit / Button 没有 :set_hint。
:set_width(px) → self / :get_width() → number
参数:px : number —— 控件像素宽;0 或省略 = 自动吃满整行。
GUIElement 基类方法,所有控件可调;实际生效的是 Slider / SliderFloat / Combobox(其余控件存而不用)。grp:slider("id","label",0,100,5):set_width(120)。
:set_per_weapon(enable?) → self / :is_per_weapon() → bool
参数:enable? : bool = true
让控件值按"武器库当前选中武器"分别存储(仅对 Lua 控件生效)。开启后切换武器库选中的武器,控件自动显示那把武器的值;未单独设过的武器回退到 default 武器的值。链式置于末尾(返回基类,后面只接 :set_visible 等基类方法)。
值存在 aimbot.weapon.<wid>.lua.<控件id>,脚本可经此路径 gui.get/set 点名任意武器读写;切换武器时控件自动显示选中武器的值,未单独设过的武器回退 default 武器的值。
仅值类控件(checkbox / slider / slider_float / combobox / input_text)生效;带 keybind 或 colors 的控件不支持 per-weapon。同一寻址下控件 id 须唯一。
local grp = gui.find("aimbot.legit.smoothadv")
grp:slider_float("lua_gain", "Lua 增益", 0, 5, 1):set_format("%.2f"):set_per_weapon(true)Slider:set_format(fmt) → Slider / SliderFloat:set_format / RangeSliderFloat:set_format / RangeSliderInt:set_format
Combobox:on_change(fn) → Combobox
参数:fn : function(idx_1based : int, name : string) —— 1-based 索引 + 选中项字符串
Combobox:add_item(item) → Combobox / add_items(items) / remove_item(idx_or_name) / clear_items()
Combobox:get_selected_name() → string / get_items() → table<string>
InputText:set_size(vec2)
Button:set_size(vec2) / set_icon(string)
ColorEdit:set_colors(table) / set_alpha(bool)
MultiDropdown:add_item(item, default?) / add_items(items) / remove_item(idx_or_name) / clear_items() / get_selected_names() → table<string>
GUIElement 基类方法(所有控件继承)
:get_id() → string / :get_owner() → string / :get_label() → string / :set_label(str)
:is_enabled() → bool / :set_enabled(bool) / :is_visible() → bool / :set_visible(bool)
:get() → value / :set(value) / :has_value() → bool
路径访问该控件当前值的统一接口(与 gui.get / gui.set 等价)。
:bind_weapon(...) / :get_target_weapon(...)
控件级武器绑定(高级用户)。
示例
local tab = gui.tab("MyTab")
local g = tab:group("g", "我的分组", 0, 0, 0, 0)
local cb = g:checkbox("enable", "启用", false)
:set_hint("勾上后开启功能")
local sl = g:slider_float("scale", "Scale", 0.0, 5.0, 1.0)
:set_format("%.2fx")
local cb_theme = g:dropdown("theme", "主题",
{ "Default", "Dark", "Light" }, 1)
:on_change(function(idx_1based, name)
log.info("主题切到:" .. name)
end)
g:button("reset", "复位", function()
gui.set("MyTab.g.enable", false)
gui.set("MyTab.g.scale", 1.0)
end)