diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity
index 019031963f9ee306d8c38e5e8f4e21ba39354c5e..904f3548e867e82cd20eb32436c736b2bb674ab7 100644
--- a/Assets/Scenes/SampleScene.unity
+++ b/Assets/Scenes/SampleScene.unity
@@ -507,8 +507,8 @@ MonoBehaviour:
   m_EditorClassIdentifier: 
   knockbackResistance: 1
   baseSpeed: 0
-  maxHealth: 100
-  health: 100
+  maxHealth: 100000
+  health: 100000
   baseDamage: 0
 --- !u!1 &675919034
 GameObject:
@@ -1194,11 +1194,11 @@ PrefabInstance:
     m_Modifications:
     - target: {fileID: 2635269686106844091, guid: 1a7698227caac3d429dceb8aa5056502, type: 3}
       propertyPath: BaseDamage
-      value: 1
+      value: 10
       objectReference: {fileID: 0}
     - target: {fileID: 2635269686106844091, guid: 1a7698227caac3d429dceb8aa5056502, type: 3}
       propertyPath: KnockbackPower
-      value: 100
+      value: 200
       objectReference: {fileID: 0}
     - target: {fileID: 3608611397487402253, guid: 1a7698227caac3d429dceb8aa5056502, type: 3}
       propertyPath: m_Name
diff --git a/Assets/Scripts/Config/GameEnvironmentConfig.cs b/Assets/Scripts/Config/GameEnvironmentConfig.cs
index 4a55d8d11f5a81bf8d1b4b0edbec7c55907b5c36..32f35ec8c6c248d2b8d2dce2a85502529f3d2046 100644
--- a/Assets/Scripts/Config/GameEnvironmentConfig.cs
+++ b/Assets/Scripts/Config/GameEnvironmentConfig.cs
@@ -8,7 +8,8 @@ public static class GameEnvironmentConfig{
 
     // Layers
     public static readonly string LAYER_ENEMY = "Enemy";
+    public static readonly string LAYER_PLAYER_ATTACK = "PlayerAttack";
     public static readonly string LAYER_PLAYER = "Player";
     public static readonly string LAYER_ENEMY_ATTACK = "EnemyAttack";
-    public static readonly string LAYER_PLAYER_ATTACK = "PlayerAttack";
+    public static readonly string LAYER_COLLECTIBLE = "Collectible";
 }
