diff --git a/Assets/Data/Weapon Data/TestWeapon/TestWeaponData.asset b/Assets/Data/Weapon Data/TestWeapon/TestWeaponData.asset
index 52188fd9629799777c9809f90caaf34fbfcdd4c9..04df8115d034bfee63908251ad18cf482b5d504d 100644
--- a/Assets/Data/Weapon Data/TestWeapon/TestWeaponData.asset	
+++ b/Assets/Data/Weapon Data/TestWeapon/TestWeaponData.asset	
@@ -14,6 +14,6 @@ MonoBehaviour:
   m_EditorClassIdentifier: 
   baseDamage: 10
   knockbackPower: 10
-  attackInterval: 0.5
+  attackInterval: 0.2
   alternateAttackInterval: 1
   model: {fileID: 6146631199650576833, guid: 50599534a77c7dd46b591a71fbb5feba, type: 3}
diff --git a/Assets/Data/Weapon Data/TestWeapon/TestWeaponProjectileData.asset b/Assets/Data/Weapon Data/TestWeapon/TestWeaponProjectileData.asset
index e67302fde8d8f18699e610346af56f798ee04ac7..495ed41a44a8da6b1f603297baf4a0663ff6819b 100644
--- a/Assets/Data/Weapon Data/TestWeapon/TestWeaponProjectileData.asset	
+++ b/Assets/Data/Weapon Data/TestWeapon/TestWeaponProjectileData.asset	
@@ -12,7 +12,7 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 9eb73b2d49aa0a5439d5c9a15a3f49e0, type: 3}
   m_Name: TestWeaponProjectileData
   m_EditorClassIdentifier: 
-  speed: 0
-  travelDistance: 0
+  speed: 50
+  travelDistance: 10
   through: 0
-  model: {fileID: 0}
+  model: {fileID: 5003074370431539976, guid: 8c93d213036531f47a377ee7fd1e7877, type: 3}
diff --git a/Assets/Resources/Models/Weapons/TestWeapon/TestWeaponModel.prefab b/Assets/Resources/Models/Weapons/TestWeapon/TestWeaponModel.prefab
index 1f98c326b97d61da304513647b45beb2ddda7584..5a192af5ccd1ef525992a521998ff1c01e1099d4 100644
--- a/Assets/Resources/Models/Weapons/TestWeapon/TestWeaponModel.prefab
+++ b/Assets/Resources/Models/Weapons/TestWeapon/TestWeaponModel.prefab
@@ -12,7 +12,7 @@ GameObject:
   - component: {fileID: 2791526420071666714}
   - component: {fileID: 1664417149787680797}
   - component: {fileID: 444274800546035912}
-  m_Layer: 8
+  m_Layer: 0
   m_Name: TestWeaponModel
   m_TagString: Untagged
   m_Icon: {fileID: 0}
diff --git a/Assets/Resources/PhysicsMaterial/Slippery.physicMaterial b/Assets/Resources/PhysicsMaterial/Slippery.physicMaterial
index e147072cc5f85dfc03fbd26c45f410d281097c44..2b7c350f0fadec44e75225a0519bd7f690f4f993 100644
--- a/Assets/Resources/PhysicsMaterial/Slippery.physicMaterial
+++ b/Assets/Resources/PhysicsMaterial/Slippery.physicMaterial
@@ -7,8 +7,8 @@ PhysicMaterial:
   m_PrefabInstance: {fileID: 0}
   m_PrefabAsset: {fileID: 0}
   m_Name: Slippery
-  dynamicFriction: 0.6
-  staticFriction: 0.6
+  dynamicFriction: 0
+  staticFriction: 0
   bounciness: 0
-  frictionCombine: 0
-  bounceCombine: 0
+  frictionCombine: 1
+  bounceCombine: 1
diff --git a/Assets/Resources/Prefabs/Weapons/TestWeapon/TestWeapon.prefab b/Assets/Resources/Prefabs/Weapons/TestWeapon/TestWeapon.prefab
index 6e2b78e1138c48858a0309d6c40de5bb26463f5f..c7d6d5738fea4aa280201872517b59c05a56f409 100644
--- a/Assets/Resources/Prefabs/Weapons/TestWeapon/TestWeapon.prefab
+++ b/Assets/Resources/Prefabs/Weapons/TestWeapon/TestWeapon.prefab
@@ -10,7 +10,7 @@ GameObject:
   m_Component:
   - component: {fileID: 1050311400148833009}
   - component: {fileID: 5029868015402955001}
