World canvas Button not clickable with raycasting

Hi all

I have a UI setup where there is a world canvas, inside the world canvas there are 3 buttons.

Then i am using RayCasting to interact with anything that has the layer UI

Works great, except, as you can see in my images the buttons are non-clickable and looks like they’re a “layer” above the actual mouse / object

I cant click them, i am probably missing some fundamental knowledge
I have added an Event system to the button and the canvas, it wasnt there previously.

Appreciate your help and time so much thank you

putting images here one by one for your convenience


Bump

Do you have any raycaster component (something inheriting directly or indirectly from BaseRaycaster) attached to canvas?

Hey Karlis thanks for your reply and apologies for delay.

Im a bit new to unity (my first project) Yeah i have a ray cast component ( i think?) a little cursor pops up and follows the player mouse

see screenshot

Did you tried to read the warning which tells you about UI events potentially not working?

Well i do see some errors

RenderSettings customReflection texture has invalid type, 2D given while only CUBE is supported. Custom reflection texture will not be used
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)

Invalid editor window of type: UnityEditor.FallbackEditorWindow, title: Failed to load
UnityEditor.EditorApplicationLayout:FinalizePlaymodeLayout ()

Invalid editor window of type: UnityEditor.CurveEditorWindow, title: Curve
UnityEditor.EditorApplicationLayout:FinalizePlaymodeLayout ()

but i dont know what they are referring to, if its related or how to fix it

nice catch!

I’ve added the camera. but unfortunately still not clicks are registered

so… sort of a break through lol.

when i make the playable character inactive and create a new camera , register that with the world canvas the buttons are clickable

No idea why unfortunately :frowning:

Ok i found out why.

Cursor.lockState = CursorLockMode.Locked;

in one of my scripts. So basically i got to find a way to make the button click register with raycast which i will do by myself.

thanks for your help! thread can be closed

Makes sense. Since normally when you are looking around in first person mode you wouldn’t want to accidentally activate buttons or other UI elements from overlay UI.

If you want a fully functional UI with all the UI elements working as usual you will need to create a customized version of standalone input module. Overriding GetMousePointerEventData might be sufficient. Source code for StandaloneInputModule is available and quite easy to understand. Default input module doesn’t even fully disabling interactions it just sets the cursor position to (-1, -1). You would probably have to set it to middle of screen and either filter results of RayCastAll or also changing FindFirstRaycast to only look at world space canvases when in locked cursor mode.

// this is part of PointerInputModule code from which StandaloneInputModule inherits
protected virtual MouseState GetMousePointerEventData(int id)
        {
            // Populate the left button...
            PointerEventData leftData;
            var created = GetPointerData(kMouseLeftId, out leftData, true);

            leftData.Reset();

            if (created)
                leftData.position = input.mousePosition;

            Vector2 pos = input.mousePosition;
            if (Cursor.lockState == CursorLockMode.Locked)
            {
                // !!! replace this with middle of screen
                leftData.position = new Vector2(-1.0f, -1.0f);
                leftData.delta = Vector2.zero;
            }
            else
            {
                leftData.delta = pos - leftData.position;
                leftData.position = pos;
            }
            leftData.scrollDelta = input.mouseScrollDelta;
            leftData.button = PointerEventData.InputButton.Left;
            eventSystem.RaycastAll(leftData, m_RaycastResultCache);
            // add filtering for  m_raycastResultCache based on cursor lock state and canvas type
           // or replace FindFirstRayCast to do similar thing
           // you might even get away with not doing that since you probably won't have any overlay canvas buttons in the middle of screen while in locked cursor mode
            var raycast = FindFirstRaycast(m_RaycastResultCache);

But if you just want to click buttons with rest of UI interactions like hovering, dragging and interaction with other UI elements broken. Then there are approaches which require less code reading skills. Like manually checking raycast result and activating a button if hit.

Different approach would be switching to the computer when you interact with it. Something like this:

  • player approaches computer
  • press E to interact with computer
  • disable cursor lock mode and show the cursor
  • disable free looking camera
  • [optional] adjust camera position so that you are not looking at computer from angle
  • after computer interactions are done switch back to first person controls

Depending on complexity of UI you display last approach might be preferable since aiming at parts of screen or reading longer text from the normal first person view might be finicky.

1 Like