Perl日記

日々の知ったことのメモなどです。Perlは最近やってないです。

Unity で Windows でウィンドウが最前面(TOPMOST)に表示し続けるアプリを作る

C# スクリプト内で Win32 API を操作することで実現できるよというメモ。

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);
    }
}


参考: