Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Override the mouse

Discussion in 'UGUI & TextMesh Pro' started by Robin-Jubber, Mar 19, 2015.

  1. Robin-Jubber

    Robin-Jubber

    Joined:
    Sep 7, 2012
    Posts:
    28
    Hi - an odd problem has just confronted me. Unity's (much improved) UI system allows easily adding event triggers to UI buttons - for instance my inventory slots all have On Click(), Mouse Enter, Begin Drag etc all calling functions within my code. Which is terrific on PC. On PS Vita it also works, with touchscreen use effectively acting as the mouse.

    My problem is that I want to add a joystick controlled cursor for fine control for the player. I can easily detect if no screentouch is happening, and control and draw my own fake mouse pointer, under joypad control. However... how do I get it to trigger UI triggers? I can't just write into mousePosition.x and y - they're read-only. Ditto the mouse click stuff.

    The horrible solution is to have an entire separate system running that emulates all of these features, for hundreds of buttons, when no mouse or touch is detected - but it would be much nicer to trigger the already existing UI functionality. Any thoughts on this humdinger would be much appreciated.
     
  2. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,685
  3. Robin-Jubber

    Robin-Jubber

    Joined:
    Sep 7, 2012
    Posts:
    28
    Simon - thanks very much for the response! I've not done something like you're suggesting in C# before - presumably I drop those files into my project (with new class and file names?) with the keyword override liberally sprinkled throughout? Presumably if I want to retain the original touchscreen functionality as well, I could check if the new cursor button is not held down, and just call the original functions from within the overridden ones. Sorry for noob questions!
     
  4. SimonDarksideJ

    SimonDarksideJ

    Joined:
    Jul 3, 2012
    Posts:
    1,685
    Shouldn't need to override, just create your own script and then attach it to the eventsystem GO. All it has to do is either inherit from the BaseInputModule or one of the others (if you just want to replace a specific process)
    You can have as many input modules attached to the EventSystem as you like (just don't go tooo crazy)

    There are no Noob questions, just incoherent and unresponsive solutions :p
     
  5. CodeMonke234

    CodeMonke234

    Joined:
    Oct 13, 2010
    Posts:
    181
  6. Robin-Jubber

    Robin-Jubber

    Joined:
    Sep 7, 2012
    Posts:
    28
    Cheers guys! After several days of banging my head against the desk and mourning the demise of comments, I've nearly got it to work, but not quite. I made a Joypad class, which tracks and draws a fake pointer, based on joypad and button presses. That bit works. I also made a Joystick_Input_Module.cs, based on StandaloneInputModule, and that nearly works. It is derived from Pointer_Input_Module.cs, which is similar to the original, except it checks the joystick buttons, not mouse buttons. The problem is that the X button is not being registered - in fact UI elements are getting On Exit messages when I press the X button. Any thoughts as to where I'm going wrong?

    Joystick_Input_Modules.cs (changes only listed)

    Code (CSharp):
    1.  
    2.   public override void UpdateModule()
    3.   {
    4.   m_LastMousePosition = m_MousePosition;
    5.   m_MousePosition = Joypad.position; // was Input.mousePosition;
    6.   }
    7.   public override bool ShouldActivateModule()
    8.   {
    9.   if( !base.ShouldActivateModule() )
    10.   return false;
    11.   var shouldActivate = Joypad.active; // ie L trigger held down
    12.   return shouldActivate;
    13.   }
    14.   public override void ActivateModule()
    15.   {
    16.   base.ActivateModule();
    17.   m_MousePosition = Joypad.position;// Input.mousePosition;
    18.   m_LastMousePosition = Joypad.position;// Input.mousePosition;
    19.   var toSelect = eventSystem.currentSelectedGameObject;
    20.   if( toSelect == null )
    21.   toSelect = eventSystem.lastSelectedGameObject;
    22.   if( toSelect == null )
    23.   toSelect = eventSystem.firstSelectedGameObject;
    24.   eventSystem.SetSelectedGameObject(toSelect, GetBaseEventData());
    25.   }
    26.   private bool SendSubmitEventToSelectedObject()
    27.   {
    28.   if( eventSystem.currentSelectedGameObject == null )
    29.   return false;
    30.   var data = GetBaseEventData();
    31.   if( Joypad.Select_Down() )//Input.GetButtonDown(m_SubmitButton) )
    32.   ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.submitHandler);
    33.   if( Input.GetButtonDown(m_CancelButton) )
    34.   ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, data, ExecuteEvents.cancelHandler);
    35.   return data.used;
    36.   }
    37.  
    and Pointer_Input_Module.cs (copied from PointerInputModule.cs)


    Code (CSharp):
    1. protected static PointerEventData.FramePressState StateForMouseButton( int buttonId )
    2.   {
    3.   //var pressed = Input.GetMouseButtonDown(buttonId);
    4.   //var released = Input.GetMouseButtonUp(buttonId);
    5.   bool pressed, released;
    6.   if( buttonId == 0 )
    7.   {
    8.   pressed = Joypad.Select_Down();
    9.   released = Joypad.Select_Up();
    10.   }
    11.   else
    12.   {
    13.   pressed = Joypad.Cancel_Down();
    14.   released = Joypad.Cancel_Up();
    15.   }
    16.   // [...] rest of function unaltered
    17.   }
    18.   protected virtual MouseState GetMousePointerEventData()
    19.   {
    20.   // Populate the left button...
    21.   PointerEventData leftData;
    22.   var created = GetPointerData(kMouseLeftId, out leftData, true);
    23.   leftData.Reset();
    24.   if( created )
    25.   leftData.position = Joypad.position;// Input.mousePosition;
    26.   Vector2 pos = Joypad.position;//Input.mousePosition;
    27.   leftData.delta = pos - leftData.position;
    28.   leftData.position = pos;
    29.   if( !Joypad.psp2 )
    30.   leftData.scrollDelta = Input.mouseScrollDelta;
    31.   else
    32.   leftData.scrollDelta = Vector2.zero;
    33.   // [...] rest of function unaltered
    34.   }
    Any help much appreciated - going slowly bananas trying to make it work. It's close - UI elements change state as the pointer moves over them.
    Cheers,
    Robin.