Search Unity

Cinemachine Freelook ignores UI

Discussion in 'Cinemachine' started by piginhat, Aug 19, 2019.

  1. piginhat

    piginhat

    Joined:
    Feb 17, 2016
    Posts:
    82
    If I use the default setup whereby on mobile the CMFreelook is controlled by finger I find that it still accepts input if the finger movement is on a UI control.

    I have a joystick to control the players movement around the scene which works fine but as I move the joystick as the player moves the CMFreelook is moving too.
     
  2. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    2,845
    Your UI control has to consume the event to prevent it from being passed along to the rest of the game.

    I don't understand your second sentence. Can you clarify please?
     
  3. piginhat

    piginhat

    Joined:
    Feb 17, 2016
    Posts:
    82
    Sure, I can use my finger to move the freelook camera and it works fine. I then take my finger off the screen and then tap and hole the virtual UI joystick than moves the player as I move the joystick, but at the same time as I move my finger whilst on the joystick the freelook camera continues to process the finger movement
     
  4. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    2,845
    Sounds like the same problem. Your virtual joystick needs to consume the UI event.
     
  5. piginhat

    piginhat

    Joined:
    Feb 17, 2016
    Posts:
    82
    I understand re checking if the touch is over a UI using EventSystem.current.IsPointerOverGameObject(touch.fingerId) and have used this when interacting with buttons successfully, but I think my issue is different as it is the CMFreelook I believe should be testing for this surely?
     
  6. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    2,845
    I don't see how the FreeLook can check for that. It just takes input from the Input system. You need to make sure that the Input system doesn't get events that are meant for your UI. Maybe I'm mistaken, but I think Event.Use is supposed to take care of that.
     
  7. piginhat

    piginhat

    Joined:
    Feb 17, 2016
    Posts:
    82
    I have modified the custom input method to deal with touches and this seems to have fixed the problem in part.

    Although no it ignores the touch if over UI when I am not over UI I have to tap to move the camera it ignores the smooth sliding of the finger?

    So to clarify, when I am using the default Input for freelook I also have another UI joystick that controls the player.

    I can use my finger to control the camera and I can use the joystick to move the player and when touching the joystick the input no longer passes through to the freelook

    Code (CSharp):
    1.  
    2. public float GetAxisCustom(string axisName) {
    3.    
    4.         // if joysticks paused
    5.         if (GameManager.instance.pauseJoysticks) {
    6.        
    7.             // we don't want any inputs from them
    8.             return 0;
    9.         }
    10.  
    11.         // if using joystick
    12.         if (useCustomAxis) {
    13.  
    14.             if(axisName == "Mouse X") { // this is set in Editor-Inspector-CineMachineFreelook-AxisControl->X Axis
    15.  
    16.                 // return our input rather than system Mouse X
    17.                 return  UltimateJoystick.GetHorizontalAxis( "CameraJoystick" );
    18.             }
    19.             else if (axisName == "Mouse Y") { // this is set in Editor-Inspector-CineMachineFreelook-AxisControl->Y Axis
    20.  
    21.                 // return our input rather than system Mouse Y
    22.                 return UltimateJoystick.GetVerticalAxis( "CameraJoystick" );
    23.             }
    24.         }
    25.  
    26.         if (Input.touchCount > 0) {
    27.  
    28.             Touch touch = Input.GetTouch(0);
    29.  
    30.             if (EventSystem.current.IsPointerOverGameObject(touch.fingerId)) {
    31.  
    32.                 return 0;
    33.             }
    34.             else {
    35.  
    36.                 return Input.GetAxis(axisName);
    37.             }
    38.         }
    39.  
    40.         return Input.GetAxis(axisName);
    41.     }
    42.  
     
    Last edited: Sep 7, 2019
  8. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    2,845
    I don't know exactly what this does:
    Code (CSharp):
    1. if (EventSystem.current.IsPointerOverGameObject(touch.fingerId))
    Did you test that it is true when the touch is over the joystick? Try with Debug.Log in there to prove that it's the right test. Maybe there's a method inside UltimateJoystick that can tell you when it's being touched.
     
  9. piginhat

    piginhat

    Joined:
    Feb 17, 2016
    Posts:
    82
    Yes it is detecting the touch.

    I moved the touch code into the Update method and introduced a flag like so:

    Code (CSharp):
    1.  
    2. if (Input.touchCount > 0) {
    3.  
    4.             Touch touch = Input.GetTouch(0);
    5.  
    6.             // if over a UI element
    7.             if (EventSystem.current.IsPointerOverGameObject(touch.fingerId)) {
    8.  
    9.                 // ignore input
    10.                 disableFreelook = true;
    11.             }
    12.             else {
    13.  
    14.                 disableFreelook = false;
    15.             }
    16.         }
    17.  
    and then in the custom axis code I check like so:

    Code (CSharp):
    1.  
    2.        if (disableFreelook) {
    3.  
    4.             return 0;
    5.        }
    6.      
    7.  
    8.        return Input.GetAxis(axisName);
    9.  
    which results in the same single touch issue as described above.

    If I comment out the if statement in the custom axis code it works smoothly with finger but again the original issue returns. So the touch is being detected but then seems to only action the input per touch once rather than continuing to use the touch updates?
     
  10. Gregoryl

    Gregoryl

    Unity Technologies

    Joined:
    Dec 22, 2016
    Posts:
    2,845
    I suspect that EventSystem.current is only valid in some of the calls. Is there a way to query the joystick without making use of EventSystem.current?
     
  11. piginhat

    piginhat

    Joined:
    Feb 17, 2016
    Posts:
    82
    I will ask the creator of the Joystick and let you know...
     
  12. sacb0y

    sacb0y

    Joined:
    May 9, 2016
    Posts:
    178
    I am also having this issue, where the freelook camera reads position even if I'm selecting ui.

    It seems to activate under any touch event.
     
  13. piginhat

    piginhat

    Joined:
    Feb 17, 2016
    Posts:
    82
    Unfortunately for me I took the easy way out and decided to use a joystick for both freelook and player movement and not give the user a choice to use finger for freelook....I just did not want to spend anymore time on it :-(
     
  14. sacb0y

    sacb0y

    Joined:
    May 9, 2016
    Posts:
    178
    That's a shame, touch camera controls is crucial to my game, is there any info i can provide to help @Gregoryl ?\

    The funny thing is this is not an issue in unity remote, only on the actual build on the android platform. So it's really hard to test if i've even fixed the problem...
     
  15. piginhat

    piginhat

    Joined:
    Feb 17, 2016
    Posts:
    82
    The dev of Ultimate Joystick tried to help with using EventSystem.current.use() and touchinfo.use() in various methods but not resolved the issue.