using UnityEngine; using System; using System.Runtime.InteropServices; public class TransparentBuildController : MonoBehaviour { // 右クリックドラッグでウィンドウを動かすための状態 public static bool Movable { get; private set; } = false; // ビルド版専用コード #if UNITY_STANDALONE_WIN && !UNITY_EDITOR // --- Win32 API --- // 実行中のプロセスのアクティブウィンドウハンドルを取得 [DllImport("user32.dll")] private static extern IntPtr GetActiveWindow(); // ウィンドウのスタイル(GWL_*)を取得するため [DllImport("user32.dll")] private static extern int GetWindowLong(IntPtr hWnd, int nIndex); // ウィンドウの画面上の矩形(位置とサイズ)を取得 [DllImport("user32.dll")] private static extern int GetWindowRect(IntPtr hWnd, out RECT lpRect); // 現在のカーソル(マウス)位置を取得 [DllImport("user32.dll")] private static extern int GetCursorPos(out POINT ipPoint); // ウィンドウのスタイルを設定(SetWindowLong)するため [DllImport("user32.dll")] private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong); // ウィンドウの Z オーダーや位置・サイズを設定 [DllImport("user32.dll")] private static extern bool SetWindowPos( IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); // レイヤードウィンドウの属性(透過設定など)を設定 [DllImport("user32.dll")] private static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags); // ウィンドウを指定位置・サイズに移動・リサイズ [DllImport("user32.dll")] private static extern int MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, int bRepaint); // --- 単純な RECT / POINT 構造体定義 --- // Win32 RECT 構造体に対応(Left, Top, Right, Bottom)。左上基準。 struct RECT { public int Left; public int Top; public int Right; public int Bottom; } // Win32 POINT 構造体に対応。スクリーン座標を保持。 struct POINT { public int X; public int Y; } // --- 定数定義(Win32 スタイル・フラグ) --- private const int GWL_STYLE = -16; private const int GWL_EXSTYLE = -20; private const int HWND_TOPMOST = -1; private const int WS_EX_LAYERED = 0x080000; private const int LWA_COLORKEY = 1; // ウィンドウスタイル(見えるウィンドウ、ポップアップ)を組み合わせる際に利用 private const uint WS_VISIBLE = 0x10000000; private const uint WS_POPUP = 0x80000000; // SetWindowPos のフラグ: 位置は変更しない(ここでは高さ幅をセットするが、フラグは適宜調整可能) private const uint SWP_NOMOVE = 0x0002; // 黒色を透過色に設定 private const uint COLOR_CODE = 0; // アクティブウィンドウのハンドル保持 private IntPtr _hwnd; // ドラッグ開始時のカーソル位置を保持 private POINT _cursorPosition; /// /// ウィンドウ透過処理 /// private void Start() { int width = Screen.width; int height = Screen.height; // 実行中のプロセスのアクティブウィンドウハンドルを取得 _hwnd = GetActiveWindow(); // ウィンドウスタイルを変更: 可視かつポップアップウィンドウに設定 SetWindowLong(_hwnd, GWL_STYLE, WS_VISIBLE | WS_POPUP); // ウィンドウを最前面にしてサイズを画面サイズに合わせる SetWindowPos(_hwnd, HWND_TOPMOST, 0, 0, width, height, SWP_NOMOVE); // 拡張スタイルにレイヤードフラグをセットして透過処理を可能にする SetWindowLong(_hwnd, GWL_EXSTYLE, WS_EX_LAYERED); // レイヤードウィンドウの属性を設定: // 色キー (LWA_COLORKEY) を使って第二引数で指定した色を透過 SetLayeredWindowAttributes(_hwnd, COLOR_CODE, 0, LWA_COLORKEY); } private void Update() { // アプリを終了するキーを設定 if (Input.GetKeyDown(KeyCode.Escape)) { Application.Quit(); } // 右クリック押下で移動モードに入る if (Input.GetMouseButtonDown(1)) { Movable = true; // ドラッグ開始時のカーソル位置を記録(スクリーン座標) GetCursorPos(out _cursorPosition); } else if (Input.GetMouseButtonUp(1)) { // 右クリック解除で移動モード終了 Movable = false; } if (Movable) { // 現在のカーソル位置を取得して差分を計算 GetCursorPos(out POINT currentPosition); int dx = currentPosition.X - _cursorPosition.X; int dy = currentPosition.Y - _cursorPosition.Y; // 差分がある場合のみウィンドウを移動 if (dx != 0 || dy != 0) { // 現在ウィンドウの矩形を取得して新しい位置を計算 GetWindowRect(_hwnd, out RECT rect); int x = rect.Left + dx; int y = rect.Top + dy; int width = rect.Right - rect.Left; int height = rect.Bottom - rect.Top; // MoveWindow で移動(必要に応じて最後の引数 bRepaint を 1 にして再描画) MoveWindow(_hwnd, x, y, width, height, 0); } // 次フレームの差分計算のため現在位置を保存 _cursorPosition = currentPosition; } } #endif }