Unity Windows Overlay - PullRequest
       8

Unity Windows Overlay

0 голосов
/ 11 июня 2019

Я пытаюсь сделать оверлей для ОС Windows с Unity.Я получил всю информацию, необходимую для этого из этой темы в 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 работают отлично.Но, если я нажимаю через окно, приложение приостанавливается.Как я могу понять, что программа не останавливается, пока не сфокусирована?

Другое дело, что вся программа работает, если вы запускаете ее в окне, но не в полноэкранном режиме.Если я запускаю в полноэкранном режиме, он минимизируется, когда я что-то нажимаю.

Спасибо!

1 Ответ

0 голосов
/ 11 июня 2019

Они оба могут быть связаны. У Unity есть опция Application.runInBackground

Должен ли проигрыватель работать, когда приложение находится в фоновом режиме?

По умолчанию false (приложение приостанавливается, когда оно находится в фоновом режиме).

Вы можете включить его в своем скрипте как

private void Awake()
{
    Application.runInBackground = true;
}

или в настройках проигрывателя Редактировать & rightarrow; Настройки проекта & rightarrow; Player & rightarrow; Разрешение и презентация

включить Запуск в фоновом режиме

опция Видимая в фоновом режиме может быть интересна и для вас

Включите эту опцию, чтобы приложение отображалось в фоновом режиме, если используется оконный полноэкранный режим (в Windows).

enter image description here

Также см. Настройки автономного проигрывателя для получения дополнительной информации.


Общий совет:

Вы должны скорее обернуть весь Start метод с

#if !UNITY_EDITOR
    private void Start()
    {

    }
#endif

Если нет, то это не плохо, но Unity будет вызывать пустой метод Start, что приведет к ненужным накладным расходам.

...