diff --git a/Assets/SZZ/Code/Scripts/FirstPersonController.cs b/Assets/SZZ/Code/Scripts/FirstPersonController.cs
deleted file mode 100644
index 2091d6c443631f13d7d45087a27ea8792785d194..0000000000000000000000000000000000000000
--- a/Assets/SZZ/Code/Scripts/FirstPersonController.cs
+++ /dev/null
@@ -1,268 +0,0 @@
-using UnityEngine;
-#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
-using UnityEngine.InputSystem;
-#endif
-
-namespace StarterAssets
-{
-	[RequireComponent(typeof(CharacterController))]
-#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
-	[RequireComponent(typeof(PlayerInput))]
-#endif
-	public class FirstPersonController : MonoBehaviour
-	{
-		[Header("Player")]
-		[Tooltip("Move speed of the character in m/s")]
-		public float MoveSpeed = 4.0f;
-		[Tooltip("Sprint speed of the character in m/s")]
-		public float SprintSpeed = 6.0f;
-		[Tooltip("Rotation speed of the character")]
-		public float RotationSpeed = 1.0f;
-		[Tooltip("Acceleration and deceleration")]
-		public float SpeedChangeRate = 10.0f;
-
-		[Space(10)]
-		[Tooltip("The height the player can jump")]
-		public float JumpHeight = 1.2f;
-		[Tooltip("The character uses its own gravity value. The engine default is -9.81f")]
-		public float Gravity = -15.0f;
-
-		[Space(10)]
-		[Tooltip("Time required to pass before being able to jump again. Set to 0f to instantly jump again")]
-		public float JumpTimeout = 0.1f;
-		[Tooltip("Time required to pass before entering the fall state. Useful for walking down stairs")]
-		public float FallTimeout = 0.15f;
-
-		[Header("Player Grounded")]
-		[Tooltip("If the character is grounded or not. Not part of the CharacterController built in grounded check")]
-		public bool Grounded = true;
-		[Tooltip("Useful for rough ground")]
-		public float GroundedOffset = -0.14f;
-		[Tooltip("The radius of the grounded check. Should match the radius of the CharacterController")]
-		public float GroundedRadius = 0.5f;
-		[Tooltip("What layers the character uses as ground")]
-		public LayerMask GroundLayers;
-
-		[Header("Cinemachine")]
-		[Tooltip("The follow target set in the Cinemachine Virtual Camera that the camera will follow")]
-		public GameObject CinemachineCameraTarget;
-		[Tooltip("How far in degrees can you move the camera up")]
-		public float TopClamp = 90.0f;
-		[Tooltip("How far in degrees can you move the camera down")]
-		public float BottomClamp = -90.0f;
-
-		// cinemachine
-		private float _cinemachineTargetPitch;
-
-		// player
-		private float _speed;
-		private float _rotationVelocity;
-		private float _verticalVelocity;
-		private float _terminalVelocity = 53.0f;
-
-		// timeout deltatime
-		private float _jumpTimeoutDelta;
-		private float _fallTimeoutDelta;
-
-	
-#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
-		private PlayerInput _playerInput;
-#endif
-		private CharacterController _controller;
-		private StarterAssetsInputs _input;
-		private GameObject _mainCamera;
-
-		private const float _threshold = 0.01f;
-
-		private bool IsCurrentDeviceMouse
-		{
-			get
-			{
-				#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
-				return _playerInput.currentControlScheme == "KeyboardMouse";
-				#else
-				return false;
-				#endif
-			}
-		}
-
-		private void Awake()
-		{
-			// get a reference to our main camera
-			if (_mainCamera == null)
-			{
-				_mainCamera = GameObject.FindGameObjectWithTag("MainCamera");
-			}
-		}
-
-		private void Start()
-		{
-			_controller = GetComponent<CharacterController>();
-			_input = GetComponent<StarterAssetsInputs>();
-#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
-			_playerInput = GetComponent<PlayerInput>();
-#else
-			Debug.LogError( "Starter Assets package is missing dependencies. Please use Tools/Starter Assets/Reinstall Dependencies to fix it");
-#endif
-
-			// reset our timeouts on start
-			_jumpTimeoutDelta = JumpTimeout;
-			_fallTimeoutDelta = FallTimeout;
-		}
-
-		private void Update()
-		{
-			JumpAndGravity();
-			GroundedCheck();
-			Move();
-		}
-
-		private void LateUpdate()
-		{
-			CameraRotation();
-		}
-
-		private void GroundedCheck()
-		{
-			// set sphere position, with offset
-			Vector3 spherePosition = new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z);
-			Grounded = Physics.CheckSphere(spherePosition, GroundedRadius, GroundLayers, QueryTriggerInteraction.Ignore);
-		}
-
-		private void CameraRotation()
-		{
-			// if there is an input
-			if (_input.look.sqrMagnitude >= _threshold)
-			{
-				//Don't multiply mouse input by Time.deltaTime
-				float deltaTimeMultiplier = IsCurrentDeviceMouse ? 1.0f : Time.deltaTime;
-				
-				_cinemachineTargetPitch += _input.look.y * RotationSpeed * deltaTimeMultiplier;
-				_rotationVelocity = _input.look.x * RotationSpeed * deltaTimeMultiplier;
-
-				// clamp our pitch rotation
-				_cinemachineTargetPitch = ClampAngle(_cinemachineTargetPitch, BottomClamp, TopClamp);
-
-				// Update Cinemachine camera target pitch
-				CinemachineCameraTarget.transform.localRotation = Quaternion.Euler(_cinemachineTargetPitch, 0.0f, 0.0f);
-
-				// rotate the player left and right
-				transform.Rotate(Vector3.up * _rotationVelocity);
-			}
-		}
-
-		private void Move()
-		{
-			// set target speed based on move speed, sprint speed and if sprint is pressed
-			float targetSpeed = _input.sprint ? SprintSpeed : MoveSpeed;
-
-			// a simplistic acceleration and deceleration designed to be easy to remove, replace, or iterate upon
-
-			// note: Vector2's == operator uses approximation so is not floating point error prone, and is cheaper than magnitude
-			// if there is no input, set the target speed to 0
-			if (_input.move == Vector2.zero) targetSpeed = 0.0f;
-
-			// a reference to the players current horizontal velocity
-			float currentHorizontalSpeed = new Vector3(_controller.velocity.x, 0.0f, _controller.velocity.z).magnitude;
-
-			float speedOffset = 0.1f;
-			float inputMagnitude = _input.analogMovement ? _input.move.magnitude : 1f;
-
-			// accelerate or decelerate to target speed
-			if (currentHorizontalSpeed < targetSpeed - speedOffset || currentHorizontalSpeed > targetSpeed + speedOffset)
-			{
-				// creates curved result rather than a linear one giving a more organic speed change
-				// note T in Lerp is clamped, so we don't need to clamp our speed
-				_speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed * inputMagnitude, Time.deltaTime * SpeedChangeRate);
-
-				// round speed to 3 decimal places
-				_speed = Mathf.Round(_speed * 1000f) / 1000f;
-			}
-			else
-			{
-				_speed = targetSpeed;
-			}
-
-			// normalise input direction
-			Vector3 inputDirection = new Vector3(_input.move.x, 0.0f, _input.move.y).normalized;
-
-			// note: Vector2's != operator uses approximation so is not floating point error prone, and is cheaper than magnitude
-			// if there is a move input rotate player when the player is moving
-			if (_input.move != Vector2.zero)
-			{
-				// move
-				inputDirection = transform.right * _input.move.x + transform.forward * _input.move.y;
-			}
-
-			// move the player
-			_controller.Move(inputDirection.normalized * (_speed * Time.deltaTime) + new Vector3(0.0f, _verticalVelocity, 0.0f) * Time.deltaTime);
-		}
-
-		private void JumpAndGravity()
-		{
-			if (Grounded)
-			{
-				// reset the fall timeout timer
-				_fallTimeoutDelta = FallTimeout;
-
-				// stop our velocity dropping infinitely when grounded
-				if (_verticalVelocity < 0.0f)
-				{
-					_verticalVelocity = -2f;
-				}
-
-				// Jump
-				if (_input.jump && _jumpTimeoutDelta <= 0.0f)
-				{
-					// the square root of H * -2 * G = how much velocity needed to reach desired height
-					_verticalVelocity = Mathf.Sqrt(JumpHeight * -2f * Gravity);
-				}
-
-				// jump timeout
-				if (_jumpTimeoutDelta >= 0.0f)
-				{
-					_jumpTimeoutDelta -= Time.deltaTime;
-				}
-			}
-			else
-			{
-				// reset the jump timeout timer
-				_jumpTimeoutDelta = JumpTimeout;
-
-				// fall timeout
-				if (_fallTimeoutDelta >= 0.0f)
-				{
-					_fallTimeoutDelta -= Time.deltaTime;
-				}
-
-				// if we are not grounded, do not jump
-				_input.jump = false;
-			}
-
-			// apply gravity over time if under terminal (multiply by delta time twice to linearly speed up over time)
-			if (_verticalVelocity < _terminalVelocity)
-			{
-				_verticalVelocity += Gravity * Time.deltaTime;
-			}
-		}
-
-		private static float ClampAngle(float lfAngle, float lfMin, float lfMax)
-		{
-			if (lfAngle < -360f) lfAngle += 360f;
-			if (lfAngle > 360f) lfAngle -= 360f;
-			return Mathf.Clamp(lfAngle, lfMin, lfMax);
-		}
-
-		private void OnDrawGizmosSelected()
-		{
-			Color transparentGreen = new Color(0.0f, 1.0f, 0.0f, 0.35f);
-			Color transparentRed = new Color(1.0f, 0.0f, 0.0f, 0.35f);
-
-			if (Grounded) Gizmos.color = transparentGreen;
-			else Gizmos.color = transparentRed;
-
-			// when selected, draw a gizmo in the position of, and matching radius of, the grounded collider
-			Gizmos.DrawSphere(new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z), GroundedRadius);
-		}
-	}
-}
\ No newline at end of file
diff --git a/Assets/SZZ/Code/Scripts/IInteractable.cs b/Assets/SZZ/Code/Scripts/IInteractable.cs
new file mode 100644
index 0000000000000000000000000000000000000000..e2eb714abad187b6ea6c5fcea2f309ec7fcf323a
--- /dev/null
+++ b/Assets/SZZ/Code/Scripts/IInteractable.cs
@@ -0,0 +1,3 @@
+public interface IInteractable {
+    void Interact();
+}
diff --git a/Assets/SZZ/Code/Scripts/IInteractable.cs.meta b/Assets/SZZ/Code/Scripts/IInteractable.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..2a7c4dd3a37a5d2e9f5ca650fe5547c635ded806
--- /dev/null
+++ b/Assets/SZZ/Code/Scripts/IInteractable.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: e0699688ec2beb44c87ac15d736717d5
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/SZZ/Code/Scripts/PagePickupInteraction.cs b/Assets/SZZ/Code/Scripts/PagePickupInteraction.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b74a4f959c39f48942535ff4fd3d1df16eb99b70
--- /dev/null
+++ b/Assets/SZZ/Code/Scripts/PagePickupInteraction.cs
@@ -0,0 +1,10 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class PagePickupInteraction : MonoBehaviour, IInteractable {
+    public void Interact() {
+        Destroy(gameObject);
+        // TODO pickup page
+    }
+}
diff --git a/Assets/SZZ/Code/Scripts/PagePickupInteraction.cs.meta b/Assets/SZZ/Code/Scripts/PagePickupInteraction.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..d19826381dae2df8886244c3d4aeea78ddcbf41d
--- /dev/null
+++ b/Assets/SZZ/Code/Scripts/PagePickupInteraction.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4f94be2b68e6a06429261f0f3b61e60c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/SZZ/Code/InputSystem.meta b/Assets/SZZ/Code/Scripts/Player.meta
similarity index 77%
rename from Assets/SZZ/Code/InputSystem.meta
rename to Assets/SZZ/Code/Scripts/Player.meta
index 5d31ac9dc650fbba6421c5f2d8cbfe512e97ca2d..27eb6f72c3ca53d9ec139e83923bd9d934593ccb 100644
--- a/Assets/SZZ/Code/InputSystem.meta
+++ b/Assets/SZZ/Code/Scripts/Player.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 48c9acd554a28814b922162e3fa889b0
+guid: c9bde69cbb189844c9cea43a2b794a88
 folderAsset: yes
 DefaultImporter:
   externalObjects: {}
