[Solved: Here’s the code to create a virtual mouse cursor that triggers UI events.]
Is it possible to create a virtual mouse cursor (as a UI element on the canvas) that can trigger UI events such as hover and click? More importantly, a virtual mouse cursor that does not map 1:1 with the screen position of the actual mouse cursor?
My game has an unusual setup, because I’m recreating the rectangular pixel ratio of old CRT screens, and the UI is in a pixel-perfect 320x200 VGA-esque style. The UI canvas is rendered to a RenderTexture, which is then displayed on a scaled quad to create the correct pixel aspect ratio.
Here’s a screenshot with the canvas in editor view, and the final rendered quad in game view:
At present the fake mouse cursor is an Image on the canvas. I have it moving according to mouse input, but have not been able to figure out how to make it trigger UI events.
I’ve been googling this like mad, trying to learn the API for EventSystems, and have not been able to crack this nut. Do I manually raycast from the Image and invoke events via script? If so, I haven’t been able to figure out what in the API can actually do that.
Any help is appreciated, whether it’s just pointing me in the right direction, or a more thorough response.
I have the virtual cursor sending events instead of the mouse cursor. There’s a bug right now where hover events flicker on and off. Once I fix that and make sure nothing else is buggy, I’ll upload my code for others to use.
Here’s the virtual cursor triggering a hover event on an image button:
I used your script, but its only work with Screen Space- Camera render mode canvas. And also its only detect click when the virtual cursor is behind the button. If i set the sorting layer for my virtual cursor in front of the button, it doesnt detect the click.
Any idea how to fix this ?
May I ask about the script? I’m not used with the event system model, and the script supplied is not working for me. I’ve tested on a clean project, and no luck. The only thing that works, is the Virtual Cursor (from rect transform field). It register the mouse over event on the UI buttons. But it does not move itself.
I do want to do a dirty little fix, and simply move this rect transform on the SendMoveEventToSelectedObject() method, but I’m not sure if this would be bad usage of the PointerInputModule inheritance.
Also, bringing back reynolderwandi’s question, why the mouse over is only registered when the cursor is behind the button? That’s odd.
A modified StandaloneInputModule that allows UI events to be driven by a virtual mouse cursor. Does not handle cursor movement.
So you are supposed to make your own virtual cursor movement. I already done that by repositioning the virtual cursor based on mouse delay movement.
And in my case, i finally solved it by ignoring the raycast for my virtual cursor image (because we chose the first object that raycasted)
This is a very good solution for creating a virtual cursor, worked great on 5.4, but it’s broken now on 5.5
I looked at the source code of 5.5 UI system and couldn’t find anything new in the systems - don’t know what to do.
The problem is that virtual cursor doesn’t send PointerEnter and PointerExit events to UI objects. It doesn’t work with EventTrigger component, and it even doesn’t work with standart Button component (it doesn’t change the normal color to highlighted color).
The strangest thing is that this events started to work only when any of the mouse buttons are pressed and then released. I can press any mouse button on with virtual cursor on the any part of the screen, but if I release the button while the cursor is placed on object with PointerEnter even - the event is called then, and standart Button changes its color to a highlighted color.
Hi, this works lovely for me,im developing a game with kinect, and i need two cursors(one for each hand) how can i use your code and make it work for two virtual cursors instead of one.Thanks
Recently used this code to use a controller in my game’s menus. As my_little_kafka pointed out, it doesn’t seem to work in 5.5. I was not getting proper enter and exit events on the currently raycasted object.
I did a diff on the 5.5 and 5.2 code and found that in ProcessMouseEvent() they added this under the two variables like so:
protected void ProcessMouseEvent(int id) {
var mouseData = GetMousePointerEventData(id);
var leftButtonData = mouseData.GetButtonState(PointerEventData.InputButton.Left).eventData;
if (ForceAutoSelect())
eventSystem.SetSelectedGameObject(leftButtonData.buttonData.pointerCurrentRaycast.gameObject, leftButtonData.buttonData);
and when you look at Force AutoSelect() it’s just this:
So I changed that to TRUE and suddenly the current raycasted target from my controller move events was actually working~ Hooray. One note though, it doesn’t seem to parse through raycastable UI objects that don’t have buttons or events on them so be extra sure you keep a tight house when it comes to "raycast target"s
Hope I save someone the pain I just had spending 5 hours to realize I have to flip an easily overlooked bool.
It’s probably no longer compatible with the latest versions of Unity. I haven’t touched that code in a very long time. If anyone has the fix for it, feel free.