-  m_Layer: 8
+  m_Layer: 0
   m_Name: TestWeapon
   m_TagString: Untagged
   m_Icon: {fileID: 0}
@@ -45,6 +45,7 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 68705b8ed948aae4d98ef6e87b6f6961, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
+  prefabPath: Prefabs/Weapons/TestWeapon/TestWeapon
   data: {fileID: 11400000, guid: 875c881f7a9ed2347a9d28ca2c18c4b5, type: 2}
   canAttack: 0
   fireRange: 10
diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/SampleScene.unity
index d4423856b9e82c063c2731ea7badbab848e07b77..fc666bc5acbf4e97d0594bc50ccb7cb4f749378e 100644
--- a/Assets/Scenes/SampleScene.unity
+++ b/Assets/Scenes/SampleScene.unity
@@ -241,12 +241,18 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: bbd12f0cc12b22743998413b3f14b197, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
-  Id: 
+  id: 
   knockbackResistance: 1
   baseSpeed: 10
+  jumpForce: 5
+  groundLayers:
+    serializedVersion: 2
+    m_Bits: 1
   maxHealth: 100
   health: 100
+  damagedDelay: 1
   baseDamage: 10
+  weaponList: []
 --- !u!1 &239523005
 GameObject:
   m_ObjectHideFlags: 0
@@ -276,7 +282,7 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 354f6ba1c1428a04da1f256d1da9f51e, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
-  player: {fileID: 0}
+  player: {fileID: 117855958}
   data: {fileID: 0}
 --- !u!4 &239523007
 Transform:
@@ -287,7 +293,7 @@ Transform:
   m_GameObject: {fileID: 239523005}
   serializedVersion: 2
   m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
-  m_LocalPosition: {x: -0.1930373, y: 0.8700184, z: -0.31220782}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
   m_LocalScale: {x: 1, y: 1, z: 1}
   m_ConstrainProportionsScale: 0
   m_Children:
@@ -435,7 +441,7 @@ BoxCollider:
   m_PrefabInstance: {fileID: 0}
   m_PrefabAsset: {fileID: 0}
   m_GameObject: {fileID: 576314395}
-  m_Material: {fileID: 0}
+  m_Material: {fileID: 13400000, guid: 6b36fb2e3a8a80643988a623d515cbcc, type: 2}
   m_IncludeLayers:
     serializedVersion: 2
     m_Bits: 0
@@ -1175,6 +1181,14 @@ PrefabInstance:
       propertyPath: m_LocalEulerAnglesHint.z
       value: 0
       objectReference: {fileID: 0}
+    - target: {fileID: 5029868015402955001, guid: 1a7698227caac3d429dceb8aa5056502, type: 3}
+      propertyPath: model
+      value: 
+      objectReference: {fileID: 0}
+    - target: {fileID: 5029868015402955001, guid: 1a7698227caac3d429dceb8aa5056502, type: 3}
+      propertyPath: weaponData
+      value: 
+      objectReference: {fileID: 11400000, guid: 875c881f7a9ed2347a9d28ca2c18c4b5, type: 2}
     - target: {fileID: 5240801910879785525, guid: 1a7698227caac3d429dceb8aa5056502, type: 3}
       propertyPath: m_Name
       value: TestWeapon
@@ -1315,6 +1329,10 @@ PrefabInstance:
     serializedVersion: 3
     m_TransformParent: {fileID: 1098815287}
     m_Modifications:
+    - target: {fileID: 4603107572195619152, guid: c98b222ded23bb24690e674886e5741a, type: 3}
+      propertyPath: m_Material
+      value: 
+      objectReference: {fileID: 13400000, guid: 6b36fb2e3a8a80643988a623d515cbcc, type: 2}
     - target: {fileID: 6541102688641435260, guid: c98b222ded23bb24690e674886e5741a, type: 3}
       propertyPath: m_Name
       value: TestInteractable
