[Solved] Simulating mouse inputs from code on a Canvas

Hello!

I’m looking into converting from DFGUI to uGUI for my current project but I rely heavily diegetic interfaces. In one instance, I render a GUI onto a curved monitor surface and interact with it in 3D space.

Steps:

  1. Render the GUI to texture.
  2. Apply texture to monitor surface.
  3. Raycast my mouse position on main camera to get RaycastHit info on the collider of the monitor surface.
  4. Translate the textureCoord values into GUI space coordinates. Push input to the GUI.

With uGUI, I’ve managed to replicate the rendering but I can’t figure out how to push input to the canvas given a known mouse position inside said canvas.

How do I push a mouse position or click onto a canvas at a given position inside its bounds?

Thanks!

How about using a world space canvas instead and using the event system physics ray caster to trigger the UI?

I did a video on the fake clicks here that might help. You could combine this with RayCastAll and you should get something relevant.

Very helpful, guys! I was able to call a Raycast on the Canvas’ Graphic Raycaster, took the results and translated them to pointer events to be executed on them.

One last problem:

The mouse position in my main camera is still being raycast to my Canvas. So when I mouse over a certain region in my main camera, buttons in my Canvas go into their highlighted behaviour, even though I set their Canvas to World Space and have it far off from where the main camera is facing.

I already tried suppressing the raycasts by attaching a CanvasGroup to my Canvas and disabling “Blocks Raycasts”. But, that also prevents the raycasts I’m calling from code.

So you want a raycaster that’s not included in the regular EventSystem checks?

There may be a better way to do it, but one hack that comes to mind is a transparent image in front of the screen that blocks the EventSystem.

I’m looking into making a custom input module that inherits from StandaloneInputModule to see if I can suppress events on objects inside a certain canvas. Will update as soon as I’ve tried it.

Sure enough! I implemented a custom Input module that overrides Process, ProcessMove and ProcessDrag and ignores any pointer events that are triggered on components contained inside a projected canvas while letting the others pass.

1 Like