diff --git a/Assets/SZZ/Code/Scripts/Player/FirstPersonController.cs b/Assets/SZZ/Code/Scripts/Player/FirstPersonController.cs
new file mode 100644
index 0000000000000000000000000000000000000000..47392acab60b2c05cb493750a1a03980ad7a812e
--- /dev/null
+++ b/Assets/SZZ/Code/Scripts/Player/FirstPersonController.cs
@@ -0,0 +1,269 @@
+using UnityEngine;
+#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
+using UnityEngine.InputSystem;
+#endif
+
+namespace StarterAssets {
+    [RequireComponent(typeof(CharacterController))]
+#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
+    [RequireComponent(typeof(PlayerInput))]
+#endif
+    public class FirstPersonController : MonoBehaviour {
+        [Header("Player")]
+        [Tooltip("Move speed of the character in m/s")]
+        public float MoveSpeed = 4.0f;
+        [Tooltip("Sprint speed of the character in m/s")]
+        public float SprintSpeed = 6.0f;
+        [Tooltip("Rotation speed of the character")]
+        public float RotationSpeed = 1.0f;
+        [Tooltip("Acceleration and deceleration")]
+        public float SpeedChangeRate = 10.0f;
+
+        [Space(10)]
+        [Tooltip("The height the player can jump")]
+        public float JumpHeight = 1.2f;
+        [Tooltip("The character uses its own gravity value. The engine default is -9.81f")]
+        public float Gravity = -15.0f;
+
+        [Space(10)]
+        [Tooltip("Time required to pass before being able to jump again. Set to 0f to instantly jump again")]
+        public float JumpTimeout = 0.1f;
+        [Tooltip("Time required to pass before entering the fall state. Useful for walking down stairs")]
+        public float FallTimeout = 0.15f;
+
+        [Header("Player Grounded")]
+        [Tooltip("If the character is grounded or not. Not part of the CharacterController built in grounded check")]
+        public bool Grounded = true;
+        [Tooltip("Useful for rough ground")]
+        public float GroundedOffset = -0.14f;
+        [Tooltip("The radius of the grounded check. Should match the radius of the CharacterController")]
+        public float GroundedRadius = 0.5f;
+        [Tooltip("What layers the character uses as ground")]
+        public LayerMask GroundLayers;
+
+        [Header("Cinemachine")]
+        [Tooltip("The follow target set in the Cinemachine Virtual Camera that the camera will follow")]
+        public GameObject CinemachineCameraTarget;
+        [Tooltip("How far in degrees can you move the camera up")]
+        public float TopClamp = 90.0f;
+        [Tooltip("How far in degrees can you move the camera down")]
+        public float BottomClamp = -90.0f;
+
+        [Header("Interaction")]
+        [SerializeField] private float interactionDistance = 1.8f;
+        [SerializeField] private LayerMask interactionLayerMask;
+
+        // cinemachine
+        private float _cinemachineTargetPitch;
+
+        // player
+        private float _speed;
+        private float _rotationVelocity;
+        private float _verticalVelocity;
+        private float _terminalVelocity = 53.0f;
+
+        // timeout deltatime
+        private float _jumpTimeoutDelta;
+        private float _fallTimeoutDelta;
+
+        private InputAction _interactAction;
+
+
+#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
+        private PlayerInput _playerInput;
+#endif
+        private CharacterController _controller;
+        private StarterAssetsInputs _input;
+        private GameObject _mainCamera; // TODO remove
+
+        private const float _threshold = 0.01f;
+
+        private bool IsCurrentDeviceMouse {
+            get {
+#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
+                return _playerInput.currentControlScheme == "KeyboardMouse";
+#else
+				return false;
+#endif
+            }
+        }
+
+        private void Awake() {
+            _controller = GetComponent<CharacterController>();
+            _input = GetComponent<StarterAssetsInputs>();
+#if ENABLE_INPUT_SYSTEM && STARTER_ASSETS_PACKAGES_CHECKED
+            _playerInput = GetComponent<PlayerInput>();
+#else
+			Debug.LogError( "Starter Assets package is missing dependencies. Please use Tools/Starter Assets/Reinstall Dependencies to fix it");
+#endif
+
+            // get a reference to our main camera
+            if (_mainCamera == null)
+                _mainCamera = GameObject.FindGameObjectWithTag("MainCamera");
+
+            _interactAction = _playerInput.actions["Interact"];
+        }
+
+        private void OnEnable() {
+            _interactAction.performed += Interact;
+        }
+
+        private void OnDisable() {
+            _interactAction.performed += Interact;
+        }
+
+        private void Start() {
+            // reset our timeouts on start
+            _jumpTimeoutDelta = JumpTimeout;
+            _fallTimeoutDelta = FallTimeout;
+        }
+
+        private void Update() {
+            JumpAndGravity();
+            GroundedCheck();
+            Move();
+        }
+
+        private void LateUpdate() {
+            CameraRotation();
+        }
+
+        private void GroundedCheck() {
+            // set sphere position, with offset
+            Vector3 spherePosition = new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z);
+            Grounded = Physics.CheckSphere(spherePosition, GroundedRadius, GroundLayers, QueryTriggerInteraction.Ignore);
+        }
+
+        private void CameraRotation() {
+            // if there is an input
+            if (_input.look.sqrMagnitude >= _threshold) {
+                //Don't multiply mouse input by Time.deltaTime
+                float deltaTimeMultiplier = IsCurrentDeviceMouse ? 1.0f : Time.deltaTime;
+
+                _cinemachineTargetPitch += _input.look.y * RotationSpeed * deltaTimeMultiplier;
+                _rotationVelocity = _input.look.x * RotationSpeed * deltaTimeMultiplier;
+
+                // clamp our pitch rotation
+                _cinemachineTargetPitch = ClampAngle(_cinemachineTargetPitch, BottomClamp, TopClamp);
+
+                // Update Cinemachine camera target pitch
+                CinemachineCameraTarget.transform.localRotation = Quaternion.Euler(_cinemachineTargetPitch, 0.0f, 0.0f);
+
+                // rotate the player left and right
+                transform.Rotate(Vector3.up * _rotationVelocity);
+            }
+        }
+
+        private void Move() {
+            // set target speed based on move speed, sprint speed and if sprint is pressed
+            float targetSpeed = _input.sprint ? SprintSpeed : MoveSpeed;
+
+            // a simplistic acceleration and deceleration designed to be easy to remove, replace, or iterate upon
+
+            // note: Vector2's == operator uses approximation so is not floating point error prone, and is cheaper than magnitude
+            // if there is no input, set the target speed to 0
+            if (_input.move == Vector2.zero) targetSpeed = 0.0f;
+
+            // a reference to the players current horizontal velocity
+            float currentHorizontalSpeed = new Vector3(_controller.velocity.x, 0.0f, _controller.velocity.z).magnitude;
+
+            float speedOffset = 0.1f;
+            float inputMagnitude = _input.analogMovement ? _input.move.magnitude : 1f;
+
+            // accelerate or decelerate to target speed
+            if (currentHorizontalSpeed < targetSpeed - speedOffset || currentHorizontalSpeed > targetSpeed + speedOffset) {
+                // creates curved result rather than a linear one giving a more organic speed change
+                // note T in Lerp is clamped, so we don't need to clamp our speed
+                _speed = Mathf.Lerp(currentHorizontalSpeed, targetSpeed * inputMagnitude, Time.deltaTime * SpeedChangeRate);
+
+                // round speed to 3 decimal places
+                _speed = Mathf.Round(_speed * 1000f) / 1000f;
+            }
+            else {
+                _speed = targetSpeed;
+            }
+
+            // normalise input direction
+            Vector3 inputDirection = new Vector3(_input.move.x, 0.0f, _input.move.y).normalized;
+
+            // note: Vector2's != operator uses approximation so is not floating point error prone, and is cheaper than magnitude
+            // if there is a move input rotate player when the player is moving
+            if (_input.move != Vector2.zero) {
+                // move
+                inputDirection = transform.right * _input.move.x + transform.forward * _input.move.y;
+            }
+
+            // move the player
+            _controller.Move(inputDirection.normalized * (_speed * Time.deltaTime) + new Vector3(0.0f, _verticalVelocity, 0.0f) * Time.deltaTime);
+        }
+
+        private void JumpAndGravity() {
+            if (Grounded) {
+                // reset the fall timeout timer
+                _fallTimeoutDelta = FallTimeout;
+
+                // stop our velocity dropping infinitely when grounded
+                if (_verticalVelocity < 0.0f) {
+                    _verticalVelocity = -2f;
+                }
+
+                // Jump
+                if (_input.jump && _jumpTimeoutDelta <= 0.0f) {
+                    // the square root of H * -2 * G = how much velocity needed to reach desired height
+                    _verticalVelocity = Mathf.Sqrt(JumpHeight * -2f * Gravity);
+                }
+
+                // jump timeout
+                if (_jumpTimeoutDelta >= 0.0f) {
+                    _jumpTimeoutDelta -= Time.deltaTime;
+                }
+            }
+            else {
+                // reset the jump timeout timer
+                _jumpTimeoutDelta = JumpTimeout;
+
+                // fall timeout
+                if (_fallTimeoutDelta >= 0.0f) {
+                    _fallTimeoutDelta -= Time.deltaTime;
+                }
+
+                // if we are not grounded, do not jump
+                _input.jump = false;
+            }
+
+            // apply gravity over time if under terminal (multiply by delta time twice to linearly speed up over time)
+            if (_verticalVelocity < _terminalVelocity) {
+                _verticalVelocity += Gravity * Time.deltaTime;
+            }
+        }
+
+        private static float ClampAngle(float lfAngle, float lfMin, float lfMax) {
+            if (lfAngle < -360f) lfAngle += 360f;
+            if (lfAngle > 360f) lfAngle -= 360f;
+            return Mathf.Clamp(lfAngle, lfMin, lfMax);
+        }
+
+        private void Interact(InputAction.CallbackContext context) {
+            RaycastHit hitData;
+            Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));
+            Debug.DrawRay(ray.origin, ray.direction * interactionDistance, Color.magenta, 3);
+            if (Physics.Raycast(ray, out hitData, interactionDistance)) {
+                var hitObject = hitData.transform.gameObject;
+                if (hitObject.CompareTag("Interactable")) {
+                    hitObject.GetComponent<IInteractable>()?.Interact();
+                }
+            }
+        }
+
+        private void OnDrawGizmosSelected() {
+            Color transparentGreen = new Color(0.0f, 1.0f, 0.0f, 0.35f);
+            Color transparentRed = new Color(1.0f, 0.0f, 0.0f, 0.35f);
+
+            if (Grounded) Gizmos.color = transparentGreen;
+            else Gizmos.color = transparentRed;
+
+            // when selected, draw a gizmo in the position of, and matching radius of, the grounded collider
+            Gizmos.DrawSphere(new Vector3(transform.position.x, transform.position.y - GroundedOffset, transform.position.z), GroundedRadius);
+        }
+    }
+}
diff --git a/Assets/SZZ/Code/Scripts/FirstPersonController.cs.meta b/Assets/SZZ/Code/Scripts/Player/FirstPersonController.cs.meta
similarity index 100%
rename from Assets/SZZ/Code/Scripts/FirstPersonController.cs.meta
rename to Assets/SZZ/Code/Scripts/Player/FirstPersonController.cs.meta
diff --git a/Assets/SZZ/Code/InputSystem/StarterAssetsInputs.cs b/Assets/SZZ/Code/Scripts/Player/StarterAssetsInputs.cs
similarity index 99%
rename from Assets/SZZ/Code/InputSystem/StarterAssetsInputs.cs
rename to Assets/SZZ/Code/Scripts/Player/StarterAssetsInputs.cs
index a76dc773cf01a322f6d45f33be5662076dcdf36c..ff962cb3b3424665da8472364e6d9006b1e201dd 100644
--- a/Assets/SZZ/Code/InputSystem/StarterAssetsInputs.cs
+++ b/Assets/SZZ/Code/Scripts/Player/StarterAssetsInputs.cs
@@ -49,7 +49,7 @@ public void OnSprint(InputValue value)
 		public void MoveInput(Vector2 newMoveDirection)
 		{
 			move = newMoveDirection;
-		} 
+		}
 
 		public void LookInput(Vector2 newLookDirection)
 		{
@@ -65,7 +65,7 @@ public void SprintInput(bool newSprintState)
 		{
 			sprint = newSprintState;
 		}
-		
+
 		private void OnApplicationFocus(bool hasFocus)
 		{
 			SetCursorState(cursorLocked);
@@ -76,5 +76,5 @@ private void SetCursorState(bool newState)
 			Cursor.lockState = newState ? CursorLockMode.Locked : CursorLockMode.None;
 		}
 	}
