Coder Social home page Coder Social logo

imgui's Introduction

ImGui for Unreal Engine

Supercharge your Unreal Engine development with Dear ImGui. This plugin is designed to be as frictionless and easy to use as possible while seamlessly integrating all of ImGui's features into UE's ecosystem.

Features

  • Multi-viewports: Pull ImGui windows out of the application's frame (read more)
  • Docking: Combine and tear apart ImGui windows to create custom layouts (read more)
  • Editor support: Draw ImGui windows in Unreal Editor outside of game sessions
  • Play-in-Editor support: Each PIE session has its own ImGui context
  • Program support: Use ImGui in programs and standalone Slate applications
  • Remote drawing: Connect to headless (e.g. dedicated server) or remote sessions

Usage

  1. Clone this repository into your project's Plugins directory

  2. Add ImGui as a public or private dependency to your module's Build.cs file:

    PublicDependencyModuleNames.Add("ImGui");
  3. Include imgui.h and prior to using any ImGui functions create a local scoped context:

    #pragma once
    
    #include <GameFramework/Actor.h>
    #include <imgui.h>
    
    #include "ImGuiActor.generated.h"
    
    UCLASS()
    class AImGuiActor : public AActor
    {
    	GENERATED_BODY()
    
    public:
    	AImGuiActor()
    	{
    		PrimaryActorTick.bCanEverTick = true;
    	}
    
    	virtual void Tick(float DeltaTime) override
    	{
    		Super::Tick(DeltaTime);
    
    		const ImGui::FScopedContext ScopedContext;
    		if (ScopedContext)
    		{
    			// Your ImGui code goes here!
    			ImGui::ShowDemoWindow();
    		}
    	}
    };

This "scoped context" mechanism will push the appropriate ImGui context and pop it once it's gone out of scope. It's advised to check the ScopedContext like the example above to ensure that it's safe to draw.

Remote drawing

A prebuilt binary of the NetImGui Server application is included in Source/ThirdParty/NetImGuiServer. This application allows connecting to ImGui sessions either locally or on a remote device (e.g. dedicated server, console, mobile device).

There are two command-line arguments allowing you to automatically connect to a NetImGui Server:

  • Specifying -ImGuiHost=Host will attempt to automatically connect to a NetImGui Server on the specified host using the default port (8888) though this can be overridden using -ImGuiPort=Port; note that the host must already be running the NetImGui Server application otherwise this will be unsuccessful.
  • Specifying just -ImGuiPort=Port will attempt to automatically listen for a NetImGui Server connection. This is often the more convenient approach as you can then connect using NetImGui Server at any point in your session.

Alternatively you can drive this in code using FImGuiContext::Connect and FImGuiContext::Listen respectively:

const ImGui::FScopedContext ScopedContext;
if (ScopedContext.IsValid())
{
	ScopedContext->Listen(8888);
}

Usage in programs

You can utilise this plugin in Unreal programs and Slate applications, though for releases prior to UE 5.4 the latter will require integrating this PR.

You can either initialise an ImGui context manually using FImGuiContext::Create and use the remote drawing functionality outlined in the section above, or attach ImGui to a Slate application using FImGuiModule::CreateWindowContext.

Either way you will likely need to manually call FImGuiContext::BeginFrame and FImGuiContext::EndFrame at appropriate points in your application's main loop, as they usually rely on delegates fired from FEngineLoop::Tick which is often not executed in standalone programs for obvious reasons.

imgui's People

Contributors

coldencullen avatar jamesrawpower avatar vescodes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

imgui's Issues

Proper way to do user-side context initialization?

I've updated to latest according to #4 (comment) and I was going to remove my change to ImGuiContext.cpp to add new fonts when I realized that I still don't really know where to put those AddFont calls instead. Ideally this would have to be done when the context is first created but that happens in response to the Slate widget being created and that happens the first time an FScopedContext is used, so it could be anywhere.

Do you have a suggestion where to put this? Feels like either the ImGuiModule needs some customization where you can supply a delegate that's called when the context is first created, or I need to create the context explicitly at some well-known point on startup. However, that could be tricky itself because I would have to carefuly manage the lifetime of that context until the Slate widget has been created, which doesn't feel ideal.

Any ideas?

How to render images?

Hi,

thanks for this library, it works so much better than another library we were using beforehand!

I'm currently trying to render an image with ImGui. I found one example within the plugin itself where the font atlas is built and then the pointer to the UTexture2D is passed as an ImTextureID.

So I tried just passing a pointer to a UTexture2D (which is set as a default property on another class) to ImGui::Image but nothing is rendered. I also couldn't find where the conversion between ImTextureID and the actual draw commands is taking place so I can't say why it's not working.

Should this be supported?

Doesnt compile on UE5.3.2

It complains about

Severity	Code	Description	Project	File	Line	Suppression State
Error	C2039	'KeysDown': is not a member of 'ImGuiIO'	MyFirstProject	C:\Users\Neon\Documents\Unreal Projects\MyFirstProject\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiInteroperability.h	25	
Error	C2039	'NavInputs': is not a member of 'ImGuiIO'	MyFirstProject	C:\Users\Neon\Documents\Unreal Projects\MyFirstProject\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiInteroperability.h	26	
Error	C2039	'KeyMap': is not a member of 'ImGuiIO'	MyFirstProject	C:\Users\Neon\Documents\Unreal Projects\MyFirstProject\Plugins\UnrealImGui\Source\ImGui\Private\ImGuiInteroperability.h	28	

