diff --git a/Assets/Resources/PhysicsMaterial.meta b/Assets/Resources/PhysicsMaterial.meta
new file mode 100644
index 0000000000000000000000000000000000000000..05fb84991791b49c7fed2656110a6672be38a499
--- /dev/null
+++ b/Assets/Resources/PhysicsMaterial.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 7c6f0124e65782647a0319ce5faa417a
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Resources/PhysicsMaterial/Slippery.physicMaterial b/Assets/Resources/PhysicsMaterial/Slippery.physicMaterial
new file mode 100644
index 0000000000000000000000000000000000000000..e147072cc5f85dfc03fbd26c45f410d281097c44
--- /dev/null
+++ b/Assets/Resources/PhysicsMaterial/Slippery.physicMaterial
@@ -0,0 +1,14 @@
+%YAML 1.1
+%TAG !u! tag:unity3d.com,2011:
+--- !u!134 &13400000
+PhysicMaterial:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_Name: Slippery
+  dynamicFriction: 0.6
+  staticFriction: 0.6
+  bounciness: 0
+  frictionCombine: 0
+  bounceCombine: 0
diff --git a/Assets/Resources/PhysicsMaterial/Slippery.physicMaterial.meta b/Assets/Resources/PhysicsMaterial/Slippery.physicMaterial.meta
new file mode 100644
index 0000000000000000000000000000000000000000..a512998d646a6ae22f76100c26ddbefa5275f0dc
--- /dev/null
+++ b/Assets/Resources/PhysicsMaterial/Slippery.physicMaterial.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 6b36fb2e3a8a80643988a623d515cbcc
+NativeFormatImporter:
+  externalObjects: {}
+  mainObjectFileID: 13400000
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Config/GameEnvironmentConfig.cs b/Assets/Scripts/Config/GameEnvironmentConfig.cs
index 8cbed051d82d4441bdc8887bcd34bad97548c7ff..f8f0217836a480d12a1f61b044e36a141d1f2a49 100644
--- a/Assets/Scripts/Config/GameEnvironmentConfig.cs
+++ b/Assets/Scripts/Config/GameEnvironmentConfig.cs
@@ -8,6 +8,7 @@ public static class GameEnvironmentConfig{
     public const string TAG_GROUND = "Ground";
 
     // Layers
+    public const string LAYER_DEFAULT = "Default";
     public const string LAYER_PLAYER = "Player";
     public const string LAYER_ENEMY = "Enemy";
     public const string LAYER_PLAYER_ATTACK = "PlayerAttack";
diff --git a/Assets/Scripts/Core/Player/PlayerInputController.cs b/Assets/Scripts/Core/Player/PlayerInputController.cs
index 0af72b06a3aadb53950e6b027c84e08cf6afe58e..ec2edea6b19715621eaaa4a38926f2b009dcd4b5 100644
--- a/Assets/Scripts/Core/Player/PlayerInputController.cs
+++ b/Assets/Scripts/Core/Player/PlayerInputController.cs
@@ -7,6 +7,10 @@ public class PlayerInputController
     private readonly Player player;
     public float movementInputX;
     public float movementInputZ;
+    public bool movementInputJump;
+
+    // Events
+    public event Action OnJumpEvent;
     
     // Constructor
     public PlayerInputController(Player player)
@@ -20,6 +24,11 @@ public class PlayerInputController
         movementInputX = Input.GetAxisRaw("Horizontal");
         movementInputZ = Input.GetAxisRaw("Vertical");
 
+        if(Input.GetButtonDown("Jump") && player.Grounded)
+        {
+            OnJumpEvent?.Invoke();
+        }
+
         if(Input.GetKeyDown(GameInput.instance.attackButton))
         {
             Debug.Log("Player is Attacking");
@@ -47,7 +56,7 @@ public class PlayerInputController
             {
                 return;
             }
-            
+
             IInteractable interactable = player.stateController.currentInteractables[player.stateController.currentInteractables.Count - 1];
             interactable.Interact();
         }
diff --git a/Assets/Scripts/Core/Player/PlayerMovementController.cs b/Assets/Scripts/Core/Player/PlayerMovementController.cs
index 3b4bcbd8c2877e9813db4c2aa7dae0cb36376f27..26543bf28b5b678436d5364469b1bb55fbd6a639 100644
--- a/Assets/Scripts/Core/Player/PlayerMovementController.cs
+++ b/Assets/Scripts/Core/Player/PlayerMovementController.cs
@@ -12,6 +12,7 @@ public class PlayerMovementController
     public PlayerMovementController(Player player)
     {
         this.player = player;
+        player.inputController.OnJumpEvent += HandleJump;
         axisX = new(GameController.instance.mainCamera.Orientation.right.x, 0, GameController.instance.mainCamera.Orientation.right.z);
         axisZ = new(GameController.instance.mainCamera.Orientation.forward.x, 0, GameController.instance.mainCamera.Orientation.forward.z);
     }
@@ -50,4 +51,10 @@ public class PlayerMovementController
             HandleRotation(movementVector);
         } 
     }
+
+    public void HandleJump()
+    {
+        Vector3 force = new(0, player.JumpForce, 0);
+        player.Rigidbody.AddForce(force, ForceMode.Impulse);
+    }
 }
