我正在尝试使用Unity为Windows操作系统制作覆盖图。 我从UnityForum的该线程中获得了所需的所有信息。 我使用的脚本如下:
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);
}
}
现在的事情是:透明度(可用于着色器和材质),Click-through和alwaysOnTop属性运行良好。但是,如果我单击窗口,则应用程序正在暂停。我如何实现该程序在不集中精力时不会暂停?
另一件事是,如果您在窗口中启动整个程序,那么整个程序就可以正常工作,而不是全屏显示。如果我以全屏模式启动,则当我单击某些内容时,它将最小化。
谢谢!
答案 0 :(得分:0)
它们可能都相关。 Unity有一个选项Application.runInBackground
应用程序在后台运行时,播放器是否应在运行?
默认值为
false
(应用程序在后台时暂停)。
您可以在脚本中启用它,例如
private void Awake()
{
Application.runInBackground = true;
}
或在播放器设置中编辑→项目设置→播放器→分辨率和演示文稿
启用在后台运行
在后台可见选项可能对您来说也很有趣
如果使用“窗口式全屏模式”(在Windows中),请启用此选项以在后台显示应用程序。
另请参阅Standalone Player settings。
一般提示:
您应该将整个Start
方法包装为
#if !UNITY_EDITOR
private void Start()
{
}
#endif
如果您不这样做,那还不错,但是Unity也会调用一个空的Start
方法,从而导致不必要的开销。