Unity で Windows でウィンドウが最前面(TOPMOST)に表示し続けるアプリを作る
C# スクリプト内で Win32 API を操作することで実現できるよというメモ。
- using System.Runtime.InteropServices をする
- DllImport で必要な関数をインポートする(static extern をつける)
- Awake() で、SetWindowPos() をコールする
- SWP_NOSIZE でウィンドウサイズ指定を無視するようにした上で、表示するようにする
using UnityEngine; using System; using System.Runtime.InteropServices; public class WindowsAppManager : MonoBehaviour { #if !UNITY_EDITOR && UNITY_STANDALONE_WIN [DllImport("User32.dll")] private static extern IntPtr GetActiveWindow(); [DllImport("User32.dll")] private static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); private void Awake() { IntPtr windowHandle = GetActiveWindow(); IntPtr HWND_TOPMOST = new IntPtr(-1); // Places the window above all non-topmost windows. The window maintains its topmost position even when it is deactivated. const uint SWP_NOSIZE = 0x0001; // Retains the current size (ignores the cx and cy parameters) const uint SWP_SHOWWINDOW = 0x0040; // Displays the window SetWindowPos(windowHandle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW); } #endif // !UNITY_EDITOR && UNITY_STANDALONE_WIN }
もちろん Project Settings から、Windowed とウィンドウサイズを指定しておく。
400 x 200 くらいにして、デジタル時計アプリを作ってみた。
エクスプローラがアクティブだが、時計アプリの方がちゃんと上に来ている。
一応時計のスクリプトもメモ。
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using TMPro; public class ClockController : MonoBehaviour { public TextMeshProUGUI textMeshPro; private DateTime dt; private readonly WaitForSeconds w = new(1f); void Start() { _ = StartCoroutine(nameof(UpdateClock)); } IEnumerator UpdateClock() { for (; ; ) { SetTextClock(); yield return w; } } private void SetTextClock() { dt = DateTime.Now; string c = dt.Hour.ToString("00") + ":" + dt.Minute.ToString("00") + ":" + dt.Second.ToString("00"); textMeshPro.SetText(c); } }
参考: