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.
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
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.