david.cambre Posted August 24, 2020 Posted August 24, 2020 Hi, I am experimenting with UI. Using code below I try to switch the mouse state when i press F After reading these docs and looking in the sample i have not found a solution https://developer.unigine.com/en/docs/2.12/code/usage/mouse_customization/index?rlang=cpphttps://developer.unigine.com/en/docs/2.12/start/programmer/user_inputs?rlang=cshttps://developer.unigine.com/en/docs/2.12/start/programmer/ui?rlang=cpp The states only seem to work the first cycle. And i do not find what I am missing. private void Update() { if (Input.IsKeyDown(WidgedMode)) { switch (ControlsApp.MouseHandle) { case Input.MOUSE_HANDLE.GRAB: Input.MouseHandle = Input.MOUSE_HANDLE.SOFT; //ControlsApp.MouseHandle = Input.MOUSE_HANDLE.SOFT; Log.Message($"MOUSE_HANDLE.GRAB -> SOFT\n"); break; case Input.MOUSE_HANDLE.SOFT: Input.MouseHandle = Input.MOUSE_HANDLE.USER; //ControlsApp.MouseHandle = Input.MOUSE_HANDLE.USER; Log.Message($"MOUSE_HANDLE.SOFT -> USER\n"); break; case Input.MOUSE_HANDLE.USER: Input.MouseHandle = Input.MOUSE_HANDLE.GRAB; //ControlsApp.MouseHandle = Input.MOUSE_HANDLE.GRAB; Log.Message($"MOUSE_HANDLE.USER -> GRAB\n"); break; default: break; } } } Admitting i do not understand this sample in the docs /// Method toggling the mouse cursor's state public void ToggleMouseCursor() { // getting current mouse state bool enabled = controls_app.MouseEnabled; // toggling movement restriction to the application window area App.SetMouseGrab(enabled ? 0 : 1); // toggling mouse interaction with GUI elements gui.MouseEnabled = enabled; // toggling mouse control controls_app.MouseEnabled = !enabled; } Unigine v2.12.0.2 Thanks for the help
fox Posted August 25, 2020 Posted August 25, 2020 Hi David, Actually the code below works as it should (the only difference from your code is that the "F" key is specified explicitly, so maybe you should check your WidgedMode variable?): private void Update() { if (Input.IsKeyDown(Input.KEY.F)) { switch (ControlsApp.MouseHandle) { case Input.MOUSE_HANDLE.GRAB: Input.MouseHandle = Input.MOUSE_HANDLE.SOFT; //ControlsApp.MouseHandle = Input.MOUSE_HANDLE.SOFT; Log.Message($"MOUSE_HANDLE.GRAB -> SOFT\n"); break; case Input.MOUSE_HANDLE.SOFT: Input.MouseHandle = Input.MOUSE_HANDLE.USER; //ControlsApp.MouseHandle = Input.MOUSE_HANDLE.USER; Log.Message($"MOUSE_HANDLE.SOFT -> USER\n"); break; case Input.MOUSE_HANDLE.USER: Input.MouseHandle = Input.MOUSE_HANDLE.GRAB; //ControlsApp.MouseHandle = Input.MOUSE_HANDLE.GRAB; Log.Message($"MOUSE_HANDLE.USER -> GRAB\n"); break; default: break; } } } Thanks!
david.cambre Posted August 25, 2020 Author Posted August 25, 2020 Hi Fox, I simple do not get the expected response. Assuming Input.MouseHandle is the runtime equivalent of settings option. As you are able to see the grab state fails the second time around. The soft state reacts differently if i attach it to the default player or a new player actor. Any advise? Screen Recording (25-08-2020 20-03-18).wmv MouseTest.cs
fox Posted August 27, 2020 Posted August 27, 2020 Hi David, The mechanism is a bit complicated under the hood and affects several aspects (GUI interaction, camera control, and mouse visibility). Seems like you were switching the state from GRAB to SOFT while the mouse was grabbed, resulting in subsequent failures and unexpected mouse behavior (as some states were not restored properly). Check out this code for the Update() method of your component (should work as expected): private void Update() { label.Text = $"{Input.MouseCoord}"; label2.Text = $"{Input.MouseHandle}"; if (Input.IsMouseButtonDown(Input.MOUSE_BUTTON.LEFT))Log.Message($"Left click\n"); if (Input.IsKeyDown(SwapMouseHanleKey)) { Log.Message($"SwapMouseHanleKey pressed\n"); switch (ControlsApp.MouseHandle) { case Input.MOUSE_HANDLE.GRAB: if (App.MouseGrab)// if the mouse is currently grabbed, we disable grabbing and restore GUI interaction { App.MouseGrab = false; Gui.Get().MouseEnabled = true; } Input.MouseHandle = Input.MOUSE_HANDLE.SOFT; Log.Message($"MOUSE_HANDLE switch from GRAB to SOFT\n"); break; case Input.MOUSE_HANDLE.SOFT: Input.MouseHandle = Input.MOUSE_HANDLE.USER; Log.Message($"MOUSE_HANDLE switch from SOFT to USER\n"); break; case Input.MOUSE_HANDLE.USER: Input.MouseHandle = Input.MOUSE_HANDLE.GRAB; Log.Message($"MOUSE_HANDLE switch from USER to GRAB\n"); break; default: break; } } } As for the code sample in the docs that you mentioned, seems like it needs to be updated for 2.12 (will do that ASAP), sorry for the inconvenience caused! Thanks!
david.cambre Posted August 27, 2020 Author Posted August 27, 2020 Thank you @fox That works. I quickly tried to add a toggle to lock(grab) my mouse to the window without success. Maybe additional information to ad in the docs. A matrix of possible mouse situations? The difference wen editing in App. Controls. ControlsApp. Gui. They seems to have some overlap and interconnections.
fox Posted August 27, 2020 Posted August 27, 2020 If you want to restrict mouse cursor movement to the size of your application's window, while having the cursor visible, try adding the following to your component's Update() method: bool mouse_lock = false; // ... private void Update() { // ... // if we're in the USER handling mode and the Shift (STATE_RUN) key is pressed we toggle the lock if (Game.Player.Controls.ClearState(Controls.STATE_RUN) == 1 && Input.MouseHandle == Input.MOUSE_HANDLE.USER) { mouse_lock = !mouse_lock; } // when the lock is active we can simply clamp cursor's position if(mouse_lock && Input.MouseHandle == Input.MOUSE_HANDLE.USER) { App.SetMouse(MathLib.Clamp(Input.MouseCoord.x, 0, App.GetWidth()-1),MathLib.Clamp(Input.MouseCoord.y, 0, App.GetHeight()-1)); } } We'll add all necessary info regarding this aspect to docs. Thanks!
david.cambre Posted August 28, 2020 Author Posted August 28, 2020 Thank you Fox, I got everything to work as I expect. Only needed to check user status in the last if statement. Below the full readable code an Component for anyone wanting to MouseTest.cs public class MouseTest : Component { public Input.KEY SwapMouseHanleKey = Input.KEY.F; public Input.KEY SwapMouseLockKey = Input.KEY.G; private bool mouse_lock = false; public WidgetLabel LabelMouseXY; public WidgetLabel LabelMouseHandle; public WidgetLabel LabelMouseLocked; private void Init() { Unigine.Console.Run("show_messages 1"); LabelMouseXY = new WidgetLabel(); LabelMouseXY.FontSize = 20; LabelMouseHandle = new WidgetLabel(); LabelMouseHandle.FontSize = 20; LabelMouseLocked = new WidgetLabel(); LabelMouseLocked.FontSize = 20; Gui gui = Gui.Get(); gui.AddChild(LabelMouseXY,Gui.ALIGN_LEFT); gui.AddChild(LabelMouseHandle,Gui.ALIGN_LEFT); gui.AddChild(LabelMouseLocked,Gui.ALIGN_LEFT); } private void Update() { LabelMouseXY.Text = $"mouse position = {Input.MouseCoord}"; LabelMouseHandle.Text = $"mouse handle = {Input.MouseHandle}"; LabelMouseLocked.Text = $"mouse locked to screen = {mouse_lock}"; if (Input.IsMouseButtonDown(Input.MOUSE_BUTTON.LEFT))Log.Message($"Left click\n"); if (Input.IsKeyDown(SwapMouseHanleKey)) { Log.Message($"SwapMouseHanleKey pressed\n"); switch (ControlsApp.MouseHandle) { case Input.MOUSE_HANDLE.GRAB: // if the mouse is currently grabbed, we disable grabbing and restore GUI interaction if (App.MouseGrab) { App.MouseGrab = false; Gui.Get().MouseEnabled = true; } Input.MouseHandle = Input.MOUSE_HANDLE.SOFT; Log.Message($"MOUSE_HANDLE switch from GRAB to SOFT\n"); break; case Input.MOUSE_HANDLE.SOFT: Input.MouseHandle = Input.MOUSE_HANDLE.USER; Log.Message($"MOUSE_HANDLE switch from SOFT to USER\n"); break; case Input.MOUSE_HANDLE.USER: Input.MouseHandle = Input.MOUSE_HANDLE.GRAB; mouse_lock = false; Log.Message($"MOUSE_HANDLE switch from USER to GRAB\n"); break; default: break; } } if (Input.IsKeyDown(SwapMouseLockKey)) { mouse_lock = !mouse_lock; Log.Message($"SwapMouseLockKey pressed\n"); } if( mouse_lock && Input.MouseHandle == Input.MOUSE_HANDLE.USER || // Input.MouseHandle == Input.MOUSE_HANDLE.GRAB || //Make sure not to App.SetMouse() when in Grab mode. Input.MouseHandle == Input.MOUSE_HANDLE.SOFT) { App.SetMouse( MathLib.Clamp(Input.MouseCoord.x, 0, App.GetWidth()-1), MathLib.Clamp(Input.MouseCoord.y, 0, App.GetHeight()-1) ); } } } 1
fox Posted August 30, 2020 Posted August 30, 2020 Glad to be helpful, David! On 8/28/2020 at 7:41 PM, david.cambre said: Only needed to check user status in the last if statement. Yep, missed check, fixed the example above. Thanks!
the_m0rzh Posted September 28 Posted September 28 Sorry for my noob question, but is this still valid for 2.19? I mean, App class is no longer available, Gui.Get() is now Gui.GetCurrent() I guess. Any hint?
bmyagkov Posted September 30 Posted September 30 On 9/28/2024 at 7:43 PM, the_m0rzh said: Sorry for my noob question, but is this still valid for 2.19? I mean, App class is no longer available, Gui.Get() is now Gui.GetCurrent() I guess. Any hint? Instead of using ControlsApp and App please use the Input class. You can refer to the following methods for guidance: MouseGrab: https://developer.unigine.com/en/docs/2.19/api/library/controls/class.input?rlang=cs#MouseGrab MouseHandle: https://developer.unigine.com/en/docs/2.19/api/library/controls/class.input?rlang=cs#MouseHandle Thanks! 1
Recommended Posts