uimgui icon indicating copy to clipboard operation
uimgui copied to clipboard

ImGui and addressables (Win standalone x64)

Open flarsson87 opened this issue 3 years ago • 5 comments

Hi! Having trouble getting ImGui to to show in built applications. It works fine in the editor.

Subscribing to the OnImguiLayout event gives the regular callback in built application. Everything seems to be processing normally but the window/widgets won't render.

Unity version: 2021.2.16f1
Renderer: URP

Sample:

	public override void Render(UImGui.UImGui imgui) {
		UnityEngine.Debug.Log(" RENDER: " + this.GetType().Name);
		ImGui.Begin("DevParameters", ref m_Showing, ImGuiWindowFlags.MenuBar);
		{
			string search = "";
			ImGui.InputText("", ref search, 100);
			
			ImGui.Dummy(new UnityEngine.Vector2(0.0f, 10.0f));
			ImGui.Separator();
			ImGui.Dummy(new UnityEngine.Vector2(0.0f, 10.0f));

			foreach(var widget in m_Widgets) {
				widget.Render(imgui);
			}
		}
		ImGui.End();
	}

Example widget:

public class BoolInputWidget : ImGuiWidget
{
	private BoolParam m_Param = null;

	public BoolInputWidget(BoolParam param)
		: base(param.Label) 
	{
		m_Param = param;
	}

	public override bool Render(UImGui.UImGui imgui) {
		bool v = m_Param.Value;
		if(ImGui.Checkbox(Label, ref v)) {
			m_Param.SetValue(v);
			return true;
		}

		return false;
	}
}

Yields the debug log in built application but no window is rendering where as in the editor we get the correct behavior: image

flarsson87 avatar Apr 01 '22 06:04 flarsson87

Ok found reproduction steps.

Short: It seems that attaching a UImGui component to a prefab and loading it as an addressable and instantiated in runtime does not work.

  1. Create a UImGui prefab with the UImGui component disabled
  2. Assign it an address
  3. Load and instantiate the prefab through addressables
  4. Assign camera to the UImGui component (Main or other and add to camera stack if needed depending on setup)
  5. Enable UImGui component and try showing a widget

Placing the UImGui prefab in a /Resources/ directory and loading from there works fine and we get proper widgets in built applications.

My case for this is that I want to load and instantiate the UImGui prefab when I'm running a dev build and strip it from release builds. It also circumvents the need to place it in all scenes.

flarsson87 avatar Apr 01 '22 09:04 flarsson87

Hello there.

Could you share a project sample that doesn't work with addressable? That way other people could try to find a solution. As I'm working mac port, I can't try to solve this.

Sorry for the delayed response and thanks for reporting.

psydack avatar Apr 15 '22 14:04 psydack

I also experienced this but using scenes. If you load a scene using addressables with the UImGui script in it the UI doesn't render but the layout and update in it are called. It also happens just in builds, not in the editor.

simeonradivoev avatar Nov 18 '22 17:11 simeonradivoev

https://github.com/simeonradivoev/UimGui-Addressable-Bug here I made a project for it. Also uploaded a build https://github.com/simeonradivoev/UimGui-Addressable-Bug/releases/tag/bugged with the bug

simeonradivoev avatar Nov 18 '22 18:11 simeonradivoev

It looks like there's something wrong with this variable image Select this option for the addressables, than the problem will be reproduced in the editor, and you can debug it FUE~UCFIHLNKI0POHGF9WA3_tmb

Tou can see the imgui won't render.that's the bug. Click the renderFeatrue, you can see it is not points to the renderFeature which in your assets, I don't know where it points to.

Pull the renderFeature which in your assets to this variable could make the imgui render. But I don't know why this is happening.

I made a function called SetRenderFeature in the UImGui. And Get the renderFeature with code:

        public static ScriptableRendererFeature GetRenderFeature(UniversalRenderPipelineAsset asset, int index1, int index2)
        {
            var type = asset.GetType();
            var propertyInfo = type.GetField("m_RendererDataList", BindingFlags.Instance | BindingFlags.NonPublic);

            if (propertyInfo == null)
            {
                return null;
            }

            var scriptableRenderData = (ScriptableRendererData[])propertyInfo.GetValue(asset);

            if (scriptableRenderData != null && scriptableRenderData.Length > 0)
            {
                return scriptableRenderData[index1].rendererFeatures[index2];
            }
            return null;
        }

then use:

        var rf = GetRenderFeature(UniversalRenderPipeline.asset, 1, 0);
        uImGui.SetRenderFeature(rf);
        uImGui.gameObject.SetActive(true);

to solve this problem Hope to help.

r5r6ty avatar Dec 03 '23 17:12 r5r6ty