(ImGui library is available under a free and permissive license, but needs financial support to sustain its continued improvements. In addition to maintenance and stability there are many desirable features yet to be added. If your company is using Dear ImGui, please consider reaching out.)
UImGui (Unity ImGui) is an UPM package for the immediate mode GUI library using ImGui.NET. This project is based on RG.ImGui project. This project use FreeType as default renderer.
Using imgui 1.84 WIP
Dear ImGui is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).
Dear ImGui is designed to enable fast iterations and to empower programmers to create content creation tools and visualization / debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and lacks certain features normally found in more high-level libraries.
To update (using ImGui.Net.dll) easier and often.
Feature | RG | UImGui |
---|---|---|
IL2CPP | ❌ | ✔️ |
Windows | ✔️ | ✔️ |
Linux | ✔️ | ❌ |
MacOS | ✔️ | ❌ |
Custom Assert | ✔️ | ❌ |
Docking | ❌ | ✔️ |
Unity Input Manager | ✔️ | ✔️ |
Unity Input System | ✔️ | ✔️ |
Docking | ❌ | ✔️ |
RenderPipeline Built in | ✔️ | ✔️ |
RenderPipeline URP | ❌ | ✔️ |
RenderPipeline HDRP | ❌ | ✔️ |
Renderer Mesh | ✔️ | ✔️ |
Renderer Procedural | ~ | ✔️ |
FreeType | ~ | ✔️ |
Image / Texture | ❌ | ✔️ |
- Add package from git URL: https://github.com/psydack/uimgui.git
- Add
UImGui
component to the scene and - (Optional) Set
Platform Type
toInput System
if you're using the new input system theSampleDemoWindow
object on the scene the following properties: - If you're using URP check Using URP section, for HDRP Using HDRP section, for built in check Using Built in section.
- You're ready. Look Samples section for more usage samples.
It has a demo scene called UImGuiDemoScene
inside UImGui/Sample
folder.
You can subscribe to global layout or for a specific UImGui
context:
If choose to use global, don't to forget to set Do Global Events
to true
on UImGui
instance.
using UImGui;
using UnityEngine;
public class StaticSample : MonoBehaviour
{
private void Awake()
{
UImGuiUtility.Layout += OnLayout;
UImGuiUtility.OnInitialize += OnInitialize;
UImGuiUtility.OnDeinitialize += OnDeinitialize;
}
private void OnLayout(UImGui.UImGui obj)
{
// Unity Update method.
// Your code belongs here! Like ImGui.Begin... etc.
}
private void OnInitialize(UImGui.UImGui obj)
{
// runs after UImGui.OnEnable();
}
private void OnDeinitialize(UImGui.UImGui obj)
{
// runs after UImGui.OnDisable();
}
private void OnDisable()
{
UImGuiUtility.Layout -= OnLayout;
UImGuiUtility.OnInitialize -= OnInitialize;
UImGuiUtility.OnDeinitialize -= OnDeinitialize;
}
}
To use instance instead a global UImGui, use like this.
using UnityEngine;
public class InstanceSample : MonoBehaviour
{
[SerializeField]
private UImGui.UImGui _uimGuiInstance;
private void Awake()
{
if (_uimGuiInstance == null)
{
Debug.LogError("Must assign a UImGuiInstance or use UImGuiUtility with Do Global Events on UImGui component.");
}
_uimGuiInstance.Layout += OnLayout;
_uimGuiInstance.OnInitialize += OnInitialize;
_uimGuiInstance.OnDeinitialize += OnDeinitialize;
}
private void OnLayout(UImGui.UImGui obj)
{
// Unity Update method.
// Your code belongs here! Like ImGui.Begin... etc.
}
private void OnInitialize(UImGui.UImGui obj)
{
// runs after UImGui.OnEnable();
}
private void OnDeinitialize(UImGui.UImGui obj)
{
// runs after UImGui.OnDisable();
}
private void OnDisable()
{
_uimGuiInstance.Layout -= OnLayout;
_uimGuiInstance.OnInitialize -= OnInitialize;
_uimGuiInstance.OnDeinitialize -= OnDeinitialize;
}
}
Sample code
[SerializeField]
private float _sliderFloatValue = 1;
[SerializeField]
private string _inputText;
// Add listeners, etc ...
private void OnLayout(UImGui.UImGui obj)
{
ImGui.Text($"Hello, world {123}");
if (ImGui.Button("Save"))
{
Debug.Log("Save");
}
ImGui.InputText("string", ref _inputText, 100);
ImGui.SliderFloat("float", ref _sliderFloatValue, 0.0f, 1.0f);
}
[SerializeField]
private System.Numerics.Vector4 _myColor;
private bool _isOpen;
private void OnLayout(UImGui.UImGui obj)
{
// Create a window called "My First Tool", with a menu bar.
ImGui.Begin("My First Tool", ref _isOpen, ImGuiWindowFlags.MenuBar);
if (ImGui.BeginMenuBar())
{
if (ImGui.BeginMenu("File"))
{
if (ImGui.MenuItem("Open..", "Ctrl+O")) { /* Do stuff */ }
if (ImGui.MenuItem("Save", "Ctrl+S")) { /* Do stuff */ }
if (ImGui.MenuItem("Close", "Ctrl+W")) { _isOpen = false; }
ImGui.EndMenu();
}
ImGui.EndMenuBar();
}
// Edit a color (stored as ~4 floats)
ImGui.ColorEdit4("Color", ref _myColor);
// Plot some values
float[] my_values = new float[] { 0.2f, 0.1f, 1.0f, 0.5f, 0.9f, 2.2f };
ImGui.PlotLines("Frame Times", ref my_values[0], my_values.Length);
// Display contents in a scrolling region
ImGui.TextColored(new System.Numerics.Vector4(1, 1, 0, 1), "Important Stuff");
ImGui.BeginChild("Scrolling");
for (int n = 0; n < 50; n++)
ImGui.Text($"{n}: Some text");
ImGui.EndChild();
ImGui.End();
}
Image Sample
[SerializeField]
private Texture _sampleTexture;
private void OnLayout(UImGui.UImGui obj)
{
if (ImGui.Begin("Image Sample"))
{
System.IntPtr id = UImGuiUtility.GetTextureId(_sampleTexture);
System.Numerics.Vector2 size = new System.Numerics.Vector2(_sampleTexture.width, _sampleTexture.height)
ImGui.Image(id, size);
ImGui.End();
}
}
Custom UserData
[Serializable]
private struct UserData
{
public int SomeCoolValue;
}
[SerializeField]
private UserData _userData;
private string _input = "";
// Add Listeners... etc.
private unsafe void OnInitialize(UImGui.UImGui uimgui)
{
fixed (UserData* ptr = &_userData)
{
uimgui.SetUserData((IntPtr)ptr);
}
}
private unsafe void OnLayout(UImGui.UImGui obj)
{
if (ImGui.Begin("Custom UserData"))
{
fixed (UserData* ptr = &_userData)
{
ImGuiInputTextCallback customCallback = CustomCallback;
ImGui.InputText("label", ref _input, 100, ~(ImGuiInputTextFlags)0, customCallback, (IntPtr)ptr);
}
ImGui.End();
}
}
private unsafe int CustomCallback(ImGuiInputTextCallbackData* data)
{
IntPtr userDataPtr = (IntPtr)data->UserData;
if (userDataPtr != IntPtr.Zero)
{
UserData userData = Marshal.PtrToStructure<UserData>(userDataPtr);
Debug.Log(userData.SomeCoolValue);
}
// You must to overwrite how you handle with new inputs.
// ...
return 1;
}
You can see more samples here.
- Add a
Render Im Gui Feature
render feature to the renderer asset. - Assign it to the
render feature
field of the DearImGui component.
- When using the
High Definition Render Pipeline
, add a custom render pass and select "DearImGuiPass" injected after post processing. - Assign it to the
render feature
field of the DearImGui component. - See Known issues HDRP for more info.
No special sets.
Issue: Already using System.Runtime.CompilerServices.Unsafe.dll
will cause the following error: Multiple precompiled assemblies with the same name System.Runtime.CompilerServices.Unsafe.dll included or the current platform Only one assembly with the same name is allowed per platform. Resolution: add
REMOVE_UIMGUI_UNSAFE_DLL`` on Project Settings > Player > Other Settings > Script define symbols > Apply > Restart Unity Editor.
Original repo https://github.com/realgamessoftware/dear-imgui-unity
Thanks to @lacrc and @airtonmotoki for encouraging me.
https://www.conventionalcommits.org/en/v1.0.0/
https://semver.org/
https://github.com/yeyushengfan258/Lyra-Cursors
https://github.com/lob/generate-changelog
Dear ImGui is licensed under the MIT License, see LICENSE.txt for more information.