Search Unity

Need help smoothing out my mouse look. (SOLVED)

Discussion in 'Scripting' started by Not_Sure, Aug 2, 2018.

  1. Not_Sure

    Not_Sure

    Joined:
    Dec 13, 2011
    Posts:
    2,673
    I'm still hammering away at my FPS controller and I think I'm about halfway there.

    My checklist looks like this right now:
    TO DO:
    -Stop clinging to walls mid air DONE
    -Ground Check DONE
    -fix movement direction DONE
    -Sprint DONE
    -Lock look up and down past 90 degrees DONE
    -Fix jump pad issue. jumpClock allows air control?! DONE
    -Create Motion direction DONE
    -Set velocity when jumping and walking off surface DONE

    -Smooth Mouselook
    -Set slope / Grip Ground
    -Weapon Camera
    -Fall / Velocity Damage
    -Prevent Motion Telescoping
    -Terminal Velocity
    -Sound Effects : Jump, Land, Possibly Footsteps
    -Optimize

    So now I'm trying to figure out why my mouse look is a jittery pile of trash:
    Code (CSharp):
    1.     void LookControls(){
    2.  
    3.         //Left and Right
    4.         mouseX = mouseXSensitivity * Input.GetAxis("Mouse X") * Time.deltaTime;
    5.         gameObject.transform.Rotate(0, mouseX, 0, Space.World);
    6.  
    7.         //Up and Down
    8.         mouseY += mouseYSensitivity * Input.GetAxis("Mouse Y") * Time.deltaTime;
    9.         mouseY = Mathf.Clamp(mouseY, -75, 75);
    10.         mainCamera.transform.localEulerAngles = new Vector3(-mouseY, 0, 0);
    11.     }
    My first thought are to apply a lerp to it, but that seems like it would hinder reaction time and I would have to dig into quaternions, which gives me a stomach ache just thinking about it.

    Any suggestions?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    5,601
    Generally you want a lowpass filter of some kind. Lerp is an easy way to do that and has nothing to do with Quaternions.

    Another way to do that is a time-smoothed average. You can get as complicated or as simple as you want with this.

    The basic idea is you have an accumulator that is your current input signal.

    When taking new input, if you just assign to that accumulator, you will be exactly where you are, no filtering.

    If instead you take X fraction of the accumulator and add it to (1 - X) fraction of the new input signal, then store it back into the accumulator, you have created a simple low pass filter. The data will be less responsive and less noisy.

    Mathf.Lerp is a handy way to do this. So is Vector3.Lerp to do it for multiple items at once.

    For instance, to handle just one axis, the X axis:

    Code (csharp):
    1. float xAccumulator; // this is a member variable, NOT a local!
    2.  
    3. const float Snappiness = 10.0f; // larger values of this cause less filtering, more responsiveness
    and then in your input reading function:

    Code (csharp):
    1. float inputX = Input.GetAxis("Horizontal");
    2.  
    3. xAccumulator = Mathf.Lerp( xAccumulator, inputX, Snappiness * Time.deltaTime);
    4.  
    5. // now go use xAccumulator where you would have used the raw inputX before
    The same above works for Vector2 and Vector3, with the appropriate Lerpers in those classes.
     
    Not_Sure likes this.
  3. Not_Sure

    Not_Sure

    Joined:
    Dec 13, 2011
    Posts:
    2,673
    Yep, that did the trick.

    Thanks!
     
    Kurt-Dekker likes this.
  4. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    12,488
    Why are you multiplying your mouse input by Time.deltaTime?

    Mouse input tells you how far the mouse has moved since last time it was checked. This is an absolute measurement. Assuming 1:1 (unaccelerated) input is desired, surely you want a certain amount of physical movement to result in the same amounf of in-game rotation regardless of speed? If you multiply by frame deltas then longer frames will result in more rotation for the same amount of mouse movement.
     
unityunity