Bootstrap

【ZeloEngine】ImGui汇总

【ZeloEngine】ImGui汇总

需求

游戏内置菜单(In-Game Menus)

GM界面,这是一个程序编写的界面

需求:

  • 程序化的,代码驱动的界面
  • 无需美术拼UI,注重实用,不太在乎美观
  • 跨平台
  • 入口,一键呼出,PC可以是快捷键,手机可以是一个可以移动的小按钮,手柄可以是一个组合键

以下图片来自《游戏引擎架构》

顽皮狗是自己定制的一个界面,属于ImGui的子集

Main development menu
在这里插入图片描述
Rendering submenu
在这里插入图片描述
Mesh options subsubmenu
在这里插入图片描述
Background meshes turned off
在这里插入图片描述

使用Icon

前面虽然说实用优先,不需要表面功夫,不过话说回来

程序开发的界面,Icon是一个很好的优化,美观,提供视觉引导

这种引导是潜移默化的,即使你不去看手册,一个有Icon的编辑器用多了,自然会看Icon来识别出哪个功能在哪里

而没有Icon的编辑器,则一直需要看文字来找位置

案例二

Images and Icons for Visual Studio - Visual Studio | Microsoft Docs

Icon Download
在这里插入图片描述
案例二

阿比盖尔 | Don’t Starve 中文維基 | Fandom

在这里插入图片描述

本地化

编辑器本地化有标准方案,参考Godot

说实话,对于国内团队,中文编辑器是刚需

大部分人的英文水平,仍然需要中文编辑器来达到最好的编辑效率

ImGui

如何开发/编程指南

  • ImGui基本原理
  • ImGui框架概念
  • ImGui接口
  • 脚本绑定接口
  • 脚本薄封装框架
  • 参考项目

痛点

原理学完只是第一步,我们要铺量去写UI,那工具链要是完善的

目前抄了几个界面后的痛点是:对接口不熟悉,查接口要跳很多文档

理想的状态是:Model数据结构=》设计粗略View展示Model=》转换成代码=》迭代交互和样式

接口文档

https://blog.csdn.net/zolo_mario/article/details/120359861?spm=1001.2014.3001.5501

https://blog.csdn.net/zolo_mario/article/details/120357560?spm=1001.2014.3001.5501

https://blog.csdn.net/zolo_mario/article/details/120359935?spm=1001.2014.3001.5501

Doc/Editor/ImGui/**

imgui的文档维护比较糟糕,接口文档都在代码里,所以我整理了一份文档

脚本绑定接口

原文档

imgui_patch.lua

文档导出的桩文件,基本可用,按需要改即可

脚本绑定方案和接口,可以多看看几个方案,但是持续维护目前的就够了

主要是由于C和Lua的差异,脚本接口是有微小差异的,所以需要维护一套

ImGui Demo 自解释

ImGui本身有很多参数,ImGui本身又是一个参数编辑器框架,所以Demo基本就是自己编辑自己

UI框架

基本架构

ImGui(C++) => sol wrapper => ImGui(Lua) => ImGui Framework

框架主要是做一个薄封装和分类,便于开发

薄封装

ImGui接口本身都是全局函数,有两个问题:

  • 没有做分类,量很大,从开发者角度有一些冗余
    • 同样功能不同接口二选一,Column和Table
    • 实际用不到的
    • 过时的接口
    • beta接口
  • 脚本绑定后Lua接口和C接口的差异
  • ImGui更新(docking分支目前仍然不是主分支),后向兼容性的风险

分类

  • panel
  • widget
  • layout
  • plugin

脚本绑定减少重载

既然脚本层封装了,那么绑定层就不要提供太多重载,影响性能

以MenuItem为例,下面这样写太复杂了,封装成一个接口就可以了

bool MenuItem ( const  char * label, const  char *shortcut = NULL , bool selected = false , bool enabled = true );  
激活时返回真。

bool MenuItem ( const  char * label, const  char * shortcut, bool * p_selected, bool enabled = true );    
激活时返回 true + toggle (*p_selected) 如果 p_selected != NULL
inline bool MenuItem(const std::string &label) {
    return ImGui::MenuItem(label.c_str()); }

inline bool MenuItem(const std::string &label, const std::string &shortcut) {
   
    return ImGui::MenuItem(label.c_str(), shortcut.c_str())
;