- Home /
How do you detect if the cursor is visible within another window?
I'm trying to get my unity game to run in the background while I play other games. I've got keyboard/mouse input working in the background thanks to ReWired.
But now I'm trying to figure out how to get my unity game to check if the cursor is visible or not.
So in Fortnite for instance, when you're in the menu screen, the cursor is visible. But when you get into playing the game (third-person shooter), the cursor disappears.
So I'm trying to get my background Unity game to detect when the cursor is visible and when it's not visible within another game. Does that make sense?
I tried:
If (Cursor.visible == true)
{
//Do this
}
Else if (Cursor.visible == false)
{
//Do this
}
But that didn't work. Only the true statement worked, as it thought the cursor was always visible, even though it wasn't.
I read somewhere that Cursor.visible only works within the Unity window and not anywhere else.
So what would I need to do to get this working? Any insight would be appreciated. Thanks!
(P.S. I only need this to work on Windows)
Answer by zachrodgers · Apr 10, 2019 at 06:51 PM
So I dove deep and figured out what I believe should work. But for some reason, update always returns the "else if" value right when I start up the game, even though the cursor is clearly visible. Any idea what I'm doing wrong?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Runtime.InteropServices;
public class DebuggingInfo : MonoBehaviour
{
[StructLayout(LayoutKind.Sequential)]
struct CURSORINFO
{
public Int32 cbSize;
public Int32 flags;
public IntPtr hCursor;
}
[DllImport("user32.dll")] static extern bool GetCursorInfo(out CURSORINFO pci);
const Int32 CURSOR_SHOWING = 0x00000001;
void Update()
{
CURSORINFO pci;
pci.flags = System.Runtime.InteropServices.Marshal.SizeOf(typeof(CURSORINFO));
if (pci.flags == CURSOR_SHOWING)
{
Debug.Log("Cursor is visible");
}
else if (pci.flags != CURSOR_SHOWING)
{
Debug.Log("Cursor is NOT visible");
}
}
}
Uhm, you never call "GetCursorInfo". Also it would make more sense to replace the "out" with a "ref". Also you HAVE TO initialize the cbSize member with the size of the structure so the GetCursorInfo method knows the size of the structure.
like this:
[DllImport("user32.dll")] static extern bool GetCursorInfo(ref CURSORINFO pci);
void Update()
{
// initialize the struct
CURSORINFO pci;
pci.cbSize = System.Runtime.InteropServices.$$anonymous$$arshal.SizeOf(typeof(CURSORINFO));
// Actually call GetCursorInfo
GetCursorInfo(ref pci);
if (pci.flags == CURSOR_SHOWING)
// [ ... ]
Ref makes more sense since the GetCursorInfo method does not fully initialize the struct and you actually have to set the size before calling the method. So it's not an out parameter.
When in doubt about win API methods, check the pinvoke reference
Thanks for the help! I've made the changes but I'm now getting 1 error on the "pci" portion of: GetCursorInfo(ref pci); It says " Use of unassigned local variable 'pci' "
Thoughts?
Yes, you should replace
CURSORINFO pci;
with
CURSORINFO pci = new CURSORINFO();
to actually initialize the whole struct with 0.
$$anonymous$$eep in $$anonymous$$d that this only works for checking if the "hardware cursor" is visible. If the game has a "virtual" cursor of course there's no method to check that since a virtual cursor is essentially just a rendered quad inside the game itself. If you use a virtual cursor the hardware cursor is always hidden.
Answer by Zaeran · Apr 10, 2019 at 04:00 PM
You'll likely have to call Windows' native cursor functions (specifically GetCursorInfo : https://docs.microsoft.com/en-gb/windows/desktop/api/winuser/nf-winuser-getcursorinfo ), quite possibly with a C++ DLL.
Thanks for the reply! I looked into that, but have no idea how to do it. Would you $$anonymous$$d sharing some more specific details?
I haven't done it in quite a while unfortunately, and Google has failed me.
You'll need to look at how to bring windows dlls into Unity. This post should be a good start: https://forum.unity.com/threads/windows-api-calls.127719/
You'll just need to figure out which dll it is you need