以下の内容はhttps://revsd.hatenablog.com/entry/2025/02/16/184832より取得しました。


UnityのスタンドアローンアプリでWindows11の丸角表示をさせない方法

PCの買い替えによりwin11導入

昨年のデジゲー博直前にPCが不調になり、イベント後すぐにPCを買い替えました。よく2イベント乗り越えられたもんですわ。
買い換えたPCはWindows11です。もともとROG Allyでwin11がどのような操作性かはうっすら把握していましたが、すぐに母艦PCもwin11に変わるとは思っていませんでした。

マジカルブラスターへの影響

win11に対して不満は山ほどありますが製作中のゲーム「マジカルブラスター」への影響も若干ながらあります。
マジブラは、低解像で作ってますよーということをネタにして、ウインドウ解像度240x160で動作させることが可能です。
しかしwin11ではアプリ側で制御しない限りウインドウの丸角が強制的に入ってしまうようです。
くっきり表示できることをウリにしているのに、丸角されると印象が変わってしまうので対応したい。

左が対応前(丸角あり)、右が対応後(丸角なし)

対応内容

アプリ起動時に、WindowsAPIを呼んでウインドウの属性を変更し、角丸させない設定にする。

資料1:Windows 11 向けデスクトップ アプリケーションで角の丸めを適用する
https://learn.microsoft.com/ja-jp/windows/apps/desktop/modernize/ui/apply-rounded-corners

角の丸めは、Windows 11 Geometry の最も注目すべき機能です。

だ、そうだ…無駄な手間かけさせやがって

サンプルとして、WPF やWinformアプリの実装例が記載されている。
これの通りにウインドウの情報の取得・丸角設定の変更を行う。

また、Unity上でどのようにWINAPIを扱うかを調べながら実装を行った。

資料2:Unity(C#)でWINAPIを使う
https://qiita.com/hakua-doublemoon/items/f3d44c0986a94bacaa74

ソースは以下の通り。

#if UNITY_STANDALONE_WIN
using UnityEngine;
using System;
using System.Runtime.InteropServices;

public class WindowRoundCanceller {

    [DllImport("user32.dll", EntryPoint = "FindWindow")]
    public static extern IntPtr FindWindow(System.String className, System.String windowName);

    public enum DWMWINDOWATTRIBUTE {
        DWMWA_WINDOW_CORNER_PREFERENCE = 33
    }

    public enum DWM_WINDOW_CORNER_PREFERENCE {
        DWMWCP_DEFAULT = 0,
        DWMWCP_DONOTROUND = 1,
        DWMWCP_ROUND = 2,
        DWMWCP_ROUNDSMALL = 3
    }

    [DllImport("dwmapi.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
    internal static extern void DwmSetWindowAttribute(IntPtr hwnd,
                                                     DWMWINDOWATTRIBUTE attribute,
                                                     ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
                                                     uint cbAttribute);

    [RuntimeInitializeOnLoadMethod]
    static void cancelWindowRound() {

        IntPtr hWnd = FindWindow(null,Application.productName);
        var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
        var preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_DONOTROUND;
        DwmSetWindowAttribute(hWnd, attribute, ref preference, sizeof(uint));

    }
}
#endif

#if UNITY_STANDALONE_WIN

exe実行時のみコードを実行させたいため、こちらを指定。

[RuntimeInitializeOnLoadMethod]

MonoBehaviourを継承してAwake()などの各ライフサイクルでもよいが、コンポーネントをつけるのが面倒、かつUpdate()等で常に実行や監視が必要なものでもないので、
アプリ起動時のみ実行される[RuntimeInitializeOnLoadMethod]で一度だけ実行させる。

FindWindow

資料1にてGetWindow(this)...等でウインドウ情報を取ってきているようだが、Unityで同じ方法はできないようなので資料2を参照。
FindWindow()を使用し、ウインドウ名を指定して取得する。
併せて、ProjectSettingで多重起動を封じ、ウインドウ名の重複を避ける。

DwmSetWindowAttribute

変更対象のアトリビュートに、丸角設定を司るDWMWA_WINDOW_CORNER_PREFERENCEを指定。
設定する値にDWMWCP_DONOTROUND(角丸させない)を指定。

以上!

以上で対応完了です。結果は記事の最初の画像の通りです。
起動後にフルスクリーンやボーダーレスに切り替えても、丸角なしは維持されるようです。

めっちゃ小さいウインドウ表示は一発ネタのつもりで実装しましたが、どうせやるなら画面の省略がないくっきり表示ができたほうが良いですよね。

FPS表示は、この解像度の時は消すようにします。上かぶせからゲーム内解像度に変えても邪魔だよなぁ。




以上の内容はhttps://revsd.hatenablog.com/entry/2025/02/16/184832より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14