Search Unity

Input.mousePosition wrong in fullscreen

Discussion in 'Scripting' started by slice3d, Jul 28, 2015.

  1. slice3d

    slice3d

    Joined:
    May 7, 2011
    Posts:
    207
    Hey guys,

    I've just found significant issue where Input.mousePosition returns wrong value when running in fullscreen with aspect ratios different from native display aspect ratio.

    I've already filed a bug report (case 715666) and I'm posting this here only to share temporary workaround which partially resolves this issue for me / to find a better solution for this issue together before we will get the proper fix from Unity Technologies.

    Remaining issues:
    * Fix doesn't work when display resolution is not set to the native monitor resolution in Windows. (for example, when native display resolution is 1920x1080, windows resolution is set to 1280x800, game is launched with 1280x800)
    * Behaviour is unknown on Mac OS X (probably there is no such issue on OS X). Currently I don't have a Mac handy to check this.

    So, add this script to your project and instead of Input.mousePosition - use InputEx.mousePosition:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. static public class InputEx
    6. {
    7.     static private bool initialized = false;
    8.     static private int frame = -1;
    9.     static private float monitorAspect = 1.77f;
    10.    
    11.     static private Vector3 _mousePosition = new Vector3(0f, 0f, 0f);
    12.     static public Vector3 mousePosition
    13.     {
    14.         get
    15.         {
    16.             UpdateMousePosition();
    17.             return _mousePosition;
    18.         }
    19.     }
    20.  
    21.     static private void Initialize()
    22.     {
    23.         if (initialized) { return; }
    24.        
    25.         Resolution resolution = Screen.currentResolution;
    26.         Resolution[] resolutions = Screen.resolutions;
    27.         int maxWidth = resolution.width;
    28.         int maxHeight = resolution.height;
    29.         for (int i = 0, imax = resolutions.Length; i < imax; i++)
    30.         {
    31.             resolution = resolutions[i];
    32.             if (maxWidth < resolution.width) { maxWidth = resolution.width; }
    33.             if (maxHeight < resolution.height) { maxHeight = resolution.height; }
    34.         }
    35.         monitorAspect = (float)maxWidth / (float)maxHeight;
    36.         Debug.Log(string.Format("InputEx : maxWidth:{0}, maxHeight:{1}, monitorAspect:{2}", maxWidth, maxHeight, monitorAspect));
    37.        
    38.         initialized = true;
    39.     }
    40.    
    41.     static private void UpdateMousePosition()
    42.     {
    43.         if (frame == Time.frameCount) { return; }
    44.         frame = Time.frameCount;
    45.        
    46.         Initialize();
    47.        
    48.         _mousePosition = Input.mousePosition;
    49.  
    50.         if (!Screen.fullScreen || monitorAspect == -1f) { return; }
    51.        
    52.         float sw = Screen.width;
    53.         float sh = Screen.height;
    54.        
    55.         float currentAspect = sw / sh;
    56.        
    57.         if (currentAspect == -1f) { return; }
    58.  
    59.         // HACK Workaround for Unity bug
    60.         if (monitorAspect > currentAspect)
    61.         {
    62.             float wrongWidth = sh * monitorAspect;
    63.             _mousePosition.x = Mathf.Round((_mousePosition.x / wrongWidth) * sw);
    64.         }
    65.     }
    66. }
    67.  
     
    RobertWebb and LeftyRighty like this.
  2. RobertWebb

    RobertWebb

    Joined:
    Aug 3, 2015
    Posts:
    3
    I ran into the same problem. Your fix is half the solution, and works when the full-screen resolution is narrower than the native screen resolution, but I still had the problem when the aspect ratio was wider. Adding an else part to the final if-statement fixes this case too:

    Code (CSharp):
    1.         else if (monitorAspect < currentAspect)
    2.         {
    3.             float wrongHeight = sw / monitorAspect;
    4.             _mousePosition.y += wrongHeight - sh;
    5.             _mousePosition.y = Mathf.Round((_mousePosition.y / wrongHeight) * sh);
    6.         }