diff --git a/Assets/Scripts/Core/Player/PlayerStateController.cs b/Assets/Scripts/Core/Player/PlayerStateController.cs
index d964474eaa4c3ec7b0dd33f1b265f1a9a3494958..5815b530326282c47d2006c691a5ebc21faaa3d7 100644
--- a/Assets/Scripts/Core/Player/PlayerStateController.cs
+++ b/Assets/Scripts/Core/Player/PlayerStateController.cs
@@ -22,12 +22,28 @@ public class PlayerStateController : DamageableEntityStateController
     {
         return (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0) && Input.GetKey(KeyCode.LeftShift);
     }
+    private bool DetectJumping()
+    {
+        return !player.Grounded && player.Rigidbody.velocity.y > 0;
+    }
+    private bool DetectFalling()
+    {
+        return !player.Grounded && player.Rigidbody.velocity.y < 0;
+    }
 
     public override int UpdateState()
     {
         int initialState = state;
 
-        if(DetectSprinting())
+        if(DetectJumping())
+        {
+            state = PlayerState.JUMPING;
+        }
+        else if(DetectFalling())
+        {
+            state = PlayerState.FALLING;
+        }
+        else if(DetectSprinting())
         {
             state = PlayerState.SPRINTING;
         }
@@ -44,7 +60,7 @@ public class PlayerStateController : DamageableEntityStateController
         {
             InvokeOnStateChanged();
         }
-        
+
         return state;
     }
 }
diff --git a/Assets/Scripts/Library/BaseClasses/EntityObject/WorldEntity.cs b/Assets/Scripts/Library/BaseClasses/EntityObject/WorldEntity.cs
index c7796b95fbd87773773ea5c52ada8210fea0e7f7..c0ed5fb772d9a7cec802c8561811f12a2feefb9d 100644
--- a/Assets/Scripts/Library/BaseClasses/EntityObject/WorldEntity.cs
+++ b/Assets/Scripts/Library/BaseClasses/EntityObject/WorldEntity.cs
@@ -5,11 +5,16 @@ public class WorldEntity : WorldObject, IRigid
     // Attributes
     [SerializeField] private float knockbackResistance;
     [SerializeField] private float baseSpeed;
-    private new Rigidbody rigidbody;
-    
+    [SerializeField] private float jumpForce;
+    protected Vector3 groundDetectionSize; 
+    [SerializeField] protected LayerMask groundLayers;
+    protected new Rigidbody rigidbody;
+    private bool grounded = false;
+
     // Set-Getters
     public Rigidbody Rigidbody => rigidbody;
     public Vector3 Position => transform.position;
+    public bool Grounded => grounded;
     public float KnockbackResistance
     {
         get => knockbackResistance <= 0? 1 : knockbackResistance;
@@ -20,16 +25,22 @@ public class WorldEntity : WorldObject, IRigid
         get => baseSpeed; 
         set => baseSpeed = value < 0? 0 : value; 
     }
+    public float JumpForce 
+    { 
+        get => jumpForce; 
+        set => jumpForce = value < 0? 0 : value; 
+    }
 
     // Constructor
-
     protected void Start()
     {
-        rigidbody = GetComponent<Rigidbody>();        
+        rigidbody = GetComponent<Rigidbody>();
+        groundDetectionSize = new Vector3(0.05f, 0.05f, 0.05f);      
         if(rigidbody == null)
         {
             Debug.LogWarning("Rigid entity " + name + " does not have a rigidbody"); 
         }
+        groundLayers = LayerMask.GetMask(GameEnvironmentConfig.LAYER_DEFAULT);
     }
 
     // Functions
@@ -61,5 +72,9 @@ public class WorldEntity : WorldObject, IRigid
         {
             return;
         }
+
+        Vector3 center = transform.position;
+        Collider[] groundOverlaps = Physics.OverlapBox(center, groundDetectionSize, Quaternion.identity, groundLayers);
+        grounded = groundOverlaps.Length != 0;
     }
 }
\ No newline at end of file
diff --git a/Assets/Scripts/Library/Enum/Inheritable/DefaultEntityState.cs b/Assets/Scripts/Library/Enum/Inheritable/DefaultEntityState.cs
index 5babf367963f75d9f6add5775bc38cdbf95de94e..5c1e807edd20d4f63f6ed6ad42c153b22b00f338 100644
--- a/Assets/Scripts/Library/Enum/Inheritable/DefaultEntityState.cs
+++ b/Assets/Scripts/Library/Enum/Inheritable/DefaultEntityState.cs
@@ -5,4 +5,6 @@ public class DefaultEntityState
     public const int WALKING = 2;
     public const int SPRINTING = 4;
     public const int ATTACKING = 8;
+    public const int JUMPING = 16;
+    public const int FALLING = 32;
 }
diff --git a/Assets/Scripts/Library/Interfaces/IRigid.cs b/Assets/Scripts/Library/Interfaces/IRigid.cs
index 8cea356917c2f88bfb3ce7ee17360e3626552284..2456ef3507ef1e618f705f780dfe98f3efb71b2d 100644
--- a/Assets/Scripts/Library/Interfaces/IRigid.cs
+++ b/Assets/Scripts/Library/Interfaces/IRigid.cs
@@ -7,6 +7,8 @@ public interface IRigid
     // Set-Getters
     public Rigidbody Rigidbody {get;}
     public Vector3 Position {get;}
+    public bool Grounded {get;}
     public float BaseSpeed {get; set;}
+    public float JumpForce {get; set;}
     public float KnockbackResistance {get; set;}
 }