Merge branch 'main' into gitlocalize-35558

This commit is contained in:
Tixx
2026-05-20 11:49:54 +02:00
committed by GitHub
16 changed files with 4397 additions and 32 deletions
+12
View File
@@ -0,0 +1,12 @@
!!! warning "本页面正在建设中!"
```
本站点目前正处于积极开发与维护阶段。
觉得您可以提供帮助?请点击页面右侧的铅笔图标参与编辑!
此操作适用于站内的任何页面。
```
# BeamNG.drive CEF Code 的片段
to-do
+189
View File
@@ -0,0 +1,189 @@
!!! warning "本页面正在建设中!"
```
本站点目前正处于积极开发与维护阶段。
觉得您可以提供帮助?请点击页面右侧的铅笔图标参与编辑!
此操作适用于站内的任何页面。
```
# BeamNG.drive CSS Code 的片段
## 常见变量
=== BeamNG Orange
```
```css
var(--bng-orange) /*Common orange*/
var(--bng-orange-shade1) /*70% opacity*/
var(--bng-orange-shade2) /*40% opacity*/
var(--bng-orange-shade1opaque)
var(--bng-orange-shade2opaque)
```
```
=== Monochrome
```
```css
--- Monochrome
var(--bng-black-8) /*80% opacity (duplicate --bng-black-o8)*/
var(--bng-black-6) /*60% opacity (duplicate --bng-black-o6)*/
var(--bng-black-4) /*40% opacity (duplicate --bng-black-o4)*/
var(--bng-black-2) /*20% opacity (duplicate --bng-black-o2)*/
var(--dark-neutral-grey)
var(--neutral-grey)
var(--light-neutral-grey)
var(--dark-grey)
var(--dark-grey-alpha) /*80% opacity*/
var(--black-1) /*70% opacity*/
var(--black-2) /*40% opacity (duplicate --bng-black-o4)*/
var(--white-1) /*80% opacity*/
var(--white-2) /*40% opacity*/
var(--white-3) /*20% opacity*/
```
```
=== BeamNG 界面颜色调色板
```
=== Orange
```css
var(--bng-orange-50)
var(--bng-orange-100)
var(--bng-orange-200)
var(--bng-orange-300)
var(--bng-orange-b400)
var(--bng-orange-500)
var(--bng-orange-600)
var(--bng-orange-700)
var(--bng-orange-800)
var(--bng-orange-900)
```
=== Cool Gray
```css
var(--bng-cool-gray-50)
var(--bng-cool-gray-100)
var(--bng-cool-gray-200)
var(--bng-cool-gray-300)
var(--bng-cool-gray-400)
var(--bng-cool-gray-500)
var(--bng-cool-gray-600)
var(--bng-cool-gray-700)
var(--bng-cool-gray-800)
var(--bng-cool-gray-900)
```
=== Ter Blue
```css
var(--bng-ter-blue-50)
var(--bng-ter-blue-100)
var(--bng-ter-blue-200)
var(--bng-ter-blue-300)
var(--bng-ter-blue-400)
var(--bng-ter-blue-500)
var(--bng-ter-blue-600)
var(--bng-ter-blue-700)
var(--bng-ter-blue-800)
var(--bng-ter-blue-900)
```
=== Add Blue
```css
var(--bng-add-blue-50)
var(--bng-add-blue-100)
var(--bng-add-blue-200)
var(--bng-add-blue-300)
var(--bng-add-blue-400)
var(--bng-add-blue-500)
var(--bng-add-blue-600)
var(--bng-add-blue-700)
var(--bng-add-blue-800)
var(--bng-add-blue-900)
```
=== Add Green
```css
var(--bng-add-green-50)
var(--bng-add-green-100)
var(--bng-add-green-200)
var(--bng-add-green-300)
var(--bng-add-green-400)
var(--bng-add-green-500)
var(--bng-add-green-600)
var(--bng-add-green-700)
var(--bng-add-green-800)
var(--bng-add-green-900)
```
=== Add Yellow
```css
var(--bng-add-yellow-50)
var(--bng-add-yellow-100)
var(--bng-add-yellow-200)
var(--bng-add-yellow-300)
var(--bng-add-yellow-400)
var(--bng-add-yellow-500)
var(--bng-add-yellow-600)
var(--bng-add-yellow-700)
var(--bng-add-yellow-800)
var(--bng-add-yellow-900)
```
=== Add Peach
```css
var(--bng-add-peach-50)
var(--bng-add-peach-100)
var(--bng-add-peach-200)
var(--bng-add-peach-300)
var(--bng-add-peach-400)
var(--bng-add-peach-500)
var(--bng-add-peach-600)
var(--bng-add-peach-700)
var(--bng-add-peach-800)
var(--bng-add-peach-900)
```
=== Add Red
```css
var(--bng-add-red-50)
var(--bng-add-red-100)
var(--bng-add-red-200)
var(--bng-add-red-300)
var(--bng-add-red-400)
var(--bng-add-red-500)
var(--bng-add-red-600)
var(--bng-add-red-700)
var(--bng-add-red-800)
var(--bng-add-red-900)
```
```
=== 额外颜色预设
```
```css
var(--bng-filter-orange) /*Filter preset to force SVGs to use bng-orange*/
var(--bng-black-o8) /*80% opacity*/
var(--bng-black-o6) /*60% opacity*/
var(--bng-black-o4) /*40% opacity*/
var(--bng-black-o2) /*20% opacity*/
```
```
=== 圆角预设
```
```css
var(--bng-corners-1) /*0.25rem*/
var(--bng-corners-2) /*0.50rem*/
var(--bng-corners-3) /*1.00rem*/
```
```
@@ -0,0 +1,88 @@
!!! warning "本页面正在建设中!"
```
本站点目前正处于积极开发与维护阶段。
觉得您可以提供帮助?请点击页面右侧的铅笔图标参与编辑!
此操作适用于站内的任何页面。
#创建 ImGui 窗口
```
本页将介绍如何创建一个基础的 ImGui 窗口。
## 设置
在开始使用 ImGui 之前,需要进行一些基础设置:
```lua
local im = ui_imgui -- 缩写以避免频繁查找。这有助于性能优化
local imguiExampleWindowOpen = im.BoolPtr(true)
```
`imguiExampleWindowOpen` 将用于决定该示例窗口是否应当进行渲染。
## 窗口渲染
ImGui 窗口及其内容必须在每一个需要显示的帧中重新创建。这意味着,若要使用 ImGui,必须通过某种形式的onUpdate函数来实现。
```lua
local function onUpdate()
if worldReadyState == 2 then
if imguiExampleWindowOpen[0] == true then
imguiExample()
end
end
end
M.onUpdate = onUpdate
```
只要关卡已完全加载,且示例窗口处于应当显示的状态,这段代码就会运行一个函数来创建该示例窗口。
## 窗口内容
如果您是初次编写 ImGui,可以把ImGui看作 HTML 的亲戚:
- `im.SetNextWindowSize(im.ImVec2(x, y), im.Cond_FirstUseEver)` 用于在尚未定义视口尺寸的情况下,对其进行初始化定义。
- `im.Begin()``im.End()`相当于你的 `<body>``</body>`
- `im.Text()` 相当于你的 `<p></p>`
```lua
local buttonPresses = 0
local function imguiExample()
im.SetNextWindowSize(im.ImVec2(366, 100), im.Cond_FirstUseEver) -- 准备窗口尺寸
im.Begin("Hello World, I am a window") -- 创建一个标题为“Hello World, I am a window”的窗口
im.Indent() -- 缩进元素(类似于内边距)
im.Text("Hello World, I am text.") -- 添加一行文本,类似于 <p> 标签
im.SameLine() -- 与 HTML 不同,这会将下一个元素附加到上一个元素的同一行
if im.Button("The Hello World Button") then -- 类似于 <button>。点击时运行 Lua 代码
buttonPresses = buttonPresses + 1
end
if buttonPresses > 0 then
im.Text("The Hello World Button has been pressed " .. buttonPresses .. " times!")
else
im.Text("The Hello World Button has not been pressed.")
end
im.Unindent() -- 结束缩进
im.End() -- 完成“画布”以便进行渲染
end
```
您可以添加以下函数,以便轻松切换窗口的可见性:
```lua
local function toggleExampleImgui()
imguiExampleWindowOpen[0] = not imguiExampleWindowOpen[0]
end
```
## 结果
<figure class="image image_resized" style="width:100%" markdown=""> ![演示游戏内使用的 ImGui 示例代码](../../../../assets/content/imguiExample.png) </figure>
当The Hello World Button按钮被按下时,其下方的计数器将更新,并显示The Hello World Button按钮被按下的次数。
## 下载
本教程几乎完全基于 [StanleyDudek](https://github.com/StanleyDudek) 的 ImGui 示例模组(Mod)。您可以从[此处](../../../../assets/content/imguiExample.zip)下载该示例模组。
@@ -0,0 +1,3 @@
# imgui-windows.md
此页面需要创建。
+83
View File
@@ -0,0 +1,83 @@
!!! warning "本页面正在建设中!"
```
本站点目前正处于积极开发与维护阶段。
觉得您可以提供帮助?请点击页面右侧的铅笔图标参与编辑!
此操作适用于站内的任何页面。
```
# BeamNG.drive ImGui Code 的片段
## 配置
### 配置 ImGui
```lua
local im = ui_imgui
```
### 配置 Window
```lua
im.SetNextWindowSize(im.ImVec2(366, 100), im.Cond_FirstUseEver)
```
### 创建 window
```lua
im.Begin("Window Title") -- Create window
im.End()
```
## 一般演示
=== 基本格式
```
```lua
im.Text("") -- 普通文本
im.TextWrapped("") -- 自动换行文本
im.TextColored(im.ImVec4(0,1,0,1), "") -- 彩色文本(参数为 R,G,B,A
im.TextDisabled("") -- 禁用状态样式的文本(预设样式)
im.LabelText("", "") -- 带标签的文本
im.BulletText("") -- 带项目符号(圆点)的文本
im.SeparatorText("") -- 带中间文字的分隔线
im.Separator() -- 分隔线(在添加前可能需要换行)
im.SameLine() -- 将下一个元素水平附加到上一个元素之后
im.NewLine() -- 换行
im.Spacing() -- 微小间距(填充)
im.Indent() -- 缩进
im.Unindent() -- 取消缩进
```
```
=== 输入
```
```lua
im.Button("", im.ImVec2(0,0)) -- 按钮(0 = 自动适应内容大小)
im.SmallButton("") -- 小按钮(适应内容且内边距更小)
im.ArrowButton("", 0) -- 箭头按钮(参数1:字符串实际未被使用?参数2:0=左,1=右,2=上,3=下)
im.InvisibleButton("", im.ImVec2(0,0), ...) -- 不可见按钮(用于 ImGui 光标定位?)
im.Checkbox("", im.BoolPtr(false)) -- 复选框
im.RadioButton1("", im.BoolPtr(false)) -- 单选框 1
im.RadioButton2("", im.IntPtr(), 0) -- 单选框 2(参数3:0 或 1,分别代表禁用或启用状态)
```
```
=== 其他
```
```lua
im.Bullet()
im.ProgressBar(0.5, im.ImVec2(0,0), "") -- 进度条(参数 2:填 0 则使用默认宽度和/或高度)
im.TextUnformatted("", "") -- 非格式化文本(第二个参数似乎会导致游戏崩溃)
```
```
+3 -3
View File
@@ -1,6 +1,6 @@
# 欢迎来到 车祸模拟器 文档
# 欢迎来到 BeamNG.drive 文档
本文档是非官方的,由车祸模拟器模组团队和车祸模拟器社区制作。
本文档是非官方的,由BeamMP模组团队和BeamNG社区制作。
## 了解文件结构
@@ -8,4 +8,4 @@
## 片段
可以在这里找到有用的代码片段:[代码片段](snippets.md)
对您可能有用的代码片段可以在这里找到: [Lua Snippets](lua-snippets.md)
+346
View File
@@ -0,0 +1,346 @@
!!! warning "本页面正在建设中!"
```
本站点目前正处于积极开发与维护阶段。
觉得您可以提供帮助?请点击页面右侧的铅笔图标参与编辑!
此操作适用于站内的任何页面。
```
# BeamNG.drive Lua Code 的片段
## 世界
### 绘制标记&amp;车辆检测
在地图上绘制标记是告知用户该处存在某种交互形式的最佳方式之一。
绘制标记相当简单。以下是巴士路线标记绘制方式的一个示例:
```lua
local function createBusMarker(markerName)
local marker = createObject('TSStatic')
marker:setField('shapeName', 0, "art/shapes/interface/position_marker.dae")
marker:setPosition(vec3(0, 0, 0))
marker.scale = vec3(1, 1, 1)
marker:setField('rotation', 0, '1 0 0 0')
marker.useInstanceRenderData = true
marker:setField('instanceColor', 0, '1 1 1 0')
marker:setField('collisionType', 0, "Collision Mesh") -- 碰撞类型:碰撞网格
marker:setField('decalType', 0, "Collision Mesh") -- 贴花类型:碰撞网格
marker:setField('playAmbient', 0, "1") -- 播放环境动画
marker:setField('allowPlayerStep', 0, "1") -- 允许玩家踏上
marker:setField('canSave', 0, "0") -- 是否可保存
marker:setField('canSaveDynamicFields', 0, "1") -- 是否可保存动态字段
marker:setField('renderNormals', 0, "0") -- 渲染法线
marker:setField('meshCulling', 0, "0") -- 网格剔除
marker:setField('originSort', 0, "0")
marker:setField('forceDetail', 0, "-1")
marker.canSave = false
marker:registerObject(markerName)
scenetree.MissionGroup:addObject(marker)
return marker
end
-- 随后可以在循环中调用此函数来设置您的标记。
-- 注意:您应该只在初始化设置时执行一次,而不是在每一帧都调用。
if #markers == 0 then
for k,v in pairs(nameMarkers) do
local mk = scenetree.findObject(v)
if mk == nil then
log('I', logTag,'Creating marker '..tostring(v)) -- 正在创建标记...
mk = createBusMarker(v)
ScenarioObjectsGroup:addObject(mk.obj)
end
table.insert(markers, mk)
end
end
```
这是来自 [BeamNG-FuelStations](https://github.com/BeamMP/BeamNG-FuelStations/tree/master) 的自定义标记示例:
```lua
local stations = [
{ "location": [ -778.813, 485.973, 23.46 ], "type":"gas" }, -- 燃油站
{ "location": [ 617.164, -192.107, 53.2 ], "type":"ev" }, -- 充电站
]
-- 检查实体是否在区域内
local function IsEntityInsideArea(pos1, pos2, radius)
return pos1:distance(pos2) < radius
end
local onUpdate = function (dt)
for k, spot in pairs(stations) do -- 遍历当前地图上的所有站点
local bottomPos = vec3(spot.location[1], spot.location[2], spot.location[3])
local topPos = bottomPos + vec3(0,0,2) -- 偏移向量以获得顶部位置(2米高)
local spotInRange = false -- 站点是否在范围内?用于颜色判定
local spotCompatible = false -- 站点是否匹配(燃料类型)?
if activeVeh then -- 如果存在车辆且属于当前玩家(若在多人模式下)
local vehPos = activeVeh:getPosition()
-- 检查车辆是否在站点 1.5 米范围内
spotInRange = IsEntityInsideArea(vec3(vehPos.x, vehPos.y,vehPos.z), bottomPos, 1.5)
-- 检查燃料类型是否匹配
spotCompatible = activeFuelType == "any" or spot.type == "any" or activeFuelType == spot.type
end
-- 确定站点颜色:如果范围内且匹配,则使用活动颜色,否则使用非活动颜色或默认半透明白色
local spotColor = (spotInRange and spotCompatible) and activeColorMap[spot.type] or inactiveColorMap[spot.type] or ColorF(1,1,1,0.5)
-- 绘制圆柱体:底部位置,顶部位置,半径,颜色
debugDrawer:drawCylinder(bottomPos:toPoint3F(), topPos:toPoint3F(), 1, spotColor)
end
end
```
## 用户界面
### 屏幕右上角弹出的通知
<figure class="image image_resized" style="width:75%" markdown=""> ![image](https://github.com/StanleyDudek/Docs/assets/49531350/c8a87842-b95a-4eca-84dc-93072ecc9158) </figure>
```lua
--guihooks.trigger('toastrMsg', {type, title, msg, config = {timeOut}})
guihooks.trigger('toastrMsg', {type = "info", title = "Info Message:", msg = "Info Message Text Here", config = {timeOut = 5000}})
guihooks.trigger('toastrMsg', {type = "warning", title = "Warning Message:", msg = "Warning Message Text Here", config = {timeOut = 5000}})
guihooks.trigger('toastrMsg', {type = "error", title = "Error Message:", msg = "Error Message Text Here", config = {timeOut = 5000}})
```
### 消息通知,默认显示在消息应用的屏幕左上角
这需要安装“消息”或“消息与任务”UI 应用。图标可以在此处找到: `ui\ui-vue\src\assets\fonts\bngIcons\svg这需要安装“消息”或“消息与任务”UI 应用。图标可以在此处找到:
<figure class="image image_resized" style="width:75%" markdown=""> ![image](https://github.com/StanleyDudek/Docs/assets/49531350/6baef813-50cb-43c3-9c59-0de550b014b6) </figure>
```lua
--guihooks.trigger('Message', {msg, ttl, category, icon})
--ui_message(msg, ttl, category, icon)
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "arrow_upward", icon = "arrow_upward"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "arrow_downward", icon = "arrow_downward"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "flag", icon = "flag"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "check", icon = "check"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "check_circle", icon = "check_circle"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "warning", icon = "warning"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "error", icon = "error"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "directions_car", icon = "directions_car"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "star", icon = "star"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "timeline", icon = "timeline"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "save", icon = "save"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "settings", icon = "settings"})
```
### 屏幕中央大尺寸或小尺寸闪烁显示
<figure class="image image_resized" style="width:75%" markdown=""> ![image](https://github.com/StanleyDudek/Docs/assets/49531350/d0cf754f-83f8-4d15-9159-27350da127de) </figure>
<figure class="image image_resized" style="width:75%" markdown=""> ![image](https://github.com/StanleyDudek/Docs/assets/49531350/1df6fc9b-756f-484e-b8d9-5df346dc4c26) </figure>
```lua
--guihooks.trigger('ScenarioFlashMessage', {{msg, ttl, sound, big}} ) -- requires RaceCountdown ui app
guihooks.trigger('ScenarioFlashMessage', {{"Message", 5.0, 0, true}} )
guihooks.trigger('ScenarioFlashMessage', {{"Message Text Here", 5.0, 0, false}} )
--countdown example, when all executed at once, the items are queued and will follow eachother after the previous ttl expires
guihooks.trigger('ScenarioFlashMessage', {{"3", 1.0, "Engine.Audio.playOnce('AudioGui', 'event:UI_Countdown1')", true}})
guihooks.trigger('ScenarioFlashMessage', {{"2", 1.0, "Engine.Audio.playOnce('AudioGui', 'event:UI_Countdown2')", true}})
guihooks.trigger('ScenarioFlashMessage', {{"1", 1.0, "Engine.Audio.playOnce('AudioGui', 'event:UI_Countdown3')", true}})
guihooks.trigger('ScenarioFlashMessage', {{"GO!", 3.0, "Engine.Audio.playOnce('AudioGui', 'event:UI_CountdownGo')", true}})
--另一个声音示例
guihooks.trigger('ScenarioFlashMessage', {{"Teleported!", 3.0, "Engine.Audio.playOnce('AudioGui', 'event:UI_Checkpoint')", false}})
```
### 屏幕中央中等尺寸持久显示
这需要安装实时竞赛显示UI 应用。
<figure class="image image_resized" style="width:75%" markdown=""> ![image](https://github.com/StanleyDudek/Docs/assets/49531350/6290e018-6b3d-4674-98f2-34282a723258) </figure>
```lua
--guihooks.trigger('ScenarioRealtimeDisplay', {msg = msg} ) -- 需要安装 Race Realtime Display UI 应用
guihooks.trigger('ScenarioRealtimeDisplay', {msg = "在此输入消息文本"} )
-- 这些消息会持久显示,可以通过发送空字符串来清除
-- 如果您正在运行实时数据(例如计时器、距离计算等),这是一个非常适合快速更新的接口
guihooks.trigger('ScenarioRealtimeDisplay', {msg = ""} )
```
### 确认对话框
确认对话框是一个带有多达两个按钮的简化弹出窗口。
```lua
-- 打开一个包含标题、正文文本和最多两个按钮的确认对话框(ConfirmationDialog
guihooks.trigger("ConfirmationDialogOpen",
"示例标题",
"示例正文文本内容",
"确定",
"", -- 对应的 gelua 代码,此处为空字符串
"取消",
"" -- 对应的 gelua 代码
)
-- 关闭任何具有指定标题的已打开确认对话框
guihooks.trigger("ConfirmationDialogClose", "示例标题")
```
<figure class="image image_resized" style="width:75%" markdown=""> ![Example of a ConfirmationDialog](../../assets/content/ConfirmationDialog.png) </figure>
按钮的两个字段都必须为字符串类型,按钮才会显示。
如果提供了确定按钮,按下 *确定 / 首要操作(OK / Primary action* 键等同于点击“确定”按钮。
如果提供了取消按钮,按下 *菜单(Menu)*键等同于点击取消按钮。
支持HTML,例如可以用来添加图片或图标。
可以同时显示多个,并将按顺序排列显示。
!!! bug
```
如果不提供任何按钮,玩家将无法在不使用控制台的情况下关闭或退出该对话框。
```
!!! bug
```
当 ConfirmationDialog(确认对话框)处于活动状态时,迷你地图UI应用的 SDF 部分仍然保持可见。
可以使用 `#!lua guihooks.trigger('ShowApps', false)` 隐藏 UI 应用,作为一种临时解决方案。
```
<figure class="image image_resized" style="width:75%" markdown=""> ![确认对话框用于挂机踢出系统](../../assets/content/ConfirmationDialog_Example.png) </figure>
### introPopupTutorial
introPopupTutorial 是一个高度可定制的弹出窗口,很大程度上是通过嵌入式 HTML 来定义的。通常的做法是从一个独立的 HTML 文件中进行加载,该文件位于:`/gameplay/tutorials/pages/*/content.html`.
```lua
guihooks.trigger("introPopupTutorial", {
{
content = readFile("/gameplay/tutorials/pages/template/content.html"):gsub("\r\n",""),
flavour = "onlyOk"
}
})
guihooks.trigger("introPopupClose")
```
<figure class="image image_resized" style="width:75%" markdown=""> ![在 BeamNG.drive 中显示的introPopupTutorial代码片段](../../assets/content/introPopupTutorial.png) </figure>
`flavour` 控制哪些按钮会被显示。共有四种类型:
- `withLogbook`
- Buttons: Career Logbook, Okay
- `onlyOk`
- Buttons: Okay
- `onlyLogbook`
- Buttons: Career Logbook
- `noButtons`
- 不提供任何按钮
!!! 警告
```
如果在页面中使用noButtons类型,且页面内容中没有提供额外的 JavaScript 来关闭该弹出窗口,则会导致游戏出现Softlock。在此类型下,多个页面不会合并到同一个弹出窗口中。因此,不建议使用此类型。
```
如果提供了多个页面,或者该Hook被多次触发,这些页面将合并到同一个弹出窗口中。<br>如果在一个 introPopup 处于活动状态时触发该钩子,或者已经触发了另一种不同类型的 introPopup,则它会在当前窗口关闭后,在一个独立的弹出窗口中显示。
### introPopupCareer
introPopupCareer是一种易于使用且开放式Open-ended的弹出窗口,如果需要,它还支持嵌入 HTML 内容。
Flavours控制显示哪些按钮以及默认的图像长宽比。共有四种类型:
- `default`
- Default image aspect ratio: 16x9
- Buttons: Later, Okay
- `welcome`
- Default image aspect ratio: 16x9
- Buttons: Career Logbook, Okay
- `branch-info`
- Default image aspect ratio: 16x9
- Buttons: Career Logbook, Okay
- `garage`
- Buttons: Later, Okay
```lua
guihooks.trigger("introPopupCareer", {
{
title = "Example title",
text = "Example text",
image = "/gameplay/tutorials/pages/template/image.jpg",
ratio = "16x9",
flavour = "default"
}
})
guihooks.trigger("introPopupClose")
```
<figure class="image image_resized" style="width:75%" markdown=""> !在 BeamNG.drive 中显示的introPopupCareer代码片段](../../assets/content/introPopupCareer.png) </figure>
如果提供了多个页面,或者该Hook被多次触发,这些页面将被合并到同一个弹出窗口中。<br>如果在一个introPopup处于活动状态时触发了该钩子,或者已经触发了另一种不同类型的introPopup,那么它将在当前窗口关闭后,通过一个独立的弹出窗口进行显示。
!!! bug
```
背景模糊具有最小高度限制,这会导致内容较少的弹出窗口在其窗口下方出现多余的模糊区域。目前主要有两种解决方法:
* 重复输入 `\n`(换行符)并在结尾添加 `#!html <div />`,直到窗口遮住模糊区域。
* 使用空路径或缺失的 `image` 路径,并调整长宽比(Aspect Ratio),直到窗口遮住模糊区域。
```
### introPopupMission
introPopupMission与 introPopupCareer几乎完全相同,但它需要手动定义按钮,而不是直接为按钮选择预设样式。
按钮样式组合为*bng-button-*`style`。内置的按钮样式包括:
- `main` - 橙色
- `secondary` - 青色
- `attention` - 红色
- `white` - 白色
- `link` - 半透明
- `outline` - 橙色轮廓
```lua
guihooks.trigger('introPopupMission', {
title = "introPopupMission title",
text = "introPopupMission description",
image = "/gameplay/tutorials/pages/template/image.jpg",
ratio = "16x9",
buttons = {
{ default=true, class="main", label="main button", clickLua="" },
{ default=false, class="secondary", label="secondary button", clickLua="" },
{ default=false, class="attention", label="attention button", clickLua="" },
{ default=false, class="white", label="white button", clickLua="" },
{ default=false, class="link", label="link button", clickLua="" },
{ default=false, class="outline", label="outline button", clickLua="" }
}
})
guihooks.trigger("introPopupClose")
```
<figure class="image image_resized" style="width:75%" markdown=""> ![在 BeamNG.drive 中显示的introPopupMission代码片段](../../assets/content/introPopupMission.png) </figure>
如果提供了多个页面,或者该Hook被多次触发,这些页面将合并到同一个弹出窗口中。<br>如果在一个introPopup处于活动状态时触发了该钩子,或者已经触发了另一种不同类型的 introPopup,则它会在当前窗口关闭后,通过一个独立的弹出窗口进行显示。
!!! bug
```
背景模糊具有最小高度限制,这会导致内容较少的弹出窗口在其窗口下方出现多余的模糊区域。目前主要有两种解决方法:
* 重复输入 `\n`(换行符)并在结尾添加 `#!html <div />`,直到窗口拉长并遮住模糊区域。
* 使用空路径或缺失的 `image`(图像)路径,并调整长宽比(Aspect Ratio),直到窗口覆盖住模糊区域。
```
### 对话窗口
todo
+232 -11
View File
@@ -8,17 +8,19 @@
这也可以在任何页面上完成。
```
# BeamNG.drive代码片段
# BeamNG.drive 代码片段
## Lua代码片段
### 绘制标记和车辆检测
### 世界
#### 绘制标记和车辆检测
在地图中绘制标记可能是向用户表明他们可以在那里进行某种形式的交互的最佳方式之一。
绘制标记相当容易。以下是如何绘制公交车路线标记的示例:
```Lua
```lua
local function createBusMarker(markerName)
local marker = createObject('TSStatic')
marker:setField('shapeName', 0, "art/shapes/interface/position_marker.dae")
@@ -60,7 +62,7 @@
以下是来自[BeamNG-FuelStations](https://github.com/BeamMP/BeamNG-FuelStations/tree/master)的自定义标记示例:
```Lua
```lua
local stations = [
{ "location": [ -778.813, 485.973, 23.46 ], "type":"gas" },
{ "location": [ 617.164, -192.107, 53.2 ], "type":"ev" },
@@ -93,11 +95,11 @@
end
```
### guihooks示例
### 用户界面
#### Toast通知,位于屏幕右上角
#### 屏幕右上角弹出的通知
![图像](https://github.com/StanleyDudek/Docs/assets/49531350/c8a87842-b95a-4eca-84dc-93072ecc9158)
<figure class="image image_resized" style="width:75%" markdown=""> ![image](https://github.com/StanleyDudek/Docs/assets/49531350/c8a87842-b95a-4eca-84dc-93072ecc9158) </figure>
```lua
--guihooks.trigger('toastrMsg', {type, title, msg, config = {timeOut}})
@@ -108,10 +110,13 @@ guihooks.trigger('toastrMsg', {type = "error", title = "Error Message:", msg = "
#### 消息通知,消息应用程序中默认位于屏幕左上角
![图像](https://github.com/StanleyDudek/Docs/assets/49531350/6baef813-50cb-43c3-9c59-0de550b014b6)
这需要'Messages' 或 'Messages &amp; Tasks' UI 插件。图标文件可以在以下路径中找到 `ui\ui-vue\src\assets\fonts\bngIcons\svg这需要'Messages' 或 'Messages &amp; Tasks' UI 插件。图标文件可以在以下路径中找到
<figure class="image image_resized" style="width:75%" markdown=""> ![image](https://github.com/StanleyDudek/Docs/assets/49531350/6baef813-50cb-43c3-9c59-0de550b014b6) </figure>
```lua
--guihooks.trigger('Message', {msg, ttl, category, icon}) --requires Messages app
--guihooks.trigger('Message', {msg, ttl, category, icon})
--ui_message(msg, ttl, category, icon)
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "arrow_upward", icon = "arrow_upward"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "arrow_downward", icon = "arrow_downward"})
guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "flag", icon = "flag"})
@@ -128,7 +133,9 @@ guihooks.trigger('Message', {msg = "Message Text Here", ttl = 5.0, category = "s
#### 位于中心,大,小型短暂显示
![图像](https://github.com/StanleyDudek/Docs/assets/49531350/d0cf754f-83f8-4d15-9159-27350da127de)![图像](https://github.com/StanleyDudek/Docs/assets/49531350/1df6fc9b-756f-484e-b8d9-5df346dc4c26)
<figure class="image image_resized" style="width:75%" markdown=""> ![image](https://github.com/StanleyDudek/Docs/assets/49531350/d0cf754f-83f8-4d15-9159-27350da127de) </figure>
<figure class="image image_resized" style="width:75%" markdown=""> ![image](https://github.com/StanleyDudek/Docs/assets/49531350/1df6fc9b-756f-484e-b8d9-5df346dc4c26) </figure>
```lua
--guihooks.trigger('ScenarioFlashMessage', {{msg, ttl, sound, big}} ) -- requires RaceCountdown ui app
@@ -147,7 +154,9 @@ guihooks.trigger('ScenarioFlashMessage', {{"Teleported!", 3.0, "Engine.Audio.pla
#### 位于中心,中型持续显示
![图像](https://github.com/StanleyDudek/Docs/assets/49531350/6290e018-6b3d-4674-98f2-34282a723258)
这需要 **“比赛实时显示 (Race Realtime Display)”** UI 插件。
<figure class="image image_resized" style="width:75%" markdown=""> ![image](https://github.com/StanleyDudek/Docs/assets/49531350/6290e018-6b3d-4674-98f2-34282a723258) </figure>
```lua
--guihooks.trigger('ScenarioRealtimeDisplay', {msg = msg} ) -- requires Race Realtime Display ui app
@@ -157,6 +166,218 @@ guihooks.trigger('ScenarioRealtimeDisplay', {msg = "Message Text Here"} )
guihooks.trigger('ScenarioRealtimeDisplay', {msg = ""} )
```
#### Confirmation Dialog
ConfirmationDialog是一种简单的弹出窗口,最多支持两个按钮。
```lua
-- -- 打开一个包含标题、正文及最多两个按钮的Confirmation Dialog
guihooks.trigger("ConfirmationDialogOpen",
"Example Title",
"Example Body Text",
"Okay",
"", --gelua. empty string
"Cancel",
"" --gelua
)
-- 关闭任何具有指定标题且处于打开状态的确认对话框
guihooks.trigger("ConfirmationDialogClose", "Example Title")
```
<figure class="image image_resized" style="width:75%" markdown=""> ![ConfirmationDialog示例](../../assets/content/ConfirmationDialog.png) </figure>
按钮的两个字段都必须是字符串,该按钮才能正常显示。
如果提供了Okay按钮,按下 *确定 / 主要动作 (OK / Primary action)*按键的效果等同于点击确定按钮。
如果提供了Cancel按钮,按下*菜单 (Menu)*按键的效果等同于点击取消按钮。
支持HTML格式,例如可以用来添加图像或图标。
可以同时显示多个,并将按顺序依次呈现。
!!! bug
```
不提供任何按钮会导致玩家在不使用控制台的情况下无法退出该对话框。
```
!!! bug
```
当 **ConfirmationDialog**(确认对话框)处于活动状态时,小地图 (Minimap) UI 插件的 **SDF 部分** 依然保持可见。
可以使用 `#!lua guihooks.trigger('ShowApps', false)` 隐藏 UI 插件,作为一种临时性的补救方案。
```
<figure class="image image_resized" style="width:75%" markdown=""> ![ConfirmationDialog被用于挂机踢出系统的示例](../../assets/content/ConfirmationDialog_Example.png) </figure>
#### introPopupTutorial
introPopupTutorial 是一种高度可定制的弹出窗口,其内容主要由嵌入式 HTML 定义。标准做法是从位于`/gameplay/tutorials/pages/*/content.html`的独立 HTML 文件中进行加载。
```lua
guihooks.trigger("introPopupTutorial", {
{
content = readFile("/gameplay/tutorials/pages/template/content.html"):gsub("\r\n",""),
flavour = "onlyOk"
}
})
guihooks.trigger("introPopupClose")
```
<figure class="image image_resized" style="width:75%" markdown=""> ![在BeamNG.drive中显示的introPopupTutorial代码片段](../../assets/content/introPopupTutorial.png) </figure>
Flavours控制显示的按钮类型。共有四种预设模式:
- `withLogbook`
- Buttons: Career Logbook, Okay
- `onlyOk`
- Buttons: Okay
- `onlyLogbook`
- Buttons: Career Logbook
- `noButtons`
- Provides no buttons
!!! 警告
```
当页面使用noButtons模式时,如果页面内容中未提供用于关闭弹出窗口的额外 JavaScript 代码,则会导致软锁定。在这种模式下,多个页面不会合并到同一个弹出窗口中。因此,不建议使用该模式。
```
如果提供了多个页面,或者该hook被多次触发,这些页面将合并到同一个弹出窗口中。<br>如果在introPopup处于活动状态时触发钩子,或者已经触发了另一种类型的introPopup,则新内容将在现有弹出窗口关闭后,以独立的弹出窗口形式显示。
#### introPopupCareer
introPopupCareer是一种易于使用且具有高度开放性的弹出窗口,如有需要,它还支持嵌入 HTML 内容。
Flavours控制显示的按钮类型以及默认的图像宽高比。共有四种预设模式:
- `default`
- Default image aspect ratio: 16x9
- Buttons: Later, Okay
- `welcome`
- Default image aspect ratio: 16x9
- Buttons: Career Logbook, Okay
- `branch-info`
- Default image aspect ratio: 16x9
- Buttons: Career Logbook, Okay
- `garage`
- Buttons: Later, Okay
```lua
guihooks.trigger("introPopupCareer", {
{
title = "Example title",
text = "Example text",
image = "/gameplay/tutorials/pages/template/image.jpg",
ratio = "16x9",
flavour = "default"
}
})
guihooks.trigger("introPopupClose")
```
<figure class="image image_resized" style="width:75%" markdown=""> !在BeamNG.drive中显示的introPopupCareer代码片段](../../assets/content/introPopupCareer.png) </figure>
如果提供了多个页面,或者该hook被多次触发,这些页面将合并到同一个弹出窗口中。<br>如果在introPopup处于活动状态时触发了hook,或者已经触发了另一种类型的introPopup,则新内容将在当前弹出窗口关闭后,以独立的弹出窗口形式显示。
!!! bug
```
背景模糊具有最小高度限制,这会导致内容较短的弹出窗口下方出现多余的模糊区域。目前主要有两种规避方案:
* 重复输入 `\n` 并以 `#!html <div />` 结尾,直到窗口完全覆盖模糊区域。
* 使用空路径或缺失的 `image` 路径,并调整宽高比(Aspect Ratio),直到窗口覆盖模糊区域。
```
#### introPopupMission
introPopupMission与introPopupCareer几乎完全相同,但它需要手动定义按钮,而不是直接为按钮选择Flavour的预设模式。
按钮样式以 *bng-button-*`style` 的格式进行组合。内置的按钮样式包括:
- `main` - 橙色
- `secondary` - 青色
- `attention` - 红色
- `white` - 白色
- `link` - 半透明
- `outline` - 橙色轮廓
```lua
guihooks.trigger('introPopupMission', {
title = "introPopupMission title",
text = "introPopupMission description",
image = "/gameplay/tutorials/pages/template/image.jpg",
ratio = "16x9",
buttons = {
{ default=true, class="main", label="main button", clickLua="" },
{ default=false, class="secondary", label="secondary button", clickLua="" },
{ default=false, class="attention", label="attention button", clickLua="" },
{ default=false, class="white", label="white button", clickLua="" },
{ default=false, class="link", label="link button", clickLua="" },
{ default=false, class="outline", label="outline button", clickLua="" }
}
})
guihooks.trigger("introPopupClose")
```
<figure class="image image_resized" style="width:75%" markdown=""> ![在BeamNG.drive中显示的introPopupMission代码片段](../../assets/content/introPopupMission.png) </figure>
如果提供了多个页面,或者该hook被多次触发,这些页面将合并到同一个弹出窗口中。<br>如果在introPopup处于活动状态时触发了hook,或者已经触发了另一种类型的introPopup,则新内容将在当前弹出窗口关闭后,以独立的弹出窗口形式显示。
!!! bug
```
背景模糊具有最小高度限制,这会导致内容较短的弹出窗口在其窗口下方出现多余的模糊区域。目前主要有两种规避方案:
* 重复使用 `\n` 并以 `#!html <div />` 结尾,直到窗口高度足以覆盖模糊区域。
* 使用空路径或缺失的 `image` 路径,并调整宽高比(Aspect Ratio),直到窗口完全覆盖模糊区域。
```
#### Dialogue
Dialogue被用于*A Rocky Start*活动中,用于显示有关任务的信息。它是一个居中且垂直对齐的弹出窗口,具有特定的布局。它不支持嵌入 HTML。
```lua
ui_missionInfo.openDialogue({
title = "Dialogue title",
type = "Custom", -- isn't actually displayed
typeName = "typeName",
data = {
{label = "objective", value = "reward"}
-- add more...
},
buttons = {
{action = "accept", text = "Accept", cmd = ""},
{action = 'decline',text = "Decline", cmd = ""}
-- add more...
}
})
ui_missionInfo.closeDialogue()
```
<figure class="image image_resized" style="width:75%" markdown=""> ![在BeamNG.drive中显示的Dialogue代码片段](../../assets/content/Dialogue.png) </figure>
同时只能显示一个Dialogue。任何现有的Dialogue都会被直接覆盖。
!!! info
```
`#!lua ui_missionInfo.closeDialogue()` 必须使用该函数来关闭对话框。
请确保在按下任何按钮时都调用此函数。
```
## IMGUI代码片段
todo
## CEF UI代码片段
todo