\ No newline at end of file
diff --git a/Assets/Scripts/Core/Entities/Mobs/Dummy/Dummy.cs b/Assets/Scripts/Core/Entities/Mobs/Dummy/Dummy.cs
index 65c70ece91fd774959451cc8269d8cf2d04f18cb..bc52d4d90e43df551f4520726a3783401c6bfe2c 100644
--- a/Assets/Scripts/Core/Entities/Mobs/Dummy/Dummy.cs
+++ b/Assets/Scripts/Core/Entities/Mobs/Dummy/Dummy.cs
@@ -6,7 +6,7 @@ public class Dummy : EnemyEntity{
     public DummyStateController stateController;
 
     // Constructor
-    new void Start(){
+    new protected void Start(){
         base.Start();
         stateController = new DummyStateController(this);
         animationController = new DummyAnimationController(this);
diff --git a/Assets/Scripts/Core/Entities/Mobs/EnemyEntity.cs b/Assets/Scripts/Core/Entities/Mobs/EnemyEntity.cs
index 88a464b0e8f3f8ef3384b0434f3ff46017e53d4b..9cdbbde96029f90f5d2d37685fa99d6c11cd8061 100644
--- a/Assets/Scripts/Core/Entities/Mobs/EnemyEntity.cs
+++ b/Assets/Scripts/Core/Entities/Mobs/EnemyEntity.cs
@@ -1,6 +1,6 @@
 public abstract class EnemyEntity : Combatant {
     // Functions
-    new void Start(){
+    new protected void Start(){
         base.Start();
         Health *= GameConfig.DIFFICULTY_MODIFIERS[GameSaveData.instance.difficulty].EnemyHealthMultiplier;
         BaseDamage *= GameConfig.DIFFICULTY_MODIFIERS[GameSaveData.instance.difficulty].EnemyDamageMultiplier;
diff --git a/Assets/Scripts/Core/Game/Data/GameControls.cs b/Assets/Scripts/Core/Game/Data/GameControls.cs
index 3e86ad3f207b8856008231154b6df5ab12fd7114..acd8630a824884c25a60c875b602715e24c86a3e 100644
--- a/Assets/Scripts/Core/Game/Data/GameControls.cs
+++ b/Assets/Scripts/Core/Game/Data/GameControls.cs
@@ -1,13 +1,15 @@
 using UnityEngine;
 
 public class GameControls : MonoBehaviour {
-    // Attributes
+    // Static instance
     public static GameControls instance;
+
+    // Attributes
     public KeyCode backButton = KeyCode.Escape;
     public KeyCode attackButton = KeyCode.Z;
 
     // Constructor
-    private void Awake(){
+    protected void Awake(){
         instance = this;
         DontDestroyOnLoad(gameObject);
     }
diff --git a/Assets/Scripts/Core/Game/GameController.cs b/Assets/Scripts/Core/Game/GameController.cs
index 61234df29cee5116044a9cb6947082b424515382..065a15251c89ec64f32d58b159e70b499c0b9205 100644
--- a/Assets/Scripts/Core/Game/GameController.cs
+++ b/Assets/Scripts/Core/Game/GameController.cs
@@ -11,7 +11,7 @@ public class GameController : MonoBehaviour {
     public bool IsPaused => Time.timeScale == 0;
 
     // Constructor
-    private void Awake(){
+    protected void Awake(){
         if(instance == null) instance = this;
         mainCamera = new GameCameraController(GetComponentInChildren<Camera>());
         stateController = new GameStateController();
@@ -19,7 +19,7 @@ public class GameController : MonoBehaviour {
     }
 
     // Functions
-    void Update(){
+    protected void Update(){
          if(Input.GetKeyDown(GameControls.instance.backButton)){
             stateController.HandleEscape();
          }
diff --git a/Assets/Scripts/Core/Game/Managers/EntityManager.cs b/Assets/Scripts/Core/Game/Managers/EntityManager.cs
index 54aa7fefcac4fc105cd4fc1d77b6a9c6e9d1fb7b..aec186b7fe11e880f8a57c263e6b6fede9c31e4f 100644
--- a/Assets/Scripts/Core/Game/Managers/EntityManager.cs
+++ b/Assets/Scripts/Core/Game/Managers/EntityManager.cs
@@ -2,17 +2,12 @@ using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
-public class EntityManager : MonoBehaviour
-{
-    // Start is called before the first frame update
-    void Start()
-    {
-        
-    }
+public class EntityManager : MonoBehaviour{
+    // Static instance
+    public static EntityManager instance;
 
-    // Update is called once per frame
-    void Update()
-    {
-        
+    // Constructor
+    protected void Awake(){
+        instance = this;
     }
 }
diff --git a/Assets/Scripts/Core/Game/Managers/EnvironmentManager.cs b/Assets/Scripts/Core/Game/Managers/EnvironmentManager.cs
index 58bd398cc94df9faa00c94ebdc0f9f14dc60009f..1d7c8260dc5ab15db9539b27eface016eea7190b 100644
--- a/Assets/Scripts/Core/Game/Managers/EnvironmentManager.cs
+++ b/Assets/Scripts/Core/Game/Managers/EnvironmentManager.cs
@@ -2,17 +2,12 @@ using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
-public class EnvironmentManager : MonoBehaviour
-{
-    // Start is called before the first frame update
-    void Start()
-    {
-        
-    }
+public class EnvironmentManager : MonoBehaviour{
+    // Static instance
+    public static EnvironmentManager instance;
 
-    // Update is called once per frame
-    void Update()
-    {
-        
+    // Constructor
+    protected void Awake(){
+        instance = this;
     }
 }
diff --git a/Assets/Scripts/Core/Game/Managers/ObjectManager.cs b/Assets/Scripts/Core/Game/Managers/ObjectManager.cs
new file mode 100644
index 0000000000000000000000000000000000000000..38a3f90a5ad54d0fe6c25a5e88991fd285d595c4
--- /dev/null
+++ b/Assets/Scripts/Core/Game/Managers/ObjectManager.cs
@@ -0,0 +1,11 @@
+using UnityEngine;
+
+public class ObjectManager : MonoBehaviour{
+    // Static Instance
+    public static ObjectManager instance;
+
+    // Constructor
+    protected void Awake(){
+        instance = this;
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Core/Game/Managers/ObjectManager.cs.meta b/Assets/Scripts/Core/Game/Managers/ObjectManager.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..93153c09757d4fb8b678b8185e45dae128ed102e
--- /dev/null
+++ b/Assets/Scripts/Core/Game/Managers/ObjectManager.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: c051aae39aef0264ba144bc30cbe301e
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Core/Objects/Collectibles/Collectible.cs b/Assets/Scripts/Core/Objects/Collectibles/Collectible.cs
new file mode 100644
index 0000000000000000000000000000000000000000..6985de0e62995bf3823384cc659b2e903bce9281
--- /dev/null
+++ b/Assets/Scripts/Core/Objects/Collectibles/Collectible.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections;
+using UnityEngine;
+
+public abstract class Collectible : MonoBehaviour {
+    // Attributes
+    [SerializeField] float TimeToLive;
+    private event Action OnCollectEvent;
+    private event Action OnTimeoutEvent;
+
+    // Constructor
+    protected void Start(){
+        OnCollectEvent += OnCollect;
+        OnCollectEvent += OnCollectEnd;
+        OnTimeoutEvent += OnTimeout;
+        OnTimeoutEvent += OnTimeoutEnd;
+        StartCoroutine(Timeout());
+    }
+
+    // Functions
+    protected void OnTriggerEnter(Collider otherCollider){
+        OnCollectEvent?.Invoke();
+    }
+
+    protected virtual void OnCollectEnd(){
+        Destroy(gameObject);
+    }
+
+    protected IEnumerator Timeout(){
+        yield return new WaitForSeconds(TimeToLive);
+        OnTimeoutEvent?.Invoke();
+    }
+
+    protected void OnTimeoutEnd(){
+        Destroy(gameObject);
+    }
+
+    public void AddOnTimeout(Action onTimeout){
+        OnTimeoutEvent -= OnTimeoutEnd;
+        OnTimeoutEvent += onTimeout;
+        OnTimeoutEvent += OnTimeoutEnd;
+    }
+
+    public void RemoveOnTimeout(Action onTimeout){
+        OnTimeoutEvent -= OnTimeoutEnd;
+        OnTimeoutEvent -= onTimeout;
+        OnTimeoutEvent += OnTimeoutEnd;
+    }
+
+    // Abstract Functions
+    protected virtual void OnTimeout(){}
+    protected abstract void OnCollect();
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Core/Objects/Collectibles/Collectible.cs.meta b/Assets/Scripts/Core/Objects/Collectibles/Collectible.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..f55811d389c27368033b58ec64f0294666961a6b
--- /dev/null
+++ b/Assets/Scripts/Core/Objects/Collectibles/Collectible.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 4e18c2d365e00fd499ac5225fe4902d0
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Core/Objects/Collectibles/TestCollectible.meta b/Assets/Scripts/Core/Objects/Collectibles/TestCollectible.meta
new file mode 100644
index 0000000000000000000000000000000000000000..d22119aaa1bea3306e3b98a4beb9a88d474f4ecd
--- /dev/null
+++ b/Assets/Scripts/Core/Objects/Collectibles/TestCollectible.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b6fc1a2d2d2eedb4a9e6def6037766cc
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Core/Objects/Collectibles/TestCollectible/TestCollectible.cs b/Assets/Scripts/Core/Objects/Collectibles/TestCollectible/TestCollectible.cs
new file mode 100644
index 0000000000000000000000000000000000000000..4fa1dcf94a3835cc3f565cf334d11e251f088c83
--- /dev/null
+++ b/Assets/Scripts/Core/Objects/Collectibles/TestCollectible/TestCollectible.cs
@@ -0,0 +1,11 @@
+using UnityEngine;
+
+public class TestCollectible : Collectible{
+    protected override void OnCollect(){
+        Debug.Log("Test collectible collected");
+    }
+
+    protected override void OnTimeout(){
+        Debug.Log("Test collectible timeout");
+    }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Core/Objects/Collectibles/TestCollectible/TestCollectible.cs.meta b/Assets/Scripts/Core/Objects/Collectibles/TestCollectible/TestCollectible.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..cd151e927259edc71746c2ff38de015b05648475
--- /dev/null
+++ b/Assets/Scripts/Core/Objects/Collectibles/TestCollectible/TestCollectible.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6a318ebd05eb15c4fabf9cbe7355eb41
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Core/Objects/Weapons/TestWeapon.meta b/Assets/Scripts/Core/Objects/Weapons/TestWeapon.meta
new file mode 100644
index 0000000000000000000000000000000000000000..9fcdc3dd5fe271be32bd970a17b9efd643a6f90c
--- /dev/null
+++ b/Assets/Scripts/Core/Objects/Weapons/TestWeapon.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 78564463204f1334eb36e66455d73aa3
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/Core/Objects/Weapons/TestWeapon.cs b/Assets/Scripts/Core/Objects/Weapons/TestWeapon/TestWeapon.cs
similarity index 100%
rename from Assets/Scripts/Core/Objects/Weapons/TestWeapon.cs
rename to Assets/Scripts/Core/Objects/Weapons/TestWeapon/TestWeapon.cs
diff --git a/Assets/Scripts/Core/Objects/Weapons/TestWeapon.cs.meta b/Assets/Scripts/Core/Objects/Weapons/TestWeapon/TestWeapon.cs.meta
similarity index 100%
rename from Assets/Scripts/Core/Objects/Weapons/TestWeapon.cs.meta
rename to Assets/Scripts/Core/Objects/Weapons/TestWeapon/TestWeapon.cs.meta
diff --git a/Assets/Scripts/Library/BaseClasses/WeaponObject.cs b/Assets/Scripts/Core/Objects/Weapons/WeaponObject.cs
similarity index 95%
rename from Assets/Scripts/Library/BaseClasses/WeaponObject.cs
rename to Assets/Scripts/Core/Objects/Weapons/WeaponObject.cs
index 6d4c55d95780ce5ad5de1497536f710faca4f3ae..26c4ecc20e3deb69e95558e0ad3f17900c981171 100644
--- a/Assets/Scripts/Library/BaseClasses/WeaponObject.cs
+++ b/Assets/Scripts/Core/Objects/Weapons/WeaponObject.cs
@@ -9,7 +9,7 @@ public abstract class WeaponObject : MonoBehaviour {
     [SerializeField] protected float KnockbackPower;
 
     // Constructor
-    void Start(){
+    protected void Start(){
         bearer = GetComponentInParent<IArmed>();
         if(bearer is Player) bearerType = AttackObjectType.PLAYER;
         else if(bearer is EnemyEntity) bearerType = AttackObjectType.ENEMY;
diff --git a/Assets/Scripts/Library/BaseClasses/WeaponObject.cs.meta b/Assets/Scripts/Core/Objects/Weapons/WeaponObject.cs.meta
similarity index 100%
rename from Assets/Scripts/Library/BaseClasses/WeaponObject.cs.meta
rename to Assets/Scripts/Core/Objects/Weapons/WeaponObject.cs.meta
diff --git a/Assets/Scripts/Library/BaseClasses/AttackHitbox.cs b/Assets/Scripts/Library/BaseClasses/AttackHitbox.cs
index fc16be161f55ffb3525675697eb4411de5df7396..a94558608d089fe3e7d595fa3f25096eef3359b9 100644
--- a/Assets/Scripts/Library/BaseClasses/AttackHitbox.cs
+++ b/Assets/Scripts/Library/BaseClasses/AttackHitbox.cs
@@ -3,7 +3,7 @@ using UnityEngine;
 
 public class AttackHitbox : AttackObject{
     // Functions
-    void OnTriggerStay(Collider otherCollider){
+    protected void OnTriggerStay(Collider otherCollider){
         Hit(otherCollider);
     }
 }
diff --git a/Assets/Scripts/Library/BaseClasses/EntityObject/AttackObject.cs b/Assets/Scripts/Library/BaseClasses/EntityObject/AttackObject.cs
index 07180f9f170bc69fc3fb3801a14e9a3e543c3c41..41c5ea2c299ef8a6199f5a8d253de8a4e834ec2e 100644
--- a/Assets/Scripts/Library/BaseClasses/EntityObject/AttackObject.cs
+++ b/Assets/Scripts/Library/BaseClasses/EntityObject/AttackObject.cs
@@ -21,6 +21,7 @@ public class AttackObject : MonoBehaviour, IAttack{
         var knockbackModifier = (-1) * knockbackPower / rigidObject.KnockbackResistance;
         Vector3 knockbackVector = MathUtils.GetDirectionVector(KnockbackOrigin, rigidObject.Position) * knockbackModifier;
         rigidObject.Rigidbody.AddForce(knockbackVector, ForceMode.Impulse);
+        Debug.Log(knockbackVector);
     }
 
     protected void Hit(Collider otherCollider){
diff --git a/Assets/Scripts/Library/CameraBehaviour/CameraFollowObject.cs b/Assets/Scripts/Library/CameraBehaviour/CameraFollowObject.cs
index 3ee122253123b97bdb429202dd8c1fc7207c1be6..b489f0e11158662e022429929a244effcb909937 100644
--- a/Assets/Scripts/Library/CameraBehaviour/CameraFollowObject.cs
+++ b/Assets/Scripts/Library/CameraBehaviour/CameraFollowObject.cs
@@ -2,13 +2,13 @@ using UnityEngine;
 
 public class CameraFollowObject : CameraBehaviour {
     // Attributes
-    [SerializeField] public Transform target;
-    [SerializeField] public float followingTime = CameraConfig.DEFAULT_FOLLOWING_SPEED;
-    [SerializeField] public Vector3 offset = CameraConfig.DEFAULT_CAMERA_OFFSET;
+    public Transform target;
+    public float followingTime = CameraConfig.DEFAULT_FOLLOWING_SPEED;
+    public Vector3 offset = CameraConfig.DEFAULT_CAMERA_OFFSET;
     private Vector3 velocity = Vector3.zero;
     
     // Functions
-    void FixedUpdate(){
+    protected void FixedUpdate(){
         Vector3 targetPosition = target.position + offset;
         Vector3 newPosition = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, followingTime);
         transform.position = newPosition;
diff --git a/Assets/Scripts/Library/Util/ObjectFactory.cs b/Assets/Scripts/Library/Util/ObjectFactory.cs
index 33c8c84f976719da3ae72458d816c7554310401c..e0d8a44ceec52c4822e6780aec7b635d6eabb57c 100644
--- a/Assets/Scripts/Library/Util/ObjectFactory.cs
+++ b/Assets/Scripts/Library/Util/ObjectFactory.cs
@@ -73,11 +73,24 @@ public static class ObjectFactory{
         return prefabObject;
     }
 
+    public static GameObject CreateCollectibleObject(
+        string prefabPath,
+        Transform parent = null,
+        Vector3? position = null,
+        Vector3? scale = null,
+        Quaternion? rotation = null,
+        int renderingOrder = 0,
+        string objectName = "Unnamed Object"
+    ){
+        GameObject prefabObject = CreateObject(prefabPath, parent == null? ObjectManager.instance.transform : parent, position, scale, rotation, renderingOrder, objectName);
+        if(!prefabObject.TryGetComponent<Collectible>(out var collectibleObject)) Debug.LogError("Loaded prefab is not a Collectible: " + prefabPath);
+        prefabObject.layer = LayerMask.NameToLayer(GameEnvironmentConfig.LAYER_COLLECTIBLE);
+
+        return prefabObject;
+    }
+
     public static void Destroy(GameObject gameObject, float delay = 0){
-        if(gameObject == null){
-            Debug.LogError("Tried to destroy a null gameObject");
-            return;
-        }
+        if(gameObject == null) return;
         GameController.instance.StartCoroutine(DestroyWithDelay(gameObject, delay));
     }