|
Hello everyone. I have a problem with the mouse accuracy in Unity and I'm trying to figure out why. When using the standard Mouse Look script, I noticed that it is impossible to maintain a good accuracy and control it smoothly. It's like it "jumps" over pixels, making it not very fun to aim and more difficult to aim at tiny spots than it should be. I'm trying to do a FPS and get the basics right one step at a time, so accuracy is important. At first I thought it was a issue with my custom setup, models etc. but I reproduced the issue in a seperate Project with nothing but standard assets. Here is a image GIF showing what I mean in this simplified seperate Project (moved 1px):
Here is also a Webplayer Demo of the Setup you can try it at. Try to aim at the bottles in small increments, like 1px at a time. The problem gets worse the more distance there is between you and the bottles: Play Webplayer Demo Here is the Unity Asset Package in Case you want to see the Project. Except for the simple Shooting and Crosshair it uses only Standard Asssets (FPS Input and MouseLook): Download Project Files here The issue has been confirmed on 5 PCs by 3 different people and has upset each one of them... Things I noticed in testing:
I hope someone has a solution for this. Thank you for your time and help Ray
(comments are locked)
|
|
The best way to get better precision is to square the values returned by Mouse X and Mouse Y - they range from -1 to +1, so these values squared will have better precision around 0. But just squaring the values would loose the original polarity, so we must multiply the axis value by its absolute value. The squared axes behave like they had variable sensitivity - low sensitivity for small movements, and high for large excursions.
using UnityEngine;
using System.Collections;
[AddComponentMenu("Camera-Control/Mouse Look")]
public class MouseLook : MonoBehaviour {
public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityX = 15F;
public float sensitivityY = 15F;
public float minimumX = -360F;
public float maximumX = 360F;
public float minimumY = -60F;
public float maximumY = 60F;
float rotationY = 0F;
void Update ()
{
float dx = Input.GetAxis("Mouse X");
dx = dx * Mathf.Abs(dx); // squares mouse x while keeping the polarity
float dy = Input.GetAxis("Mouse Y");
dy = dy * Mathf.Abs(dy); // squares mouse y while keeping the polarity
if (axes == RotationAxes.MouseXAndY)
{
float rotationX = transform.localEulerAngles.y + dx * sensitivityX;
rotationY += dy * sensitivityY;
rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0);
}
else if (axes == RotationAxes.MouseX)
{
transform.Rotate(0, dx * sensitivityX, 0);
}
else
{
rotationY += dy * sensitivityY;
rotationY = Mathf.Clamp (rotationY, minimumY, maximumY);
transform.localEulerAngles = new Vector3(-rotationY, transform.localEulerAngles.y, 0);
}
}
void Start ()
{
if (rigidbody) rigidbody.freezeRotation = true;
}
}
Seems pretty good to me. +1.
Aug 26 '11 at 05:20 AM
OrangeLightning
And it works good too, I sware!
Aug 26 '11 at 10:43 AM
aldonaletto
Thank you so much aldonaletto, this really helped and the accuracy is perfect. Maybe the mouse sensitivity makes the player turn a little too easy and too fast, but I take that any day for the enhanced accuracy your solution provides me. Thank you big time!
Aug 26 '11 at 04:16 PM
darky
Besides changing the sensitivity, you can clamp the variables dx and dy to -0.5 and 0.5, for instance - this will limit the speed in large movements.
Aug 26 '11 at 05:41 PM
aldonaletto
Thank you, this really improves the feel of aiming
Apr 04 at 10:10 AM
Linus
(comments are locked)
|


Yes it dose seem very, VERY inaccurate and I would like to know my self how to solve this. +1 and favorite.
First off, Thank you for writing a detailed question!
Its a balance between accuracy and mouse sensitivity. The only solution would be to take Mouse Acceleration into account by using the amount the user has moved the mouse in one frame.
Currently the script is essentially saying, rotate the transform 1 unit * sensitivity. How many pixels on the x-axis is based on the distance of the camera to that object.
But, this isn't a script problem, the script is doing exactly what its supposed to do. If you notice in most games when you go into sniper mode (or something similar) the sensitivity drops substantially to make it easier to pinpoint targets. However in normal walking around mode, this is usually how a game behaves with high mouse sensitivity. In your demo the mouse sensitivity was extremely high.
Lastly, look at your transform in the editor and make sure that the script is not rounding the rotation off. The rotationY should be a precise number like 38.8294389 not 38, 39 40 etc.