{
  "schemaVersion": "0.11.0",
  "canonical": "https://www.pystone.net/notes/unity-editor-extension-imgui/",
  "atlas": "https://www.pystone.net/?node=unity-editor-extension-imgui#knowledge-atlas",
  "markdown": "https://www.pystone.net/notes/unity-editor-extension-imgui.md",
  "context": "https://www.pystone.net/notes/unity-editor-extension-imgui.context.json",
  "knowledgeVersion": "224c990773de.5fa8af6e39fa",
  "build": {
    "siteCommit": "224c990773de166d23a886306577dd90379529ce",
    "notesCommit": "5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a",
    "builtAt": "1970-01-01T00:00:00.000Z",
    "version": "224c990773de.5fa8af6e39fa"
  },
  "id": "note:unity-editor-extension-imgui",
  "slug": "unity-editor-extension-imgui",
  "title": "【Editor Extension】IMGUI",
  "type": "note",
  "visibility": "public",
  "idStability": "rename-stable",
  "author": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "publisher": {
    "name": "Perrin Yong",
    "profile": "https://www.pystone.net/profile/"
  },
  "aliases": [],
  "summary": "【Editor Extension】IMGUI",
  "contentRole": "unspecified",
  "isMoc": false,
  "mocRecognition": "none",
  "generated": false,
  "attribution": "unspecified",
  "domain": "10-计算机、信息技术与工程",
  "tags": [],
  "mocs": [],
  "contentHash": "fb50c8112943d24aa70231361161737ce61c68a00e6264101301a6e10106e46a",
  "assets": [],
  "headings": [
    {
      "depth": 1,
      "text": "【Editor Extension】IMGUI",
      "anchor": "editor-extensionimgui",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#editor-extensionimgui"
    },
    {
      "depth": 2,
      "text": "Introduction",
      "anchor": "introduction",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#introduction"
    },
    {
      "depth": 3,
      "text": "传统用户界面系统缓存状态的缺点",
      "anchor": "传统用户界面系统缓存状态的缺点",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#%E4%BC%A0%E7%BB%9F%E7%94%A8%E6%88%B7%E7%95%8C%E9%9D%A2%E7%B3%BB%E7%BB%9F%E7%BC%93%E5%AD%98%E7%8A%B6%E6%80%81%E7%9A%84%E7%BC%BA%E7%82%B9"
    },
    {
      "depth": 3,
      "text": "IMGUI",
      "anchor": "imgui",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#imgui"
    },
    {
      "depth": 4,
      "text": "优点",
      "anchor": "优点",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#%E4%BC%98%E7%82%B9"
    },
    {
      "depth": 4,
      "text": "IMGUI的缺点",
      "anchor": "imgui的缺点",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#imgui%E7%9A%84%E7%BC%BA%E7%82%B9"
    },
    {
      "depth": 5,
      "text": "可能需要更多的CPU",
      "anchor": "可能需要更多的cpu",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#%E5%8F%AF%E8%83%BD%E9%9C%80%E8%A6%81%E6%9B%B4%E5%A4%9A%E7%9A%84cpu"
    },
    {
      "depth": 5,
      "text": "可访问性问题",
      "anchor": "可访问性问题",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#%E5%8F%AF%E8%AE%BF%E9%97%AE%E6%80%A7%E9%97%AE%E9%A2%98"
    },
    {
      "depth": 5,
      "text": "动画的支持性",
      "anchor": "动画的支持性",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#%E5%8A%A8%E7%94%BB%E7%9A%84%E6%94%AF%E6%8C%81%E6%80%A7"
    },
    {
      "depth": 2,
      "text": "Unity IMGUI",
      "anchor": "unity-imgui",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#unity-imgui"
    },
    {
      "depth": 3,
      "text": "Unity GameObject-based UI system vs IMGUI",
      "anchor": "unity-gameobject-based-ui-system-vs-imgui",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#unity-gameobject-based-ui-system-vs-imgui"
    },
    {
      "depth": 3,
      "text": "Controls",
      "anchor": "controls",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#controls"
    },
    {
      "depth": 3,
      "text": "GUIStyle & GUISkin",
      "anchor": "guistyle-guiskin",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#guistyle-guiskin"
    },
    {
      "depth": 3,
      "text": "Layout",
      "anchor": "layout",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#layout"
    },
    {
      "depth": 4,
      "text": "Fixed Layout & Automatic Layout",
      "anchor": "fixed-layout-automatic-layout",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#fixed-layout-automatic-layout"
    },
    {
      "depth": 4,
      "text": "GUILayoutOptions",
      "anchor": "guilayoutoptions",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#guilayoutoptions"
    },
    {
      "depth": 3,
      "text": "GUI vs EditorGUI",
      "anchor": "gui-vs-editorgui",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#gui-vs-editorgui"
    },
    {
      "depth": 2,
      "text": "经验与思考",
      "anchor": "经验与思考",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#%E7%BB%8F%E9%AA%8C%E4%B8%8E%E6%80%9D%E8%80%83"
    },
    {
      "depth": 3,
      "text": "关于OnGUI调用逻辑的探究",
      "anchor": "关于ongui调用逻辑的探究",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#%E5%85%B3%E4%BA%8Eongui%E8%B0%83%E7%94%A8%E9%80%BB%E8%BE%91%E7%9A%84%E6%8E%A2%E7%A9%B6"
    },
    {
      "depth": 3,
      "text": "EditorGUI的一个BUG",
      "anchor": "editorgui的一个bug",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#editorgui%E7%9A%84%E4%B8%80%E4%B8%AAbug"
    },
    {
      "depth": 2,
      "text": "Ref",
      "anchor": "ref",
      "citation": "https://www.pystone.net/notes/unity-editor-extension-imgui/#ref"
    }
  ],
  "claims": [],
  "outgoing": [],
  "incoming": [
    {
      "id": "note:game-graphics-and-runtime",
      "title": "游戏图形与运行时",
      "url": "https://www.pystone.net/notes/game-graphics-and-runtime/",
      "atlas": "https://www.pystone.net/?node=game-graphics-and-runtime#knowledge-atlas",
      "label": "游戏图形与运行时",
      "origin": "explicit",
      "humanReviewed": true,
      "context": "Unity中的“【Editor Extension】IMGUI”导航项",
      "citation": "https://www.pystone.net/notes/game-graphics-and-runtime/#unity"
    }
  ],
  "contentMarkdown": "# 【Editor Extension】IMGUI\n\n> 创建时间：2021/1/26 18:12\n\n  * 【Editor Extension】IMGUI\n    * Introduction\n      * 传统用户界面系统缓存状态的缺点\n      * IMGUI\n        * 优点\n        * IMGUI的缺点\n          * 可能需要更多的CPU\n          * 可访问性问题\n          * 动画的支持性\n    * Unity IMGUI\n      * Unity GameObject-based UI system vs IMGUI\n      * Controls\n      * GUIStyle & GUISkin\n      * Layout\n        * Fixed Layout & Automatic Layout\n        * GUILayoutOptions\n      * GUI vs EditorGUI\n    * 经验与思考\n      * 关于OnGUI调用逻辑的探究\n      * EditorGUI的一个BUG\n    * Ref\n\n## Introduction\n\nAn immediate mode graphic user interface (GUI), also known as IMGUI, is a graphical user interface design pattern which uses an immediate mode graphics library to create the GUI. via. Wikipedia\n\n即时模式图形用户界面（IMGUI）代表了一种范例，其中用户界面的创建（对于客户端应用程序）和实现更简单（对于工具箱设计器）。\n\n### 传统用户界面系统缓存状态的缺点\n\n传统用户界面系统设计和使用的复杂性是由此类系统保持了各种状态引起的。程序员通常被要求在应用程* 序和用户界面之间来回主动地复制状态，以便用户界面反映应用程序的状态，反之，为了使用户界面中发生的更改影响应用程序的状态。UI系统的状态是实际状态的一份COPY/CACHE。\n\n从客户端应用的角度看，UI更像是一堆对象的集合（通常称为widget），这些对象分装了需要和应用交互的各种状态。这个同步过程是双向的，为了让用户了解到当前应用的状态，状态需要从应用端转移到UI端；为了让应用知道当前用户的操作，状态需要从UI端转移到应用端。\n\n此外，通知应用程序用户与接口交互的方式（这反过来表明需要重新同步状态）通常采用回调的形式。这需要应用程序为感兴趣的任何低级交互实现“事件处理程序”，通常是通过手动或通过各种代码生成技巧将某些工具箱基类子类化；在任何一种情况下，都会使客户机应用程序的生命周期更加复杂。\n\n### IMGUI\n\n#### 优点\n\nIMGUI通过要求应用程序实时显式传递可视化和交互所需的所有状态来消除这种状态同步。 用户界面只保留了为方便系统支持的每种小部件所需的功能所需的最小状态量。\n\nWidget不再是对象，甚至可以说是不存在的。它们采用过程方法调用的形式，用户界面本身从有状态的对象集合变成了方法调用的实时序列。\n\n这种实现方式的基础是实时应用程序循环的概念，也就是说，应用以实时的帧率处理逻辑和绘制（30 frames per second或者更高）。在游戏场景，这个是很常见的。\n\n乍看起来，通过传递参数的方式实现看上去很冗余，但实际上并不是这样的。看上去会影响绘制性能。但是，对于现代的CPU和GPU而言，这个不是问题。\n\n其优点在于简单和灵活。删除用户界面系统中的隐式状态缓存可以减少与缓存相关的bug的可能性，也完全消除了工具箱将小部件作为对象公开给客户机应用程序的需要。在逻辑上，小部件从对象变为方法调用。我们将看到，这从根本上改变了客户机应用程序处理用户界面实现的方式。\n\n简单总结，IMGUI有以下优点：\n\n  * 丝毫不需要分配内存，也即需要的内存为零！\n\n  * 速度很快。即使使用非常复杂的UI并且只有单线程的情况下，大多数（如果不是全部）ImGUI在60fps（帧）的速度下运行没有任何问题。\n\n  * 不需要对必须管理的对象进行创建和销毁操作。\n\n  * 没有状态，因为没有对象来存储状态。\n\n  * 基本不需要编制数据。\n\n  * 没有需要注册或响应的事件或回调。\n\n#### IMGUI的缺点\n\n##### 可能需要更多的CPU\n\n传统的GUI系统当元素有变化时，只需重新绘制局部元素。\n\nImGUI则相反，任何时候你想更改任何内容，整个图形用户界面就要重新绘制。即使是光标。以我们进入Excel示例，所有75个工具栏控件和300个单元格都将因为一个闪烁的光标而重新绘制。这是IMGUI的最坏情况。大量的CPU被浪费了。\n\n##### 可访问性问题\n\n通常GUI不保留任何数据，所以它可能做不了保留模式GUI能够做的那些事情。\n\n##### 动画的支持性\n\n大多数ImGUI都是无状态的，所以所有的动画都取决于应用程序。\n\n## Unity IMGUI\n\nIMGUI is a code-driven GUI system. It is driven by calls to the OnGUI function on any script which implements it.\n\n“Immediate Mode” refers to the way the IMGUI is created and drawn. To create IMGUI elements, you must write code that goes into a special function named OnGUI. The code to display the interface is executed every frame, and drawn to the screen. There are no persistent gameobjects\nother than the object to which your OnGUI code is attached, or other types of objects in the hierarchy related to the visual elements that are drawn.\n\n### Unity GameObject-based UI system vs IMGUI\n\nGameObject-based UI system has far better tools to work with the visual design and layout of the UI.\n\n适用情况：Unity’s main GameObject-based UI system is used for normal in-game user interfaces that players might use and interact with.\n\nIMGUI allows you to create a wide variety of functional GUIs using code. Rather than creating GameObjects, manually positioning them, and then writing a script that handles its functionality, you can do everything at once with just a few lines of code. The code produces GUI controls that are drawn and handled with a single function call.\n\n### Controls\n\nThe Control defines the content\n\n### GUIStyle & GUISkin\n\nGUItyles define the appearance of a GUI Control. GUISkins are a collection of GUIStyles.\n\n### Layout\n\n#### Fixed Layout & Automatic Layout\n\n  * Fixed Layout makes sense to use when you have a pre-designed interface to work from.\n\n  * Automatic Layout makes sense to use when you don’t know how many elements you need up front, or don’t want to worry about hand-positioning each Control.\n\nAbout Automatic Layout:\n\n  * GUILayout is used instead of GUI\n\n  * No Rect() function is required for Automatic Layout Controls\n\n#### GUILayoutOptions\n\nYou can use GUILayoutOptions to override some of the Automatic Layout parameters. You do this by providing the options as the final parameters of the GUILayout Control.\n\n### GUI vs EditorGUI\n\nThe difference between GUI and EditorGUI is primarily just their use case. GUI is used to display GUI items in game. GUI was the original way of creating Unity UI before their new canvas APIs. EditorGUI is used to create custom editors for your scripts and other editor customization.\n\nOne exception to that rule is that certain GUI classes are used for both. For instance, GUISkin and GUIStyle are used by both and their current values are accessed using GUI.skin regardless if used in game or in editor.\n\n## 经验与思考\n\n### 关于OnGUI调用逻辑的探究\n\nMonobehaviour脚本的OnGUI在Play时确实是会每帧都调用，每帧都重新绘制内容。表现在使用如下脚本，Play时，字体会随着正弦函数不断连续变大变小。\n\n```csharp\nclass Program\n{\n    static void Main(string[] args)\n    {\n        dynamic dyn = 1;\n        object obj = 1;\n        dyn = dyn + 3;\n        //obj = obj + 3; 报错\n\n        // Rest the mouse pointer over dyn and obj to see their\n        // types at compile time.\n        System.Console.WriteLine(dyn.GetType());\n        System.Console.WriteLine(obj.GetType());\n    }\n}\n\n```\n\n但是在EditorWindow下，如果OnGUI中没有写EditorWindow.Repaint()的话，OnGUI并不会每帧都调用，字体大小不会自动连续地按照正弦曲线变大变小。只有当触发一定的事件时（比如点击窗口，在某个按钮上hover等），EditorWindow才会重新绘制，调用OnGUI。\n\n如果OnGUI中主动调用Repaint()，则OnGUI会每帧都调用，原理还不明确。\n\n### EditorGUI的一个BUG\n\nEditorGUI有两个函数，BeginChangeCheck、EndChangeCheck()，用以检测特定范围内，UI元素的值是否发生改变。\n当Begin与Begin发生嵌套时，会\n\n## Ref\n\n<https://en.wikipedia.org/wiki/Immediate_mode_GUI>\n\n<https://www.tangledrealitystudios.com/development-tips/gui-vs-guilayout-vs-editorgui-vs-editorguilayout-and-when-to-use-them/>\n\n<https://www.cnblogs.com/grass-and-moon/p/13864696.html>\n<https://blog.csdn.net/csdnnews/article/details/90746003>\n"
}
