Skip to content
Snippets Groups Projects
Commit b3ca5151 authored by David Huss's avatar David Huss :speech_balloon:
Browse files

Update Mouselook Script

parent dc49399e
Branches
No related tags found
No related merge requests found
...@@ -22,14 +22,13 @@ This allows users to use the mouse for looking around, with seperate sensitivite ...@@ -22,14 +22,13 @@ This allows users to use the mouse for looking around, with seperate sensitivite
![](images/screenshot.png) ![](images/screenshot.png)
1. Add a Empty with <kbd>Rightclick</kbd> + `Add Empty`. Rename it to something useful (we used `Player`) 1. Add a Empty with <kbd>Rightclick</kbd> + `Add Empty`. Rename it to something useful (we used `Player`)
2. Make sure the `Main Camera` is at the coordinates `0, 1.7, 0` and then drag the `Main Camera` onto the `Player`-Empty. This makes `Player` the parent of `Main Camera` 2. Make sure the `Main Camera` is at the coordinates `(0, 1.7, 0)` and rotated right and then drag the `Main Camera` onto the `Player`-Empty. This makes `Player` the parent of `Main Camera`
3. Create a Capsule that represents the Player-Body (for collisions and such) with <kbd>Rightclick</kbd> + `3D Object` > `Capsule`. Drag it onto the `Player`-Empty as well. 3. Create a Capsule that represents the Player-Body (for collisions and such) with <kbd>Rightclick</kbd> + `3D Object` > `Capsule`. Drag it onto the `Player`-Empty as well.
Now things should look like in the picture above (highlighted in blue). Next we can add the Scripts. Now things should look like in the picture above (highlighted in blue). Next we can add the Scripts.
1. Drag the `FPSController.cs`-script from the Assets onto the `Player`-Empty 1. Drag the `FPSController.cs`-script from the Assets onto the `Player`-Empty
2. Drag the `SmoothMouseLook.cs`-script from the Assets onto the `Main Camera` Object. And in the Script options (right sidebar) change the value for _Character Body_ to `Player` 2. Drag the `SmoothMouseLook.cs`-script from the Assets onto the `Player`-Empty.
3. Select the `Capsule` Object
## Tweaking ## Tweaking
......
using System.Collections;
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
[AddComponentMenu("Camera/Simple Smooth Mouse Look ")] [AddComponentMenu("SmoothMouseLook ")]
public class SmoothMouseLook : MonoBehaviour public class SmoothMouseLook : MonoBehaviour
{ {
Vector2 _mouseAbsolute; // The speed at which we turn (Mouse Sensitivity)
Vector2 _smoothMouse; // mouseSensitivity.x is for left <-> right
// mouseSensitivity.y is for up <-> down
[Tooltip("Limit the possible rotation to these values (Left/Right, Up/Down)")] [Tooltip("How fast to turn when moving the mouse (bigger=faster, X: left<->right, Y: up<->down).")]
public Vector2 clampInDegrees = new Vector2(360, 180); [SerializeField] Vector2 mouseSensitivity = new Vector2(70f, 60f);
[Tooltip("Hide/Display Cursor")]
public bool lockCursor;
[Tooltip("Mouse Sensitivity (Left/Right, Up/Down)")]
public Vector2 sensitivity = new Vector2(2, 2);
[Tooltip("Movement Smoothing (Left/Right, Up/Down)")]
public Vector2 smoothing = new Vector2(3, 3);
[Tooltip("Set target direction to the camera's initial orientation.")]
public Vector2 targetDirection;
[Tooltip("Set target direction for the character body to its inital state.")]
public Vector2 targetCharacterDirection;
// Assign this if there's a parent object controlling motion, such as a Character Controller.
// Yaw rotation will affect this object instead of the camera if set.
[Tooltip("Assign Parent Object if there is one (affects horizontal rotation around Y axis)")]
public GameObject characterBody;
// How much smoothing goes on for each axis
[Tooltip("How smooth/mushy the mouse movement becomes (bigger=smoother, X: left<->right, Y: up<->down).")]
[SerializeField] Vector2 smoothing = new Vector2(2f, 2f);
// How far up the head can tilt, measured in angles from the horizon
// Must be bigger than headLowerAngleLimit
[Tooltip("How many degrees the head can look up at max.")]
[SerializeField] float headUpperAngleLimit = 85f;
// How far down the head can tilt, measured in angles from the horizon
// Must be smaller than headUpperAngleLimit
[Tooltip("How many degrees the head can look down at max.")]
[SerializeField] float headLowerAngleLimit = -80f;
// Invert the Y Axis of the Mouse if true
[Tooltip("Invert Mouse Control for up<->down.")]
[SerializeField] bool InvertAxisY = true;
// Our current rotation from start in degrees
float yaw = 0f;
float pitch = 0f;
// Stores the orientations of the head and body when the game started
// We'll derive new orientations by combining these with the variables yaw
// and pitch
Quaternion bodyStartOrientation;
Quaternion headStartOrientation;
// A reference to the head object (the object that will rotate up and down)
// The body is the current (this) object, so there is no variable needed.
// We don't want to expose this to the interface. Instead we just look for a
// Child object with type Camera, when the game starts.
Transform head;
// Two 2D-Vectors that store both axis of the mouse
private Vector2 smoothedMouseDelta;
// Start is called before the first frame update
void Start() void Start()
{ {
// Set target direction to the camera's initial orientation. // Find the head – this returns the transform parameter of this objects
targetDirection = transform.localRotation.eulerAngles; // first Child of type Camera. If none is found head = null
head = GetComponentInChildren<Camera>().transform;
// Set target direction for the character body to its inital state. // Cache the orientation of body and head.
if (characterBody) // This errors if head (Camera Child) was not found
targetCharacterDirection = characterBody.transform.localRotation.eulerAngles; bodyStartOrientation = transform.localRotation;
headStartOrientation = head.transform.localRotation;
// Lock and hide the cursor
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
} }
void Update()
{
// Ensure the cursor is always locked when set // A Easing function that smooths the mouse-movement. This is beeing
if (lockCursor) // done by making the head follow the mouse not exactly, but
// with some sort of a lag. The further away the heads point of focus
// is compared to the mouse, the faster it will move, once it comes
// closer, it slows down – this is called Easing.
//
// For an intuitive Explaination look here:
// https://processing.org/examples/easing.html
private Vector2 EaseMouseDelta(Vector2 mouseDelta)
{ {
Cursor.lockState = CursorLockMode.Locked; // Scale input against the sensitivity setting and multiply that
// with the smoothing value.
mouseDelta *= mouseSensitivity.x * smoothing.x * Time.deltaTime;
mouseDelta *= mouseSensitivity.y * smoothing.y * Time.deltaTime;
// Linear Interpolation ("Lerp") between the smoothed Delta from
// the last round/Frame and the actual mouse Position.
smoothedMouseDelta.x = Mathf.Lerp(smoothedMouseDelta.x, mouseDelta.x, 1f / smoothing.x);
smoothedMouseDelta.y = Mathf.Lerp(smoothedMouseDelta.y, mouseDelta.y, 1f / smoothing.y);
// Return the smoothed 2D-Vector
return smoothedMouseDelta;
} }
// Allow the script to clamp based on a desired target value.
var targetOrientation = Quaternion.Euler(targetDirection);
var targetCharacterOrientation = Quaternion.Euler(targetCharacterDirection);
// Get raw mouse input for a cleaner reading on more sensitive mice.
var mouseDelta = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
// Scale input against the sensitivity setting and multiply that against the smoothing value. // Every time Physics updates, update the movemnent of this object.
mouseDelta = Vector2.Scale(mouseDelta, new Vector2(sensitivity.x * smoothing.x, sensitivity.y * smoothing.y)); // Do this in FixedUpdate to keep pace with physically simulated Objects
void FixedUpdate()
{
// Read the Position-Change between this Frame and the last
// Note: GetRawAxis gives more sensitivity
var mouseDelta = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
// Interpolate mouse movement over time to apply smoothing delta. // Run the Smoothing-Function we defined above on the Mouse
_smoothMouse.x = Mathf.Lerp(_smoothMouse.x, mouseDelta.x, 1f / smoothing.x); // Vector we read before and return a smoothed one
_smoothMouse.y = Mathf.Lerp(_smoothMouse.y, mouseDelta.y, 1f / smoothing.y); smoothedMouseDelta = EaseMouseDelta(mouseDelta);
// Find the absolute mouse movement value from point zero. // Flip the vertical Control, if InvertAxisY is true
_mouseAbsolute += _smoothMouse; if (InvertAxisY) {
smoothedMouseDelta.y *= -1;
}
// Clamp and apply the local x value first, so as not to be affected by world transforms. // Add the mouse movements to the current value of yaw and pitch
if (clampInDegrees.x < 360) yaw += smoothedMouseDelta.x;
_mouseAbsolute.x = Mathf.Clamp(_mouseAbsolute.x, -clampInDegrees.x * 0.5f, clampInDegrees.x * 0.5f); pitch += smoothedMouseDelta.y;
// Then clamp and apply the global y value. // Clamp pitch so that we can't look directly down or up
if (clampInDegrees.y < 360) pitch = Mathf.Clamp(pitch, headLowerAngleLimit, headUpperAngleLimit);
_mouseAbsolute.y = Mathf.Clamp(_mouseAbsolute.y, -clampInDegrees.y * 0.5f, clampInDegrees.y * 0.5f);
transform.localRotation = Quaternion.AngleAxis(-_mouseAbsolute.y, targetOrientation * Vector3.right) * targetOrientation; // Compute rotations by rotating around a fixed axis (rotate yaw-degrees
// around the up direction for the body, and pitch degrees around the
// right direction for the head).
var bodyRotation = Quaternion.AngleAxis(yaw, Vector3.up);
var headRotation = Quaternion.AngleAxis(pitch, Vector3.right);
// If there's a character body that acts as a parent to the camera // Finally combine the rotations for body and head with the start rotations
if (characterBody) transform.localRotation = bodyRotation * bodyStartOrientation;
{ head.localRotation = headRotation * headStartOrientation;
var yRotation = Quaternion.AngleAxis(_mouseAbsolute.x, Vector3.up);
characterBody.transform.localRotation = yRotation * targetCharacterOrientation;
}
else
{
var yRotation = Quaternion.AngleAxis(_mouseAbsolute.x, transform.InverseTransformDirection(Vector3.up));
transform.localRotation *= yRotation;
}
} }
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment