diff --git a/README.md b/README.md
index 0a0b2785e34958e7fbc54a9ede7458a2e790c51d..e01b4ce97f89619d964ad9a2198bbe116f49f8f6 100644
--- a/README.md
+++ b/README.md
@@ -22,14 +22,13 @@ This allows users to use the mouse for looking around, with seperate sensitivite
 ![](images/screenshot.png)
 
 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.
 
 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
-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`
-3. Select the `Capsule` Object
+2. Drag the `SmoothMouseLook.cs`-script from the Assets onto the `Player`-Empty. 
 
 ## Tweaking
 
diff --git a/SmoothMouseLook.cs b/SmoothMouseLook.cs
index 6fd803637215c89a6e42850f5f4754c7f608bbc8..b954dafec7c17e4835265e2e1088e09a50f56b91 100644
--- a/SmoothMouseLook.cs
+++ b/SmoothMouseLook.cs
@@ -1,86 +1,133 @@
+using System.Collections;
+using System.Collections.Generic;
 using UnityEngine;
 
 
-[AddComponentMenu("Camera/Simple Smooth Mouse Look ")]
+[AddComponentMenu("SmoothMouseLook ")]
 public class SmoothMouseLook : MonoBehaviour
 {
-    Vector2 _mouseAbsolute;
-    Vector2 _smoothMouse;
-    
-    [Tooltip("Limit the possible rotation to these values (Left/Right, Up/Down)")]
-    public Vector2 clampInDegrees = new Vector2(360, 180);
-    [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;
- 
+    // The speed at which we turn (Mouse Sensitivity)
+    // mouseSensitivity.x is for left <-> right 
+    // mouseSensitivity.y is for   up <-> down
+    [Tooltip("How fast to turn when moving the mouse (bigger=faster, X: left<->right, Y: up<->down).")]
+    [SerializeField] Vector2 mouseSensitivity = new Vector2(70f, 60f);
+
+    // 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()
     {
-        // Set target direction to the camera's initial orientation.
-        targetDirection = transform.localRotation.eulerAngles;
- 
-        // Set target direction for the character body to its inital state.
-        if (characterBody)
-            targetCharacterDirection = characterBody.transform.localRotation.eulerAngles;
+        // Find the head – this returns the transform parameter of this objects 
+        // first Child of type Camera. If none is found head = null 
+        head = GetComponentInChildren<Camera>().transform;
+
+        // Cache the orientation of body and head. 
+        // This errors if head (Camera Child) was not found
+        bodyStartOrientation = transform.localRotation;
+        headStartOrientation = head.transform.localRotation;
+
+        // Lock and hide the cursor
+        Cursor.lockState = CursorLockMode.Locked;
+        Cursor.visible = false;
     }
- 
-    void Update()
+
+
+
+    // A Easing function that smooths the mouse-movement. This is beeing
+    // 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)
     {
-        // Ensure the cursor is always locked when set
-        if (lockCursor)
-        {
-            Cursor.lockState = CursorLockMode.Locked;
-        }
- 
-        // 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.
+        // 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;
+    }
+
+
+
+    // Every time Physics updates, update the movemnent of this object.
+    // 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"));
- 
-        // Scale input against the sensitivity setting and multiply that against the smoothing value.
-        mouseDelta = Vector2.Scale(mouseDelta, new Vector2(sensitivity.x * smoothing.x, sensitivity.y * smoothing.y));
- 
-        // Interpolate mouse movement over time to apply smoothing delta.
-        _smoothMouse.x = Mathf.Lerp(_smoothMouse.x, mouseDelta.x, 1f / smoothing.x);
-        _smoothMouse.y = Mathf.Lerp(_smoothMouse.y, mouseDelta.y, 1f / smoothing.y);
- 
-        // Find the absolute mouse movement value from point zero.
-        _mouseAbsolute += _smoothMouse;
- 
-        // Clamp and apply the local x value first, so as not to be affected by world transforms.
-        if (clampInDegrees.x < 360)
-            _mouseAbsolute.x = Mathf.Clamp(_mouseAbsolute.x, -clampInDegrees.x * 0.5f, clampInDegrees.x * 0.5f);
- 
-        // Then clamp and apply the global y value.
-        if (clampInDegrees.y < 360)
-            _mouseAbsolute.y = Mathf.Clamp(_mouseAbsolute.y, -clampInDegrees.y * 0.5f, clampInDegrees.y * 0.5f);
- 
-        transform.localRotation = Quaternion.AngleAxis(-_mouseAbsolute.y, targetOrientation * Vector3.right) * targetOrientation;
- 
-        // If there's a character body that acts as a parent to the camera
-        if (characterBody)
-        {
-            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;
+
+        // Run the Smoothing-Function we defined above on the Mouse
+        // Vector we read before and return a smoothed one
+        smoothedMouseDelta = EaseMouseDelta(mouseDelta);
+
+        // Flip the vertical Control, if InvertAxisY is true
+        if (InvertAxisY) {
+            smoothedMouseDelta.y *= -1;
         }
+
+        // Add the mouse movements to the current value of yaw and pitch
+        yaw   += smoothedMouseDelta.x;
+        pitch += smoothedMouseDelta.y;
+
+        // Clamp pitch so that we can't look directly down or up
+        pitch = Mathf.Clamp(pitch, headLowerAngleLimit, headUpperAngleLimit);
+
+        // 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);
+
+        // Finally combine the rotations for body and head with the start rotations
+        transform.localRotation = bodyRotation * bodyStartOrientation;
+        head.localRotation      = headRotation * headStartOrientation;
     }
 }
- 
\ No newline at end of file