Question : enable/disable clickthrough

I’m making a game overlay and have a question.

I found the code (found below) to make my screen transparent and clickthrough.
But I want the clickthrough function to be disabled when the mouse is over a object of my overlay so it can be receive a mouse click.

Now i will be honest and say that I dont understand the code displayed below. but it does what I need. But I can not figure out what produces the clickthrough and how to toggle it on and off without affecting the tranparency.

Could anybody give me a hand please?

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
SetWindowLong(hwnd, -20, 524288 | 32);//GWL_EXSTYLE=-20; WS_EX_LAYERED=524288=&h80000, WS_EX_TRANSPARENT=32=0x00000020L
SetLayeredWindowAttributes(hwnd, 0, 255, 2);// Transparency=51=20%, LWA_ALPHA=2
SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, fWidth, fHeight, 32 | 64); //SWP_FRAMECHANGED = 0x0020 (32); //SWP_SHOWWINDOW = 0x0040 (64)
DwmExtendFrameIntoClientArea(hwnd, ref margins);

#endif
    }

    void OnRenderImage(RenderTexture from, RenderTexture to)
    {
        Graphics.Blit(from, to, m_Material);
    }
}

The code above is for a Windows-specific system-created overlay that lives entire “outside” of Unity3D, not for a Unity3D UI object. That means the above will only work on Windows, and when it is working, Unity will have no idea what is actually happening in it and Unity will not be able to control it directly at a fine scale.

There are plenty of online references for Windows system dialogs if that is really what you want (I doubt it).

If you want to look at how Unity3D’s internal UI system works, look here: Learn game development w/ Unity | Courses & tutorials in game design, VR, AR, & Real-time 3D | Unity Learn

The Unity3D UI will do pretty much everything you want, but you need to slowly work through the tutorials because there are a lot of interrelated moving parts.

Yes you are correct this is for a windows system. and it works fine. I can play the game as if the Unity window is even there (But it is, with invisible background)so i can see my UI, I just can’t interact with it anymore.

But thank you for pointing me in the right direction. I will move this question to a more specific c# (language) windows targeted forum.

1 Like

The Windows object is probably just getting all the the input events, just like a separate app on top of another app. I think if you need this solution, you will need to “retransmit” the input objects from the Windows object to whatever is below it, but someone more versed in Windows Messaging could probably better speak to that.