使用 ImGui 开发编辑器和调试工具
1. 引言
在游戏开发过程中,一个直观、高效的用户界面(UI)对于编辑器和调试工具至关重要。然而 Dora SSR 作为一个聚焦于代码的引擎,暂时没有提供内置的编辑器或是调试工具。因此,需要开发者根据自己游戏作品的需求,自行进行快速开发和定制。但是,Dora SSR 提供了 ImGui 库,可以极为方便地开发这类辅助 UI。
ImGui(Immediate Mode GUI)是一种即时模式的图形用户界面库,以其简洁、高效的特点被广泛应用。接下来本教程将介绍如何 使用 Dora SSR 提供的 ImGui 库开发游戏编辑器或调试工具的 UI。
2. ImGui 框架的理念、优势和劣势
2.1 理念
ImGui 的核心理念是即时模式,这意味着 UI 是在每一帧都被重新绘制的。这与传统的保留模式(Retained Mode)不同,后者维护着一个 UI 状态树,而即时模式则是根据当前的程序状态直接绘制 UI。
2.2 优势
- 易于使用:无需管理复杂的 UI 状态,直接在代码中描述 UI 元素。
- 快速迭代:适合快速原型设计和调试工具的开发。
- 轻量级:无需整合大型的 UI 框架,减少了资源消耗。
- 高度灵活:可以轻松地嵌入到现有的游戏引擎渲染循环中。
2.3 劣势
- 不适合复杂的 UI:对于需要高度交互和复杂布局的应用,可能不太适用。
- 样式有限:默认的视觉风格较为简单,定制化需要额外的工作。可能无法满足游戏作品的视觉要求。
- 性能开销:在非常复杂的 UI 场景下,每帧重绘可能会带来性能问题。
4. 基本使用方法
4.1 创建一个简单的窗口
以下示例展示了如何创建一个简单的 ImGui 窗口:
- Lua
- Teal
- TypeScript
- YueScript
local ImGui <const> = require("ImGui")
local threadLoop <const> = require("threadLoop")
threadLoop(function()
ImGui.Begin("示例窗口", function()
ImGui.Text("欢迎使用 Dora SSR 的 ImGui!")
ImGui.Separator()
ImGui.TextWrapped("这是一个简单的示例窗口,展示了基本的文本和分隔线。")
end)
end)
local ImGui <const> = require("ImGui")
local threadLoop <const> = require("threadLoop")
threadLoop(function(): boolean
ImGui.Begin("示例窗口", function()
ImGui.Text("欢迎使用 Dora SSR 的 ImGui!")
ImGui.Separator()
ImGui.TextWrapped("这是一个简单的示例窗口,展示了基本的文本和分隔线。")
end)
return false
end)
import { threadLoop } from "Dora";
import * as ImGui from "ImGui";
threadLoop(() => {
ImGui.Begin("示例窗口", () => {
ImGui.Text("欢迎使用 Dora SSR 的 ImGui!");
ImGui.Separator();
ImGui.TextWrapped("这是一个简单的示例窗口,展示了基本的文本和分隔线。");
});
return false;
});
_ENV = Dora Dora.ImGui
threadLoop ->
Begin "示例窗口", ->
Text "欢迎使用 Dora SSR 的 ImGui!"
Separator!
TextWrapped "这是一个简单的示例窗口,展示了基本的文本和分隔线。"
说明:
threadLoop
函数用于在主线程中循环执行操作。ImGui.Begin
函数用于创建一个窗口,并指定窗口的标题。ImGui.Text
函数用于绘制文本。ImGui.Separator
函数用于绘制一个分隔线。ImGui.TextWrapped
函数用于绘制一段带有自动换行的文本。
4.2 添加交互元素
您可以在窗口中添加按钮、输入框等交互元素:
- Lua
- Teal
- TypeScript
- YueScript
local ImGui <const> = require("ImGui")
local threadLoop <const> = require("threadLoop")
local Buffer <const> = require("Buffer")
local inputText = Buffer(200)
inputText.text = "默认文本"
threadLoop(function()
ImGui.Begin("交互示例", function()
if ImGui.Button("点击我") then
print("按钮被点击!")
end
if ImGui.InputText("输入框", inputText) then
print("输入内容:" .. inputText.text)
end
end)
end)
local ImGui <const> = require("ImGui")
local threadLoop <const> = require("threadLoop")
local Buffer <const> = require("Buffer")
local inputText = Buffer(200)
inputText.text = "默认文本"
threadLoop(function(): boolean
ImGui.Begin("交互示例", function()
if ImGui.Button("