lime雑記

ゲーム開発、その他雑記。

【Unity】Dear ImGuiのメニューバー実装方法

この記事でのバージョン

Unity 2021.3.8f1
UImGui 4.1.1

概要

Dear ImGuiにおける、メニューバーの実装方法を解説。
Dear ImGui自体の紹介や導入方法は以下の記事を参照。
limegame.hatenablog.com

メニューバーとは


ゲーム画面上部に表示する上記のようなバー。
デバッグ機能使用の起点として便利。

実装方法

コード
public class ImGuiManager : MonoBehaviour {
  private void OnEnable() {
    UImGuiUtility.Layout += OnLayout;
  }

  private void OnDisable() {
    UImGuiUtility.Layout -= OnLayout;
  }

  private void OnLayout(UImGui.UImGui uImGui) {
    UpdateMenubar();
  }

  private void UpdateMenubar() {
    if (ImGuiNET.ImGui.BeginMainMenuBar()) {
      if (ImGuiNET.ImGui.BeginMenu("Test1")) {
        if (ImGuiNET.ImGui.MenuItem("Test2")) {
          Debug.Log("押された");
        }
        ImGuiNET.ImGui.EndMenu();
      }
      ImGuiNET.ImGui.EndMainMenuBar();
    }
  }
}

BeginMainMenuBar()でメニューバーの表示開始。

BeginMenu("Test1")でメニューのトップ項目の追加、表示。
→戻り値trueで選択されたときの処理

MenuItem("Test2")でメニュー内のアイテム追加、表示。
→戻り値trueで選択されたときの処理

マウスカーソルを重ねたときのみ表示する

ImGuiNET.ImGui.IsMouseHoveringRect関数を使用することでカーソルが重なっているかどうかが取得できる。
下記では、カーソルが重なっている、またはMenuを開いている場合表示するようにしている。

public class ImGuiManager : MonoBehaviour {
  private void OnEnable() {
    UImGuiUtility.Layout += OnLayout;
  }

  private void OnDisable() {
    UImGuiUtility.Layout -= OnLayout;
  }

  private void OnLayout(UImGui.UImGui uImGui) {
    UpdateMenubar();
  }

  private bool _isActiveMainMenuBar = false;

  private void UpdateMenubar() {
    bool isMouseHoverMainMenuBar = ImGuiNET.ImGui.IsMouseHoveringRect(Vector2.zero, new Vector2(Screen.width, ImGuiNET.ImGui.GetFrameHeight()), false);
    if (!isMouseHoverMainMenuBar && !_isActiveMainMenuBar) {
      return;
    }

    if (ImGuiNET.ImGui.BeginMainMenuBar()) {
      _isActiveMainMenuBar = false;
      if (ImGuiNET.ImGui.BeginMenu("Test1")) {
        _isActiveMainMenuBar = true;
        if (ImGuiNET.ImGui.MenuItem("Test2")) {
          Debug.Log("押された");
        }
        ImGuiNET.ImGui.EndMenu();
      }
      ImGuiNET.ImGui.EndMainMenuBar();
    }
  }
}