@@ -1359,6 +1377,10 @@ PrefabInstance:
       propertyPath: m_LocalEulerAnglesHint.z
       value: 0
       objectReference: {fileID: 0}
+    - target: {fileID: 8869483112752652203, guid: c98b222ded23bb24690e674886e5741a, type: 3}
+      propertyPath: m_Material
+      value: 
+      objectReference: {fileID: 13400000, guid: 6b36fb2e3a8a80643988a623d515cbcc, type: 2}
     m_RemovedComponents: []
     m_RemovedGameObjects: []
     m_AddedGameObjects: []
diff --git a/Assets/Scripts/Config/GameEnvironmentConfig.cs b/Assets/Scripts/Config/EnvironmentConfig.cs
similarity index 82%
rename from Assets/Scripts/Config/GameEnvironmentConfig.cs
rename to Assets/Scripts/Config/EnvironmentConfig.cs
index f8f0217836a480d12a1f61b044e36a141d1f2a49..2f093d4cd548a010ed5586861756202671a73aca 100644
--- a/Assets/Scripts/Config/GameEnvironmentConfig.cs
+++ b/Assets/Scripts/Config/EnvironmentConfig.cs
@@ -1,5 +1,5 @@
 // Configs should only contain constants and static readonly classes
-public static class GameEnvironmentConfig{
+public static class EnvironmentConfig{
     // Tags
     public const string TAG_UNTAGGED = "Untagged";
     public const string TAG_PLAYER = "Player";
@@ -15,4 +15,8 @@ public static class GameEnvironmentConfig{
     public const string LAYER_ENEMY_ATTACK = "EnemyAttack";
     public const string LAYER_ENVIRONMENT_ATTACK = "EnvironmentAttack";
     public const string LAYER_COLLECTIBLE = "Collectible";
+
+    // Object Components
+    public const string OBJECT_WEAPON = "Weapon";
+    public const string OBJECT_MODEL = "Model";
 }
\ No newline at end of file
diff --git a/Assets/Scripts/Config/GameEnvironmentConfig.cs.meta b/Assets/Scripts/Config/EnvironmentConfig.cs.meta
similarity index 100%
rename from Assets/Scripts/Config/GameEnvironmentConfig.cs.meta
rename to Assets/Scripts/Config/EnvironmentConfig.cs.meta
diff --git a/Assets/Scripts/Core/Entities/Mobs/EnemyEntity.cs b/Assets/Scripts/Core/Entities/Mobs/EnemyEntity.cs
index 6008c0aa8275ac0448fac66011fae23d74e2b403..9ffb4e1555035ddbb8120c4e32441c92966e7170 100644
--- a/Assets/Scripts/Core/Entities/Mobs/EnemyEntity.cs
+++ b/Assets/Scripts/Core/Entities/Mobs/EnemyEntity.cs
@@ -1,11 +1,15 @@
 public abstract class EnemyEntity : CombatantEntity 
 {
+    // Set-Getters
+    public new string AttackLayerCode => EnvironmentConfig.LAYER_ENEMY_ATTACK;
+    public new float AttackMultiplier => GameConfig.DIFFICULTY_MODIFIERS[GameSaveData.instance.difficulty].EnemyDamageMultiplier;
+
     // Functions
     new protected void Start()
     {
         base.Start();
         Health *= GameConfig.DIFFICULTY_MODIFIERS[GameSaveData.instance.difficulty].EnemyHealthMultiplier;
         BaseDamage *= GameConfig.DIFFICULTY_MODIFIERS[GameSaveData.instance.difficulty].EnemyDamageMultiplier;
-        tag = GameEnvironmentConfig.TAG_ENEMY;
+        tag = EnvironmentConfig.TAG_ENEMY;
     }
 }
diff --git a/Assets/Scripts/Core/Objects/Weapons/TestWeapon/TestWeapon.cs b/Assets/Scripts/Core/Objects/Weapons/TestWeapon/TestWeapon.cs
index 4720285b297a57ae3c997496cbb20ef6fa6eacf1..25364a3d8eb23e5586e4059437b1bb4a257ff74f 100644
--- a/Assets/Scripts/Core/Objects/Weapons/TestWeapon/TestWeapon.cs
+++ b/Assets/Scripts/Core/Objects/Weapons/TestWeapon/TestWeapon.cs
@@ -3,13 +3,14 @@ using UnityEngine;
 public class TestWeapon : WeaponObject
 {
     // Constants
+    private static readonly string weaponPrefab = "Prefabs/Weapons/TestWeapon/TestWeapon";
     private static readonly string hitboxPrefab = "Prefabs/Weapons/TestWeapon/WeaponHitbox";
     private static readonly string projectilePrefab = "Prefabs/Weapons/TestWeapon/TestProjectile";
     
     // Attribute
-    [SerializeField] private float fireRange = 100;
-    [SerializeField] private float projectileSpeed = 100; 
-    private TestWeaponAnimationController animationController;
+    public float fireRange = 100;
+    public float projectileSpeed = 100; 
+    public TestWeaponAnimationController animationController;
 
     // Constructor
     protected new void Start()
@@ -25,7 +26,8 @@ public class TestWeapon : WeaponObject
             prefabPath: projectilePrefab,
             damage: MathUtils.CalculateDamage(bearer.BaseDamage, data.baseDamage),
             knockbackPower: data.knockbackPower / 4,
-            type: bearerType,
+            attackLayerCode: bearer.AttackLayerCode,
+            damageModifier: bearer.AttackMultiplier,
             position: transform.position,
             rotation: bearer.Orientation.rotation,
             knockbackOrigin: transform.position - (bearer.Orientation.forward * projectileSpeed),
@@ -47,7 +49,8 @@ public class TestWeapon : WeaponObject
             prefabPath: hitboxPrefab,
             damage: MathUtils.CalculateDamage(bearer.BaseDamage, data.baseDamage),
             knockbackPower: data.knockbackPower,
-            type: bearerType,
+            attackLayerCode: bearer.AttackLayerCode,
+            damageModifier: bearer.AttackMultiplier,
             knockbackOrigin: transform.position,
             parent: animationController.model,
             objectName: "TestWeapon Hitbox"
diff --git a/Assets/Scripts/Core/Objects/Weapons/WeaponObject.cs b/Assets/Scripts/Core/Objects/Weapons/WeaponObject.cs
index b6294063391de1cccb932f2545734e449ed9634b..46562480b7c3ba54ed69255504b2536597d3fba8 100644
--- a/Assets/Scripts/Core/Objects/Weapons/WeaponObject.cs
+++ b/Assets/Scripts/Core/Objects/Weapons/WeaponObject.cs
@@ -4,11 +4,12 @@ using UnityEngine;
 
 public abstract class WeaponObject : MonoBehaviour 
 {
+
     // Attributes
+    public string prefabPath;
     public WeaponData data;
-    protected AttackObjectType bearerType;
     protected IArmed bearer;
-    [SerializeField] private bool canAttack;
+    private bool canAttack = true;
 
     // Events
     public event Action OnAttackEvent;
@@ -18,21 +19,6 @@ public abstract class WeaponObject : MonoBehaviour
     protected void Start()
     {
         bearer = GetComponentInParent<IArmed>();
-        
-        // Switch requires a constant, so can't use that here
-        if(bearer is Player)
-        {
-            bearerType = AttackObjectType.PLAYER;
-        }
-        else if(bearer is EnemyEntity)
-        {
-            bearerType = AttackObjectType.ENEMY;
-        } 
-        else
-        {
-            bearerType = AttackObjectType.ENVIRONMENT;
-        } 
-
         canAttack = true;
         OnAttackEvent += OnAttack;
         OnAlternateAttackEvent += OnAlternateAttack;
diff --git a/Assets/Scripts/Core/Player/Player.cs b/Assets/Scripts/Core/Player/Player.cs
index b559a55e4172e489ce338eca1bea280358403bc2..89d543c1c1d10bdc7a90bf3e7b21b02d19833231 100644
--- a/Assets/Scripts/Core/Player/Player.cs
+++ b/Assets/Scripts/Core/Player/Player.cs
@@ -15,6 +15,10 @@ public class Player : PlayerEntity
     public PlayerStateController stateController;
     public PlayerStats stats;
 
+    // Set-Getters
+    public new string AttackLayerCode => EnvironmentConfig.LAYER_PLAYER;
+    public new float AttackMultiplier => GameConfig.DIFFICULTY_MODIFIERS[GameSaveData.instance.difficulty].PlayerDamageMultiplier;
+
     // Constructor
     new void Start()
     {
@@ -33,7 +37,7 @@ public class Player : PlayerEntity
         {
             WeaponList.Add(weapon);
         }
-        SetWeapon(0);
+        EquipWeapon(0);
 
         GameController.instance.player = this;
     }
diff --git a/Assets/Scripts/Core/Player/PlayerInputController.cs b/Assets/Scripts/Core/Player/PlayerInputController.cs
index ec2edea6b19715621eaaa4a38926f2b009dcd4b5..afe5b3b57529f73a1a7d9fc5bfddd79fb16aa77a 100644
--- a/Assets/Scripts/Core/Player/PlayerInputController.cs
+++ b/Assets/Scripts/Core/Player/PlayerInputController.cs
@@ -34,20 +34,24 @@ public class PlayerInputController
             Debug.Log("Player is Attacking");
             if(player.Weapon == null)
             {
+                Debug.Log("Player does not have a weapon");
                 return;
             }
+            Debug.Log("Attacking using Weapon");
 
             player.Weapon.Attack();
+            (player.Weapon as TestWeapon).AlternateAttack();
         }
         else if(Input.GetKeyDown(GameInput.instance.attackAlternateButton))
         {
             Debug.Log("Player is Attacking (alternate)");
             if(player.Weapon == null)
             {
+                Debug.Log("Player does not have a weapon");
                 return;
             }
 
-            player.Weapon.AlternateAttack();
+            (player.Weapon as TestWeapon).AlternateAttack();
         }
         else if(Input.GetKeyDown(GameInput.instance.interactButton))
         {
diff --git a/Assets/Scripts/Library/BaseClasses/Controller/AnimationController.cs b/Assets/Scripts/Library/BaseClasses/Controller/AnimationController.cs
index 411af95c4ea42553f273342c422c600c5e3da0c7..aa119af6fc833f7f95b1c4928d8692402903f001 100644
--- a/Assets/Scripts/Library/BaseClasses/Controller/AnimationController.cs
+++ b/Assets/Scripts/Library/BaseClasses/Controller/AnimationController.cs
@@ -10,7 +10,7 @@ public abstract class AnimationController
     // Constructor
     public AnimationController(MonoBehaviour animable)
     {
-        model = animable.transform.Find("Model");
+        model = animable.transform.Find(EnvironmentConfig.OBJECT_MODEL);
         animator = model.GetComponent<Animator>();
         meshRenderer = model.GetComponent<MeshRenderer>();
 
diff --git a/Assets/Scripts/Library/BaseClasses/EntityObject/CombatantEntity.cs b/Assets/Scripts/Library/BaseClasses/EntityObject/CombatantEntity.cs
index 4b3eebc5f231a20880101194f3aec65d14e878b0..a837c75c9de707bbeeed27f7b9f48a3f749d4a78 100644
--- a/Assets/Scripts/Library/BaseClasses/EntityObject/CombatantEntity.cs
+++ b/Assets/Scripts/Library/BaseClasses/EntityObject/CombatantEntity.cs
@@ -1,11 +1,13 @@
 using System;
 using System.Collections.Generic;
+using System.Reflection;
 using UnityEngine;
 
 public class CombatantEntity : DamageableEntity, IArmed
 {
     // Attributes
-    [SerializeField] private float baseDamage;
+    [SerializeField] protected float baseDamage;
+    [SerializeField] protected Vector3 weaponLocation;
     public List<WeaponObject> weaponList = new();
     private int weaponIndex;
     
@@ -13,6 +15,9 @@ public class CombatantEntity : DamageableEntity, IArmed
     public List<WeaponObject> WeaponList => weaponList;
     public WeaponObject Weapon => weaponList.Count > 0? weaponList[WeaponIndex] : null;
     public Transform Orientation => transform;
+    public Vector3 WeaponLocation => weaponLocation;
+    public string AttackLayerCode => EnvironmentConfig.LAYER_ENVIRONMENT_ATTACK;
+    public float AttackMultiplier => 1f;
     public float BaseDamage 
     {
         get => baseDamage;
@@ -31,14 +36,38 @@ public class CombatantEntity : DamageableEntity, IArmed
         } 
     }
 
+
     // Functions
-    public void SetWeapon(int index)
+    // TODO: Review, consider using prefabs instead?
+    // Prefabs are easier to implement but much less extendable
+    public void EquipWeapon(int index)
     {
         if(weaponList.Count == 0)
         {
             return;
         }
+        Debug.Log($"Equipping weapon {WeaponIndex}");
+
+        UnequipWeapon();
 
         WeaponIndex = index;
+
+        WeaponObject weaponObject = ObjectFactory.CreateObject<WeaponObject>(
+            prefabPath: Weapon.prefabPath,
+            parent: transform, 
+            position: WeaponLocation,
+            objectName: EnvironmentConfig.OBJECT_WEAPON
+        );
+        weaponObject.gameObject.layer = LayerMask.NameToLayer(AttackLayerCode);
+        WeaponList[weaponIndex] = weaponObject;
+
+        Debug.Log(Weapon == null);
+    }
+
+    public void UnequipWeapon(){
+        foreach (WeaponObject weapon in GetComponentsInChildren<WeaponObject>())
+        {
+            Destroy(weapon.gameObject);
+        }
     }
 }
diff --git a/Assets/Scripts/Library/BaseClasses/EntityObject/WorldEntity.cs b/Assets/Scripts/Library/BaseClasses/EntityObject/WorldEntity.cs
index c0ed5fb772d9a7cec802c8561811f12a2feefb9d..7f5181197f762c44dcb746f5e1f44484b0ad9623 100644
--- a/Assets/Scripts/Library/BaseClasses/EntityObject/WorldEntity.cs
+++ b/Assets/Scripts/Library/BaseClasses/EntityObject/WorldEntity.cs
@@ -6,8 +6,8 @@ public class WorldEntity : WorldObject, IRigid
     [SerializeField] private float knockbackResistance;
     [SerializeField] private float baseSpeed;
     [SerializeField] private float jumpForce;
-    protected Vector3 groundDetectionSize; 
     [SerializeField] protected LayerMask groundLayers;
+    protected Vector3 groundDetectionSize; 
     protected new Rigidbody rigidbody;
     private bool grounded = false;
 
@@ -40,7 +40,7 @@ public class WorldEntity : WorldObject, IRigid
         {
             Debug.LogWarning("Rigid entity " + name + " does not have a rigidbody"); 
         }
-        groundLayers = LayerMask.GetMask(GameEnvironmentConfig.LAYER_DEFAULT);
+        groundLayers = LayerMask.GetMask(EnvironmentConfig.LAYER_DEFAULT);
     }
 
     // Functions
diff --git a/Assets/Scripts/Library/Enum/AttackObjectType.cs b/Assets/Scripts/Library/Enum/AttackObjectType.cs
deleted file mode 100644
index 103641dae7b7ee2947bafce28de6fc0982897775..0000000000000000000000000000000000000000
--- a/Assets/Scripts/Library/Enum/AttackObjectType.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-public enum AttackObjectType 
-{
-    PLAYER,
-    ENEMY,
-    ENVIRONMENT
-}
diff --git a/Assets/Scripts/Library/Enum/AttackObjectType.cs.meta b/Assets/Scripts/Library/Enum/AttackObjectType.cs.meta
deleted file mode 100644
index a494c18c8bdc6f00daa60591c7d721bafbdf36b7..0000000000000000000000000000000000000000
--- a/Assets/Scripts/Library/Enum/AttackObjectType.cs.meta
+++ /dev/null
@@ -1,11 +0,0 @@
-fileFormatVersion: 2
-guid: 26aa78311840dbc4d80cd73c43fe9bcf
-MonoImporter:
-  externalObjects: {}
-  serializedVersion: 2
-  defaultReferences: []
-  executionOrder: 0
-  icon: {instanceID: 0}
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Assets/Scripts/Library/Interfaces/IArmed.cs b/Assets/Scripts/Library/Interfaces/IArmed.cs
index 7752880ae0b8f0da4827c3e195b0ab85b1a4095d..5282e6a7f742948a4028e801e27118efe893d5db 100644
--- a/Assets/Scripts/Library/Interfaces/IArmed.cs
+++ b/Assets/Scripts/Library/Interfaces/IArmed.cs
@@ -5,6 +5,9 @@ public interface IArmed
 {
     // Set-Getters
     public float BaseDamage { get; set; }
+    public string AttackLayerCode { get; }
+    public float AttackMultiplier { get; }
+    public Vector3 WeaponLocation { get; }
     public WeaponObject Weapon { get; }
     public Transform Orientation { get; }
 }
diff --git a/Assets/Scripts/Library/Util/ObjectFactory.cs b/Assets/Scripts/Library/Util/ObjectFactory.cs
index 8cb2285ce8fe1eb435e58df98919c61bfa3f6914..8760e02974d76b8271acfd88f34b453a341f4e63 100644
--- a/Assets/Scripts/Library/Util/ObjectFactory.cs
+++ b/Assets/Scripts/Library/Util/ObjectFactory.cs
@@ -26,6 +26,41 @@ public static class ObjectFactory
         return CreateObject(prefabObject, parent, position, scale, rotation, renderingOrder, objectName);
     }
 
+    public static GameObject CreateObject(
+        GameObject gameObject,
+        Transform parent = null,
+        Vector3? position = null,
+        Vector3? scale = null,
+        Quaternion? rotation = null,
+        int renderingOrder = 0,
+        string objectName = "Unnamed Object"
+    )
+    {
+        GameObject createdObject = parent == null?
+            GameObject.Instantiate(gameObject, ObjectManager.instance.transform) :
+            GameObject.Instantiate(gameObject, parent);
+
+        if(position != null)
+        {
+            createdObject.transform.position = position.Value;
+        }
+        if(rotation != null)
+        {
+            createdObject.transform.rotation *= rotation.Value;
+        }
+        if(scale != null)
+        {
+            createdObject.transform.localScale = Vector3.Scale(createdObject.transform.localScale, scale.Value);
+        }
+        if(createdObject.TryGetComponent<Renderer>(out var renderer))
+        {
+            renderer.sortingOrder = renderingOrder;
+        }
+        createdObject.name = objectName;
+
+        return createdObject;
+    }
+
     public static T CreateObject<T>(
         string prefabPath,
         Transform parent = null,
@@ -54,12 +89,41 @@ public static class ObjectFactory
         return UnityObject;
     }
 
+    public static T CreateObject<T>(
+        GameObject gameObject,
+        Transform parent = null,
+        Vector3? position = null,
+        Vector3? scale = null,
+        Quaternion? rotation = null,
+        int renderingOrder = 0,
+        string objectName = "Unnamed Object"
+    ) where T : MonoBehaviour 
+    {
+        GameObject prefabObject = CreateObject(
+            gameObject, 
+            parent == null? ObjectManager.instance.transform : parent, 
+            position, 
+            scale, 
+            rotation, 
+            renderingOrder, 
+            objectName
+        );
+
+        if(!prefabObject.TryGetComponent<T>(out var UnityObject))
+        {
+            Debug.LogError("Loaded gameobject is not a a valid type: " + gameObject.name);
+        }
+
+        return UnityObject;
+    }
+
     public static AttackObject CreateAttackObject(
         string prefabPath,
         float damage,
         float knockbackPower,
         Vector3 knockbackOrigin,
-        AttackObjectType type,
+        string attackLayerCode = EnvironmentConfig.LAYER_ENVIRONMENT_ATTACK,
+        float damageModifier = 0,
         Transform parent = null,
         Vector3? position = null,
         Vector3? scale = null,
@@ -81,24 +145,9 @@ public static class ObjectFactory
         attackObject.Damage = damage;
         attackObject.KnockbackPower = knockbackPower;
         attackObject.KnockbackOrigin = knockbackOrigin;
-
-        switch (type)
-        {
-            case AttackObjectType.PLAYER:
-                attackObject.gameObject.layer = LayerMask.NameToLayer(GameEnvironmentConfig.LAYER_PLAYER_ATTACK);
-                attackObject.Damage *= GameConfig.DIFFICULTY_MODIFIERS[GameSaveData.instance.difficulty].PlayerDamageMultiplier;
-                break;
-            case AttackObjectType.ENEMY:
-                attackObject.gameObject.layer = LayerMask.NameToLayer(GameEnvironmentConfig.LAYER_ENEMY_ATTACK);
-                attackObject.Damage *= GameConfig.DIFFICULTY_MODIFIERS[GameSaveData.instance.difficulty].EnemyDamageMultiplier;
-                break;
-            case AttackObjectType.ENVIRONMENT:
-                attackObject.gameObject.layer = LayerMask.NameToLayer(GameEnvironmentConfig.LAYER_ENVIRONMENT_ATTACK);
-                break;
-            default:
-                Debug.LogError("Invalid AttackObjectType set, please refer to enum AttackObjectType for valid types");
-                break;
-        }
+        attackObject.gameObject.layer = 
+        attackObject.gameObject.layer = LayerMask.NameToLayer(attackLayerCode);
+        attackObject.Damage *= damageModifier;
 
         return attackObject;
     }
@@ -108,7 +157,8 @@ public static class ObjectFactory
         float damage,
         float knockbackPower,
         Vector3 knockbackOrigin,
-        AttackObjectType type,
+        string attackLayerCode = EnvironmentConfig.LAYER_ENVIRONMENT_ATTACK,
+        float damageModifier = 0,
         Transform parent = null,
         Vector3? position = null,
         Vector3? scale = null,
@@ -122,7 +172,8 @@ public static class ObjectFactory
             damage, 
             knockbackPower, 
             knockbackOrigin, 
-            type, 
+            attackLayerCode, 
+            damageModifier,
             parent, 
             position, 
             scale, 
@@ -158,7 +209,7 @@ public static class ObjectFactory
             objectName
         );
 
-        collectible.gameObject.layer = LayerMask.NameToLayer(GameEnvironmentConfig.LAYER_COLLECTIBLE);
+        collectible.gameObject.layer = LayerMask.NameToLayer(EnvironmentConfig.LAYER_COLLECTIBLE);
         
         return collectible;
     }
@@ -191,41 +242,6 @@ public static class ObjectFactory
     }
 
     // Internal functions
-    private static GameObject CreateObject(
-        GameObject gameObject,
-        Transform parent = null,
-        Vector3? position = null,
-        Vector3? scale = null,
-        Quaternion? rotation = null,
-        int renderingOrder = 0,
-        string objectName = "Unnamed Object"
-    )
-    {
-        GameObject createdObject = parent == null?
-            GameObject.Instantiate(gameObject, ObjectManager.instance.transform) :
-            GameObject.Instantiate(gameObject, parent);
-
-        if(position != null)
-        {
-            createdObject.transform.position = position.Value;
-        }
-        if(rotation != null)
-        {
-            createdObject.transform.rotation *= rotation.Value;
-        }
-        if(scale != null)
-        {
-            createdObject.transform.localScale = Vector3.Scale(createdObject.transform.localScale, scale.Value);
-        }
-        if(createdObject.TryGetComponent<Renderer>(out var renderer))
-        {
-            renderer.sortingOrder = renderingOrder;
-        }
-        createdObject.name = objectName;
-
-        return createdObject;
-    }
-    
     private static IEnumerator DestroyWithDelay(GameObject gameObject, float delay)
     {
         yield return new WaitForSeconds(delay);