Checked and KeysDown is not defined in ImGuiIO. Do you used another version?

Found this after testing other versions like benui-dev and IDI-Systems and those worked fine.

Good job

Not an issue, just wanted to let you know I have found your codebase pleasing with its clean and minimalastic approach. And on top of it, you have Dear ImGui viewport support!

I am currently working on adding local drawing support in my UnrealNetImgui plugin, and I am also aiming for something simple and clear.

Good work.

Default font isn't packaged

ImGuiContext.cpp references the TTF file directly like this:

const FString FontPath = FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf");

This works fine in editor and non-staged builds, however as soon as you stage and/or package, ImGui reverts to the (quite ugly) default ImGui font.

One way to fix this is to add this line to your Build.cs file:

RuntimeDependencies.Add(Path.Combine(EngineDirectory, "Content/Slate/Fonts/Roboto-Regular.ttf"), StagedFileType.NonUFS);

Specifically, this needs to be of type NonUFS so that the file can be found using regular file operations, not just using the Unreal file system.

Handling key release after lost window focus

Hello,

I'm facing an issue where the ImGuiMod_Ctrl/Shift/Alt/Super keys are still considered to be down by the application after alt + shift tabbing out of the game window. This results in any call to ImGui::IsKeyDown(ImGuiKey_LeftAlt) == true before tabbing back or focusing the game window again. How would I best go about detecting focus loss and setting these keys to no longer being considered down? Or do you have any other ideas for how I should go about this?

And also, a big thank YOU for developing this excellent plugin🎉

Multi-viewport window glitching

ImGui windows created in the main viewport seem to glitch out badly when moved to the edges of the screen when running a game in standalone.

  • In fullscreen, it causes the imgui window to shrink down like in the image below (this seems to have started with the very latest commit, but it still pops really badly in the previous releases as well). This also seems to happen if the game window is resized.
    image

  • In windowed mode, IMGui windows can leave the main window, but are stuck on the same monitor as the game itself (they can extend further, but cannot be dragged off to the separate monitor entirely). This seems to be the case on both the latest and previous commits.

  • Disabling viewports using ImGui::GetIO().ConfigFlags &= ~ImGuiConfigFlags_ViewportsEnable; stops the imgui windows from trying to pop out of the game window, but instead causes incorrect mouse input location whenever the game window is located anywhere but the top-left corner of the monitor.

  • Using ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID); before individual windows seems to work for now with correct mouse input location. The demo window will occasionally break with this approach, probably as the main demo window isn't always drawn first when you call that function.

Commit: 67b82c1
Unreal: 5.4.3
Platform: Windows 10

Exclusive mouse control to imgui

Hello,

Thanks for your library. I find it very well designed.
I'm looking at replacing my Unreal Imgui integration (inspired by UnrealImGui) by yours in my project https://github.com/arnaud-jamin/Cog.

I have the following use case which forces me to modify your sources in a way I do not really like. Maybe you will come up with a better idea.

I want to give the option to the imgui user to change this dynamically:

  1. Disable imgui mouse. Then only the game handle the mouse.
  2. Share mouse between the game and imgui (imgui uses the mouse only over a imgui window otherwise it is for the game)
  3. Give exclusive control of the mouse to imgui. The game doesn't receive the mouse anymore.

Point 1) Can be done by using the flag ImGuiConfigFlags_NoMouse
Point 2) Can be done by disabling the flag ImGuiConfigFlags_NoMouse
Point 3) Can be done in different ways:

A) dynamically change the return value of the functions in input processor:

The InputProcessor could have a member variable "OnlyEnableImGuiMouse". Related functions would return true when this variable is true.

	virtual bool HandleMouseMoveEvent(FSlateApplication& SlateApp, const FPointerEvent& Event) override
	{
		[...]

                if (OnlyEnableImGuiMouse)
                {
                    return true;
                }    
		
                return IO.WantCaptureMouse;
	}

To be able to change that variable I would need to expose an accessor to the Overlay or the Context inside FScopedContext. Or I could create the Context by calling this:

TSharedPtr<FImGuiContext> ImGuiContext = FImGuiModule::Get().FindOrCreateContext();

Then I could keeping a reference to the created context and call a SetOnlyEnableImGuiMouse() on it. I would need to get the context from FScopedContext to do:

	virtual bool HandleMouseMoveEvent(FSlateApplication& SlateApp, const FPointerEvent& Event) override
	{
		ImGui::FScopedContext ScopedContext(Owner->GetContext());
                [...]

                if (ScopedContext.GetContext()->GetOnlyEnableImGuiMouse())
                {
                    return true;
                }    
		
                return IO.WantCaptureMouse;
	}

This doesn't seem great.

B) Another way to do this is to have a transparent imgui widget the cover the whole screen so IO.WantCaptureMouse always return true. (it could be the docking central node without ImGuiDockNodeFlags_PassthruCentralNode but made transparent)

Any suggestion ?

Thanks!

Inherent frame delay?

Hi,

I've noticed that when projecting a world position to screen and rendering a circle onto the ImGui background draw list at that position, that rendered circle will slightly lag behind when moving the camera.

I found that the plugin calls ImGui::Render just before calling ImGui::NewFrame in the same tick. That means all ImGui rendering will inherently be delayed by one tick since you only submit the render commands for the current tick in the next tick. Is there a reason why the plugin works this way? Could it be changed to submit render commands in the same tick?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.