-	
-}
\ No newline at end of file
+
+}
diff --git a/Assets/SZZ/Code/InputSystem/StarterAssetsInputs.cs.meta b/Assets/SZZ/Code/Scripts/Player/StarterAssetsInputs.cs.meta
similarity index 100%
rename from Assets/SZZ/Code/InputSystem/StarterAssetsInputs.cs.meta
rename to Assets/SZZ/Code/Scripts/Player/StarterAssetsInputs.cs.meta
diff --git a/Assets/SZZ/Level/Scenes/sandbox michal.unity b/Assets/SZZ/Level/Scenes/sandbox michal.unity
index cc60c4d8158fc7fcd6fdef6d8344bde86abfa50c..da917e4fb74771706c4b37406dc0e7dc4b46762d 100644
--- a/Assets/SZZ/Level/Scenes/sandbox michal.unity	
+++ b/Assets/SZZ/Level/Scenes/sandbox michal.unity	
@@ -1640,6 +1640,14 @@ PrefabInstance:
   m_Modification:
     m_TransformParent: {fileID: 0}
     m_Modifications:
+    - target: {fileID: 1618714456, guid: 5e581040a02cc9e4eb9f08baaeb185c3, type: 3}
+      propertyPath: maxDelay
+      value: 5
+      objectReference: {fileID: 0}
+    - target: {fileID: 1618714456, guid: 5e581040a02cc9e4eb9f08baaeb185c3, type: 3}
+      propertyPath: minDelay
+      value: 2
+      objectReference: {fileID: 0}
     - target: {fileID: 2632451753775102028, guid: 5e581040a02cc9e4eb9f08baaeb185c3,
         type: 3}
       propertyPath: m_Name
