Skip to content

Instantly share code, notes, and snippets.

@st4rdog
Last active October 14, 2022 21:59
Show Gist options
  • Save st4rdog/65ea593889a2c9561a579fe978ba530e to your computer and use it in GitHub Desktop.
Save st4rdog/65ea593889a2c9561a579fe978ba530e to your computer and use it in GitHub Desktop.
Unity - Smoothed mouse look for an FPS
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SmoothMouseLook : MonoBehaviour
{
private List<float> _xBuffer = new List<float>();
private List<float> _yBuffer = new List<float>();
private int _bufferIndex;
private float _targetRotX; // Used because _rotatorX needs its rotation assigned (instead of added).
[Header("Settings")]
public float _sensitivityX = 1.5f;
public float _sensitivityY = 1.5f;
[Space]
public float _minX = -90f;
public float _maxX = 90f;
[Space]
[Tooltip("The more steps, the smoother it will be.")]
public int _averageFromThisManySteps = 3;
[Header("References")]
[Tooltip("Object to be rotated when mouse moves up/down. Usually your Camera.")]
public Transform _rotatorX;
[Tooltip("Object to be rotated when mouse moves left/right. Usually your Player root GameObject for an FPS.")]
public Transform _rotatorY;
private void Start()
{
// Matches whatever your rotator is set to
_targetRotX = -_rotatorX.localEulerAngles.x;
}
private void LateUpdate()
{
var mouseDeltaX = Input.GetAxisRaw("Mouse X") * _sensitivityX;
var mouseDeltaY = Input.GetAxisRaw("Mouse Y") * _sensitivityY;
var (AveragedX, AveragedY) = GetAverages(mouseDeltaX, mouseDeltaY, _averageFromThisManySteps);
// Clamp X
_targetRotX += AveragedY;
_targetRotX = Mathf.Clamp(_targetRotX, _minX, _maxX);
// Rotate
_rotatorX.localRotation = Quaternion.Euler(-_targetRotX, 0f, 0f);
_rotatorY.Rotate(0f, AveragedX, 0f, Space.World);
}
(float AveragedX, float AveragedY) GetAverages(float mouseDeltaX, float mouseDeltaY, int steps = 3)
{
// Add entries until reached max number of steps, then mutate current entries only
if (_xBuffer.Count < steps)
{
_xBuffer.Add(mouseDeltaX);
_yBuffer.Add(mouseDeltaY);
_bufferIndex = steps - 1;
return (0f, 0f);
}
// Remove entries if max steps is reduced
else if (_xBuffer.Count > steps)
{
Remove();
void Remove()
{
if (_xBuffer.Count > steps)
{
_xBuffer.RemoveAt(0);
_yBuffer.RemoveAt(0);
Remove();
}
}
return (0f, 0f);
}
// Mutate entries
else
{
_xBuffer[_bufferIndex] = mouseDeltaX;
_yBuffer[_bufferIndex] = mouseDeltaY;
_bufferIndex++;
if (_bufferIndex >= steps)
_bufferIndex = 0;
}
// Average
var totalX = 0f;
var totalY = 0f;
for (int i = 0; i < steps - 1; i++)
{
totalX += _xBuffer[i];
totalY += _yBuffer[i];
}
return (totalX / steps, totalY / steps);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment