I'm trying to make a Overlay for the Windows OS with Unity. I got all the information, needed for this from this thread in UnityForum. The script I used is the following:
using System;
using System.Runtime.InteropServices;
using UnityEngine;
public class TransparentWindow : MonoBehaviour
{
[SerializeField]
private Material m_Material;
private struct MARGINS
{
public int cxLeftWidth;
public int cxRightWidth;
public int cyTopHeight;
public int cyBottomHeight;
}
[DllImport("user32.dll")]
private static extern IntPtr GetActiveWindow();
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, uint dwNewLong);
[DllImport("user32.dll")]
static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]
static extern int SetLayeredWindowAttributes(IntPtr hwnd, int crKey, byte bAlpha, int dwFlags);
[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
private static extern int SetWindowPos(IntPtr hwnd, int hwndInsertAfter, int x, int y, int cx, int cy, int uFlags);
[DllImport("Dwmapi.dll")]
private static extern uint DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS margins);
const int GWL_STYLE = -16;
const uint WS_POPUP = 0x80000000;
const uint WS_VISIBLE = 0x10000000;
const int HWND_TOPMOST = -1;
void Start()
{
#if !UNITY_EDITOR // You really don't want to enable this in the editor..
int fWidth = Screen.width;
int fHeight = Screen.height;
var margins = new MARGINS() { cxLeftWidth = -1 };
var hwnd = GetActiveWindow();
SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
// Transparent windows with click through
//GWL_EXSTYLE=-20; WS_EX_LAYERED=524288=&h80000, WS_EX_TRANSPARENT=32=0x00000020L
SetWindowLong(hwnd, -20, 524288 | 32);
// Transparency=51=20%, LWA_ALPHA=2
SetLayeredWindowAttributes(hwnd, 0, 255, 2);
//SWP_FRAMECHANGED = 0x0020 (32); //SWP_SHOWWINDOW = 0x0040 (64)
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, fWidth, fHeight, 32 | 64);
DwmExtendFrameIntoClientArea(hwnd, ref margins);
#endif
}
void OnRenderImage(RenderTexture from, RenderTexture to)
{
Graphics.Blit(from, to, m_Material);
}
}
Now the thing is: The transparency(works with shader and material), the Click-through and the alwaysOnTop properties are working perfectly.But, if I click through the window, the application is pausing. How can I implemet, that the program is not pausing while not focused?
Another thing is, that the whole programm just works, if you start it windowed, but not in fullscreen. If i start in fullscreen, it minimizes, when I click something.
Thank you!
They might both be related. Unity has an option Application.runInBackground
Should the player be running when the application is in the background?
Default is
false
(application pauses when it is in the background).
You can enable it in your script like
private void Awake()
{
Application.runInBackground = true;
}
or in the Player settings Edit → Project Settings → Player → Resolution and Presentation
enable Run In Background
the option Visible in Background might be interresting for you as well
Enable this option to show the application in the background if Windowed Fullscreen Mode is used (in Windows).
Also see the Standalone Player settings for more information.
General tip:
You should rather wrap the entire Start
method with
#if !UNITY_EDITOR
private void Start()
{
}
#endif
If you don't it's not bad but also an empty Start
method will be called by Unity causing unnecessary overhead.
User contributions licensed under CC BY-SA 3.0