@@ -1719,81 +1727,11 @@ PrefabInstance:
   m_Modification:
     m_TransformParent: {fileID: 0}
     m_Modifications:
-    - target: {fileID: 4135013735270702856, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: m_LocalPosition.y
-      value: 1.46
-      objectReference: {fileID: 0}
-    - target: {fileID: 5393215578589016640, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: m_Radius
-      value: 0.3
-      objectReference: {fileID: 0}
-    - target: {fileID: 5393215578589016640, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: m_Enabled
-      value: 1
-      objectReference: {fileID: 0}
-    - target: {fileID: 5393215578589016641, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: m_LocalScale.x
-      value: 0.8
-      objectReference: {fileID: 0}
-    - target: {fileID: 5393215578589016641, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: m_LocalScale.y
-      value: 0.875
-      objectReference: {fileID: 0}
-    - target: {fileID: 5393215578589016641, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: m_LocalScale.z
-      value: 0.8
-      objectReference: {fileID: 0}
-    - target: {fileID: 5393215578589016641, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: m_LocalPosition.y
-      value: 0.875
-      objectReference: {fileID: 0}
-    - target: {fileID: 5393215578589016655, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: m_Enabled
-      value: 1
-      objectReference: {fileID: 0}
-    - target: {fileID: 8616685848737228371, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: Grounded
-      value: 1
-      objectReference: {fileID: 0}
-    - target: {fileID: 8616685848737228371, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: GroundedOffset
-      value: -0.27
-      objectReference: {fileID: 0}
-    - target: {fileID: 8616685848737228371, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: GroundedRadius
-      value: 0.3
-      objectReference: {fileID: 0}
     - target: {fileID: 8616685848737228372, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
         type: 3}
       propertyPath: m_Name
       value: PlayerCapsule
       objectReference: {fileID: 0}
-    - target: {fileID: 8616685848737228372, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: m_IsActive
-      value: 1
-      objectReference: {fileID: 0}
-    - target: {fileID: 8616685848737228382, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: m_Enabled
-      value: 1
-      objectReference: {fileID: 0}
-    - target: {fileID: 8616685848737228382, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
-        type: 3}
-      propertyPath: m_Center.y
-      value: 0.875
-      objectReference: {fileID: 0}
     - target: {fileID: 8997996947095583982, guid: c5efc39a8aaf6e64ea40e9ad573e9b47,
         type: 3}
       propertyPath: m_RootOrder
diff --git a/Assets/SZZ/Prefabs/PlayerCapsule.prefab b/Assets/SZZ/Prefabs/PlayerCapsule.prefab
index 59989c01a62697ef9afdb0a8b3037767b1f78eb2..6cddde3b5fc12266cf5f88559a5b7ce97463f6b5 100644
--- a/Assets/SZZ/Prefabs/PlayerCapsule.prefab
+++ b/Assets/SZZ/Prefabs/PlayerCapsule.prefab
@@ -24,7 +24,7 @@ Transform:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 4135013735270702863}
   m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
-  m_LocalPosition: {x: 0, y: 1.375, z: 0}
+  m_LocalPosition: {x: 0, y: 1.46, z: 0}
   m_LocalScale: {x: 1, y: 1, z: 1}
   m_ConstrainProportionsScale: 0
   m_Children: []
@@ -43,7 +43,7 @@ GameObject:
   - component: {fileID: 5393215578589016654}
   - component: {fileID: 5393215578589016655}
   - component: {fileID: 5393215578589016640}
-  m_Layer: 8
+  m_Layer: 7
   m_Name: Capsule
   m_TagString: Untagged
   m_Icon: {fileID: 0}
@@ -58,8 +58,8 @@ Transform:
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 5393215578589016642}
   m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
-  m_LocalPosition: {x: 0, y: 1, z: 0}
-  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_LocalPosition: {x: 0, y: 0.875, z: 0}
+  m_LocalScale: {x: 0.8, y: 0.875, z: 0.8}
   m_ConstrainProportionsScale: 0
   m_Children: []
   m_Father: {fileID: 8997996947095583982}
@@ -125,7 +125,7 @@ CapsuleCollider:
   m_Material: {fileID: 0}
   m_IsTrigger: 0
   m_Enabled: 1
-  m_Radius: 0.5
+  m_Radius: 0.3
   m_Height: 2
   m_Direction: 1
   m_Center: {x: 0, y: 0, z: 0}
@@ -143,7 +143,7 @@ GameObject:
   - component: {fileID: 1978471637655604388}
   - component: {fileID: 5420857361349278248}
   - component: {fileID: 8616685848737228376}
-  m_Layer: 8
+  m_Layer: 7
   m_Name: PlayerCapsule
   m_TagString: Player
   m_Icon: {fileID: 0}
@@ -184,7 +184,7 @@ CharacterController:
   m_StepOffset: 0.25
   m_SkinWidth: 0.02
   m_MinMoveDistance: 0
-  m_Center: {x: 0, y: 1, z: 0}
+  m_Center: {x: 0, y: 0.875, z: 0}
 --- !u!114 &8616685848737228371
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -206,14 +206,18 @@ MonoBehaviour:
   JumpTimeout: 0.1
   FallTimeout: 0.15
   Grounded: 1
-  GroundedOffset: -0.5
-  GroundedRadius: 0.5
+  GroundedOffset: -0.27
+  GroundedRadius: 0.3
   GroundLayers:
     serializedVersion: 2
     m_Bits: 513
   CinemachineCameraTarget: {fileID: 4135013735270702863}
   TopClamp: 89
   BottomClamp: -89
+  interactionDistance: 1.8
+  interactionLayerMask:
+    serializedVersion: 2
+    m_Bits: 823
 --- !u!114 &1978471637655604388
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -262,7 +266,7 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 62899f850307741f2a39c98a8b639597, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
-  m_Actions: {fileID: -944628639613478452, guid: 4419d82f33d36e848b3ed5af4c8da37e,
+  m_Actions: {fileID: -944628639613478452, guid: 7a465a0d9e0a168469c9e51761952157,
     type: 3}
   m_NotificationBehavior: 0
   m_UIInputModule: {fileID: 0}
@@ -345,7 +349,7 @@ MonoBehaviour:
     m_ActionId: e4ce1614-c754-48c1-9103-33130441661f
     m_ActionName: UI/New action
   m_NeverAutoSwitchControlSchemes: 0
-  m_DefaultControlScheme: 
+  m_DefaultControlScheme: KeyboardMouse
   m_DefaultActionMap: Player
   m_SplitScreenIndex: -1
   m_Camera: {fileID: 0}
diff --git a/Assets/SZZ/Prefabs/TextbookPage.prefab b/Assets/SZZ/Prefabs/TextbookPage.prefab
index 5830722f88f11675f16c12a434fee580c99872be..47063eee7f221d39b901eeaa9e29cba63c93e6a3 100644
--- a/Assets/SZZ/Prefabs/TextbookPage.prefab
+++ b/Assets/SZZ/Prefabs/TextbookPage.prefab
@@ -13,9 +13,10 @@ GameObject:
   - component: {fileID: 7057840455740453433}
   - component: {fileID: 1579733795640741572}
   - component: {fileID: 7354914873719257140}
+  - component: {fileID: -8631149948245798673}
   m_Layer: 0
   m_Name: TextbookPage
-  m_TagString: Untagged
+  m_TagString: Interactable
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0
   m_StaticEditorFlags: 0
@@ -114,3 +115,15 @@ BoxCollider:
   serializedVersion: 2
   m_Size: {x: 0.23679131, y: 0.01599068, z: 0.22663671}
   m_Center: {x: -0.0027155876, y: 0.009352072, z: 0.008096494}
+--- !u!114 &-8631149948245798673
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8859285185999786988}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 4f94be2b68e6a06429261f0f3b61e60c, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
diff --git a/Assets/SZZ/Code/InputSystem/StarterAssets.inputactions b/Assets/SZZ/Settings/InputMap.inputactions
similarity index 85%
rename from Assets/SZZ/Code/InputSystem/StarterAssets.inputactions
rename to Assets/SZZ/Settings/InputMap.inputactions
index 13307f4f9010ff8a7cad7c3e7914eb64a733db46..b67402309dea1d8a804b5884bcb6441e67995bb1 100644
--- a/Assets/SZZ/Code/InputSystem/StarterAssets.inputactions
+++ b/Assets/SZZ/Settings/InputMap.inputactions
@@ -11,7 +11,8 @@
                     "id": "6bc1aaf4-b110-4ff7-891e-5b9fe6f32c4d",
                     "expectedControlType": "Vector2",
                     "processors": "",
-                    "interactions": ""
+                    "interactions": "",
+                    "initialStateCheck": true
                 },
                 {
                     "name": "Look",
@@ -19,7 +20,8 @@
                     "id": "2690c379-f54d-45be-a724-414123833eb4",
                     "expectedControlType": "Vector2",
                     "processors": "",
-                    "interactions": ""
+                    "interactions": "",
+                    "initialStateCheck": true
                 },
                 {
                     "name": "Jump",
@@ -27,7 +29,8 @@
                     "id": "8c4abdf8-4099-493a-aa1a-129acec7c3df",
                     "expectedControlType": "Button",
                     "processors": "",
-                    "interactions": ""
+                    "interactions": "",
+                    "initialStateCheck": false
                 },
                 {
                     "name": "Sprint",
@@ -35,7 +38,17 @@
                     "id": "980e881e-182c-404c-8cbf-3d09fdb48fef",
                     "expectedControlType": "",
                     "processors": "",
-                    "interactions": ""
+                    "interactions": "",
+                    "initialStateCheck": false
+                },
+                {
+                    "name": "Interact",
+                    "type": "Button",
+                    "id": "ec3c88fb-c53d-4a68-b4bb-9e3fb6444ccb",
+                    "expectedControlType": "Button",
+                    "processors": "",
+                    "interactions": "",
+                    "initialStateCheck": false
                 }
             ],
             "bindings": [
@@ -214,6 +227,28 @@
                     "action": "Sprint",
                     "isComposite": false,
                     "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "89f768d1-8b2d-4892-8b73-5c91dce0d87c",
+                    "path": "<Keyboard>/e",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "KeyboardMouse",
+                    "action": "Interact",
+                    "isComposite": false,
+                    "isPartOfComposite": false
+                },
+                {
+                    "name": "",
+                    "id": "6459d5c1-eb7b-44e4-b408-676610ccba9e",
+                    "path": "<Gamepad>/buttonWest",
+                    "interactions": "",
+                    "processors": "",
+                    "groups": "Gamepad;Xbox Controller;PS4 Controller",
+                    "action": "Interact",
+                    "isComposite": false,
+                    "isPartOfComposite": false
                 }
             ]
         }
diff --git a/Assets/SZZ/Code/InputSystem/StarterAssets.inputactions.meta b/Assets/SZZ/Settings/InputMap.inputactions.meta
similarity index 89%
rename from Assets/SZZ/Code/InputSystem/StarterAssets.inputactions.meta
rename to Assets/SZZ/Settings/InputMap.inputactions.meta
index 7d4fb54c60a89441652c6b023beb386f331b39e8..70cdba237e01a1e19c248e71278ac987bff4db5a 100644
--- a/Assets/SZZ/Code/InputSystem/StarterAssets.inputactions.meta
+++ b/Assets/SZZ/Settings/InputMap.inputactions.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 4419d82f33d36e848b3ed5af4c8da37e
+guid: 7a465a0d9e0a168469c9e51761952157
 ScriptedImporter:
   internalIDToNameTable: []
   externalObjects: {}
diff --git a/Assets/SZZ/Code/InputSystem/StarterAssets.inputsettings.asset b/Assets/SZZ/Settings/InputSettings.asset
similarity index 94%
rename from Assets/SZZ/Code/InputSystem/StarterAssets.inputsettings.asset
rename to Assets/SZZ/Settings/InputSettings.asset
index 9a03d1836ebcba60cd1cecab47b0549ed12d7b82..d419baa0bd788dca7a02a89c422829dbfabd3fe4 100644
--- a/Assets/SZZ/Code/InputSystem/StarterAssets.inputsettings.asset
+++ b/Assets/SZZ/Settings/InputSettings.asset
@@ -10,7 +10,7 @@ MonoBehaviour:
   m_Enabled: 1
   m_EditorHideFlags: 0
   m_Script: {fileID: 11500000, guid: c46f07b5ed07e4e92aa78254188d3d10, type: 3}
-  m_Name: StarterAssets.inputsettings
+  m_Name: InputSettings
   m_EditorClassIdentifier: 
   m_SupportedDevices: []
   m_UpdateMode: 1
diff --git a/Assets/SZZ/Code/InputSystem/StarterAssets.inputsettings.asset.meta b/Assets/SZZ/Settings/InputSettings.asset.meta
similarity index 78%
rename from Assets/SZZ/Code/InputSystem/StarterAssets.inputsettings.asset.meta
rename to Assets/SZZ/Settings/InputSettings.asset.meta
index bb5f3ddb843e20cb6f9d1afaaee6f9cfa021d3f6..a135fe1c9b71f6bf3a4d9ce4e8c0b8aaae420baa 100644
--- a/Assets/SZZ/Code/InputSystem/StarterAssets.inputsettings.asset.meta
+++ b/Assets/SZZ/Settings/InputSettings.asset.meta
@@ -1,5 +1,5 @@
 fileFormatVersion: 2
-guid: 9e7be553448fa2546aea5752021cbcf7
+guid: 051036f21df3a0f408e5710865818cde
 NativeFormatImporter:
   externalObjects: {}
   mainObjectFileID: 0
diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset
index 4d78f657ae6610403d7277b80272ce090ea612d2..98059e5b7431e0f09de410e233f7f3594b3481ab 100644
--- a/ProjectSettings/TagManager.asset
+++ b/ProjectSettings/TagManager.asset
@@ -6,6 +6,7 @@ TagManager:
   tags:
   - CinemachineTarget
   - NPC
+  - Interactable
   layers:
   - Default
   - TransparentFX
@@ -14,7 +15,7 @@ TagManager:
   - Water
   - UI
   - 
-  - 
+  - Player
   - Character
   - Ground
   -