diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 359ab2a991372e2a119bc043d26485b5a2e4fa8e..a04763c60e0f5c014a1dc04395d381df66262c53 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -7,7 +7,7 @@
 
 include:
   - project: '${UNREAL_CI_PROJECT}'
-    ref: master 
+    ref: master
     file: '/shared_scripts.yml'
     
 # In this file you are able to configure your plugins pipeline.
@@ -36,6 +36,11 @@ include:
 #
 # You can uncomment the deploy lines to deploy your project to the CAVE/VRDev. This only makes sense, if your plugin works
 # with a generated project.
+#
+# Use the UNREAL_VERSION variable to adjust to your preferred Unreal version.
+
+variables:
+    UNREAL_VERSION: "5.3"
 
 stages:
   - analyze
@@ -58,7 +63,7 @@ clang-format:
     allow_failure: false
     script:
         - clang-format --version
-        - git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME --depth 1
+        - git fetch --depth 1 origin $CI_MERGE_REQUEST_DIFF_BASE_SHA
         - echo $CI_MERGE_REQUEST_DIFF_BASE_SHA 
         - linter_errors=$(unbuffer git-clang-format --commit "$CI_MERGE_REQUEST_DIFF_BASE_SHA" *.h *.cpp -q --diff | grep -v --color=always "no modified files to format" || true)
         - echo "$linter_errors"
@@ -68,10 +73,12 @@ Generate_Project:
     rules: 
       - if: $CI_PIPELINE_SOURCE == "web"
       - if: $CI_PIPELINE_SOURCE == "schedule"
+      - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+      - if: $CI_COMMIT_TAG
+      - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
     extends: .Generate_Project_
     variables:
         RUN_SETUP: "false"
-        GEN_TEMPLATE_BRANCH: "5.3"
         GEN_DEPENDENCIES: "(
             [master@UnrealDTrackPlugin]='https://github.com/VRGroupRWTH/UnrealDTrackPlugin.git')"
 
@@ -80,6 +87,9 @@ Build_Windows:
     rules: 
       - if: $CI_PIPELINE_SOURCE == "web"
       - if: $CI_PIPELINE_SOURCE == "schedule"
+      - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+      - if: $CI_COMMIT_TAG
+      - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
     extends: .Build_Windows_
     tags:
         - windows
@@ -97,6 +107,9 @@ Build_Linux:
     rules: 
       - if: $CI_PIPELINE_SOURCE == "web"
       - if: $CI_PIPELINE_SOURCE == "schedule"
+      - if: $CI_PIPELINE_SOURCE == 'merge_request_event'
+      - if: $CI_COMMIT_TAG
+      - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
     extends: .Build_Linux_
     tags:
         - linux
@@ -111,6 +124,7 @@ Build_Linux:
         - job: "Generate_Project"
           artifacts: true
 
+# Deploys to vrdev
 Deploy_Windows:
     rules: 
       - if: $CI_PIPELINE_SOURCE == "web"
@@ -120,6 +134,7 @@ Deploy_Windows:
         - job: "Build_Windows"
           artifacts: true          
 
+# Deploys to vrdemo instead of av006de. Use extends: .Deploy_CAVE_ to deploy to legacy av006de
 Deploy_CAVE:
     rules: 
       - if: $CI_PIPELINE_SOURCE == "web"
diff --git a/Config/DefaultRWTHVRToolkit.ini b/Config/DefaultRWTHVRToolkit.ini
index 29ee91a7aaabc28feebf6357b1672bdd652ff613..13066ebe26e8ab454486f97bbb982275d9b2587c 100644
--- a/Config/DefaultRWTHVRToolkit.ini
+++ b/Config/DefaultRWTHVRToolkit.ini
@@ -4,4 +4,18 @@
 +StructRedirects = (OldName="/Script/RWTHVRToolkit.VRTransformRep",NewName="/Script/RWTHVRToolkit.ReplicatedTransform")
 +ClassRedirects = (OldName="/Script/RWTHVRToolkit.VRWidgetInteractionComponent",NewName="/Script/RWTHVRToolkit.RWTHVRWidgetInteractionComponent")
 +PropertyRedirects = (OldName="/Script/RWTHVRToolkit.RWTHVRPawn.PawnMovement",NewName="/Script/RWTHVRToolkit.RWTHVRPawn.CollisionHandlingMovement")
-+PropertyRedirects = (OldName="/Script/RWTHVRToolkit.RWTHVRPawn.PawnMovement",NewName="/Script/RWTHVRToolkit.RWTHVRPawn.CollisionHandlingMovement")
\ No newline at end of file
++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.RWTHVRPawn.PawnMovement",NewName="/Script/RWTHVRToolkit.RWTHVRPawn.CollisionHandlingMovement")
++ClassRedirects = (OldName="/Script/RWTHVRToolkit.RaycastSelectionComponent",NewName="/Script/RWTHVRToolkit.RaycastInteractionComponent")
++ClassRedirects = (OldName="/Script/RWTHVRToolkit.GrabComponent",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent")
++FunctionRedirects = (OldName="/Script/RWTHVRToolkit.RaycastInteractionComponent.OnBeginSelect",NewName="/Script/RWTHVRToolkit.RaycastInteractionComponent.OnBeginInteraction")
++FunctionRedirects = (OldName="/Script/RWTHVRToolkit.RaycastInteractionComponent.OnEndSelect",NewName="/Script/RWTHVRToolkit.RaycastInteractionComponent.OnEndInteraction")
++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.RaycastInteractionComponent.RayCastSelectInputAction",NewName="/Script/RWTHVRToolkit.RaycastInteractionComponent.RayCastInteractionInputAction")
++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.RaycastInteractionComponent.RayCastInteractionInputAction",NewName="/Script/RWTHVRToolkit.RaycastInteractionComponent.InteractionInputAction")
++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.PreviousGrabbablesInRange",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.PreviousInteractableComponentsInRange")
++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.GrabInputAction",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.InteractionInputAction")
++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.GrabSphereRadius",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.InteractionSphereRadius")
++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.bOnlyGrabClosestActor",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.bOnlyInteractWithClosestActor")
++FunctionRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnBeginGrab",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnBeginInteraction")
++FunctionRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnEndGrab",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.OnEndInteraction")
++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.PreviousGrabBehavioursInRange",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.PreviousInteractableComponentsInRange")
++PropertyRedirects = (OldName="/Script/RWTHVRToolkit.DirectInteractionComponent.CurrentGrabBehavioursInRange",NewName="/Script/RWTHVRToolkit.DirectInteractionComponent.CurrentInteractableComponentsInRange")
\ No newline at end of file
diff --git a/Content/BP_RWTHVRGameModeBase.uasset b/Content/BP_RWTHVRGameModeBase.uasset
index 06db2806ba4271750b06549bc76becfdb32a2ba2..a073a7f7cc247654e724c9d348d57f9bdc55d9ed 100644
Binary files a/Content/BP_RWTHVRGameModeBase.uasset and b/Content/BP_RWTHVRGameModeBase.uasset differ
diff --git a/Content/BP_RWTHVRPawn.uasset b/Content/BP_RWTHVRPawn.uasset
deleted file mode 100644
index 871461e6ffad1c644424221840b57799c9433fe9..0000000000000000000000000000000000000000
Binary files a/Content/BP_RWTHVRPawn.uasset and /dev/null differ
diff --git a/Content/Components/DirectInteraction/BP_DirectInteractionComponent.uasset b/Content/Components/DirectInteraction/BP_DirectInteractionComponent.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..840b43fab2eba1c474284e57c0018ec0d7babaaf
Binary files /dev/null and b/Content/Components/DirectInteraction/BP_DirectInteractionComponent.uasset differ
diff --git a/Content/Components/DirectInteraction/IA_DirectInteractionLeft.uasset b/Content/Components/DirectInteraction/IA_DirectInteractionLeft.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..05597e706243b8138bcea4da36fcc87849b6ba51
Binary files /dev/null and b/Content/Components/DirectInteraction/IA_DirectInteractionLeft.uasset differ
diff --git a/Content/Components/DirectInteraction/IA_DirectInteractionRight.uasset b/Content/Components/DirectInteraction/IA_DirectInteractionRight.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..76128dfe613f4825b57d9a27ac9c93e1829554de
Binary files /dev/null and b/Content/Components/DirectInteraction/IA_DirectInteractionRight.uasset differ
diff --git a/Content/Components/Grabbing/BP_GrabComponent.uasset b/Content/Components/Grabbing/BP_GrabComponent.uasset
deleted file mode 100644
index 5e0430e93aee43918ea62d4465f86e3812efe423..0000000000000000000000000000000000000000
Binary files a/Content/Components/Grabbing/BP_GrabComponent.uasset and /dev/null differ
diff --git a/Content/Components/Grabbing/BP_GrabbableObjectTest.uasset b/Content/Components/Grabbing/BP_GrabbableObjectTest.uasset
deleted file mode 100644
index 6300ab49226dce334df0826293f3d583c7605c07..0000000000000000000000000000000000000000
Binary files a/Content/Components/Grabbing/BP_GrabbableObjectTest.uasset and /dev/null differ
diff --git a/Content/Components/Grabbing/BP_GrabbableTestObject.uasset b/Content/Components/Grabbing/BP_GrabbableTestObject.uasset
deleted file mode 100644
index 9ee3c8f375ef05e90f3c3f8300b6a13f94def5c6..0000000000000000000000000000000000000000
Binary files a/Content/Components/Grabbing/BP_GrabbableTestObject.uasset and /dev/null differ
diff --git a/Content/Components/Grabbing/IA_GrabLeft.uasset b/Content/Components/Grabbing/IA_GrabLeft.uasset
deleted file mode 100644
index bcc873bcdbf823add969db4e7528603617badb84..0000000000000000000000000000000000000000
Binary files a/Content/Components/Grabbing/IA_GrabLeft.uasset and /dev/null differ
diff --git a/Content/Components/Grabbing/IA_GrabRight.uasset b/Content/Components/Grabbing/IA_GrabRight.uasset
deleted file mode 100644
index 9df17caed4d5b4f6e8da91e219ffde3fdb72c21e..0000000000000000000000000000000000000000
Binary files a/Content/Components/Grabbing/IA_GrabRight.uasset and /dev/null differ
diff --git a/Content/Components/Grabbing/IMC_Grab.uasset b/Content/Components/Grabbing/IMC_Grab.uasset
deleted file mode 100644
index 47abc9f0ea07957df2f54c0c80f683d07a14fadc..0000000000000000000000000000000000000000
Binary files a/Content/Components/Grabbing/IMC_Grab.uasset and /dev/null differ
diff --git a/Content/Components/Movement/ContinuousMovement/BP_ContinuousMovementComponent.uasset b/Content/Components/Movement/ContinuousMovement/BP_ContinuousMovementComponent.uasset
index 83b1677640b9495da4155029b2b3f320a66ccb81..6885feec7ec19c1fd7f5771d379225ebd86dd0e1 100644
Binary files a/Content/Components/Movement/ContinuousMovement/BP_ContinuousMovementComponent.uasset and b/Content/Components/Movement/ContinuousMovement/BP_ContinuousMovementComponent.uasset differ
diff --git a/Content/Components/Movement/IMC_MovementLeftHand.uasset b/Content/Components/Movement/IMC_MovementLeftHand.uasset
deleted file mode 100644
index d871b2eb4545c1acbc81470a80ae950683a574bc..0000000000000000000000000000000000000000
Binary files a/Content/Components/Movement/IMC_MovementLeftHand.uasset and /dev/null differ
diff --git a/Content/Components/Movement/IMC_MovementRightHand.uasset b/Content/Components/Movement/IMC_MovementRightHand.uasset
deleted file mode 100644
index b1eb664d5e755f86858f40ad6737e87e9dd29a0c..0000000000000000000000000000000000000000
Binary files a/Content/Components/Movement/IMC_MovementRightHand.uasset and /dev/null differ
diff --git a/Content/Components/Movement/Teleportation/BP_TeleportationComponent.uasset b/Content/Components/Movement/Teleportation/BP_TeleportationComponent.uasset
index d83f23de6da316687028de4c6a45713918bee2f4..724895615850f01d9d665e8b40569d5829fc4574 100644
Binary files a/Content/Components/Movement/Teleportation/BP_TeleportationComponent.uasset and b/Content/Components/Movement/Teleportation/BP_TeleportationComponent.uasset differ
diff --git a/Content/Components/Movement/Turn/BP_TurnComponent.uasset b/Content/Components/Movement/Turn/BP_TurnComponent.uasset
index e135a8eca226aa6043ca8dcdb87932775aadc93b..a572594744827a04a0a6a6b1912e80ef9be86297 100644
Binary files a/Content/Components/Movement/Turn/BP_TurnComponent.uasset and b/Content/Components/Movement/Turn/BP_TurnComponent.uasset differ
diff --git a/Content/Components/Movement/Turn/IMC_DesktopRotation.uasset b/Content/Components/Movement/Turn/IMC_DesktopRotation.uasset
deleted file mode 100644
index d68fb4eae4e33f04237249477b5a9994cb6b2721..0000000000000000000000000000000000000000
Binary files a/Content/Components/Movement/Turn/IMC_DesktopRotation.uasset and /dev/null differ
diff --git a/Content/Components/Raycast/BP_RaycastSelectionComponent.uasset b/Content/Components/Raycast/BP_RaycastSelectionComponent.uasset
deleted file mode 100644
index 4900352dfaa28d6b6f38c595e44bbc889891c947..0000000000000000000000000000000000000000
Binary files a/Content/Components/Raycast/BP_RaycastSelectionComponent.uasset and /dev/null differ
diff --git a/Content/Components/Raycast/IA_RaycastSelectLeft.uasset b/Content/Components/Raycast/IA_RaycastSelectLeft.uasset
deleted file mode 100644
index 16139611e6a786a71823592bd78c1feb2518862d..0000000000000000000000000000000000000000
Binary files a/Content/Components/Raycast/IA_RaycastSelectLeft.uasset and /dev/null differ
diff --git a/Content/Components/Raycast/IA_RaycastSelectRight.uasset b/Content/Components/Raycast/IA_RaycastSelectRight.uasset
deleted file mode 100644
index 201c652c77e03a56b9c67e9fcfce356d16e10f3c..0000000000000000000000000000000000000000
Binary files a/Content/Components/Raycast/IA_RaycastSelectRight.uasset and /dev/null differ
diff --git a/Content/Components/Raycast/IMC_RaycastSelection.uasset b/Content/Components/Raycast/IMC_RaycastSelection.uasset
deleted file mode 100644
index c8107a17d2a2759c51d57c42495245273d290947..0000000000000000000000000000000000000000
Binary files a/Content/Components/Raycast/IMC_RaycastSelection.uasset and /dev/null differ
diff --git a/Content/Components/RaycastInteraction/BP_RaycastInteractionComponent.uasset b/Content/Components/RaycastInteraction/BP_RaycastInteractionComponent.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..2416ad8fba677355d3d0f1fc8a1708b90bc8fb12
Binary files /dev/null and b/Content/Components/RaycastInteraction/BP_RaycastInteractionComponent.uasset differ
diff --git a/Content/Components/RaycastInteraction/IA_RaycastInteractionLeft.uasset b/Content/Components/RaycastInteraction/IA_RaycastInteractionLeft.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..13494f735ac48c8c86551b18695f3a0cd064d524
Binary files /dev/null and b/Content/Components/RaycastInteraction/IA_RaycastInteractionLeft.uasset differ
diff --git a/Content/Components/RaycastInteraction/IA_RaycastInteractionRight.uasset b/Content/Components/RaycastInteraction/IA_RaycastInteractionRight.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..f6ffa30dcc98699d57b19eacfa02bd0701e076e0
Binary files /dev/null and b/Content/Components/RaycastInteraction/IA_RaycastInteractionRight.uasset differ
diff --git a/Content/Components/WidgetInteraction/BP_RWTHVRWidgetInteractionComponent.uasset b/Content/Components/WidgetInteraction/BP_RWTHVRWidgetInteractionComponent.uasset
index bbbac1fc6516d46209168216f4d8b502e88f0a38..904f5d3363442da0ff916b54041f595a4e023ffc 100644
Binary files a/Content/Components/WidgetInteraction/BP_RWTHVRWidgetInteractionComponent.uasset and b/Content/Components/WidgetInteraction/BP_RWTHVRWidgetInteractionComponent.uasset differ
diff --git a/Content/Components/WidgetInteraction/IA_WidgetClick.uasset b/Content/Components/WidgetInteraction/IA_WidgetClick.uasset
index 1e8b6c8dbba9ffe7beac263c84b4c800c521e468..a178015abe4a9f945703f46f936b35b97850bc91 100644
Binary files a/Content/Components/WidgetInteraction/IA_WidgetClick.uasset and b/Content/Components/WidgetInteraction/IA_WidgetClick.uasset differ
diff --git a/Content/Components/WidgetInteraction/IMC_WidgetInteraction.uasset b/Content/Components/WidgetInteraction/IMC_WidgetInteraction.uasset
deleted file mode 100644
index d3751897c41b760e653f74954ff29956897cd671..0000000000000000000000000000000000000000
Binary files a/Content/Components/WidgetInteraction/IMC_WidgetInteraction.uasset and /dev/null differ
diff --git a/Content/Examples/ContentExamples/BP_RWTHVRContentExamplesGameModeBase.uasset b/Content/Examples/ContentExamples/BP_RWTHVRContentExamplesGameModeBase.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..352e801778bc4dd955b5a1a4fcea0f973b37a1cf
Binary files /dev/null and b/Content/Examples/ContentExamples/BP_RWTHVRContentExamplesGameModeBase.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoAssets/BP_GrabbableTestObject.uasset b/Content/Examples/ContentExamples/DemoAssets/BP_GrabbableTestObject.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..00436a8ef34d22cb949180832fb6717255ed1c98
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoAssets/BP_GrabbableTestObject.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoAssets/BP_IntenselectableObject.uasset b/Content/Examples/ContentExamples/DemoAssets/BP_IntenselectableObject.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..ad3229202c1db904c6f218802fdbc86d33d8fc44
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoAssets/BP_IntenselectableObject.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/BP_DemoRoom.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/BP_DemoRoom.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..8d44e3029f0810051a7b749688b3440afff8e7ed
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/BP_DemoRoom.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/BP_Demostation.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/BP_Demostation.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..97a2b6c1fd75976d41f6be2ce09463f72d594432
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/BP_Demostation.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_back_piller.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_back_piller.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..5ea4eeae269ac2a5ced17512441e6553f15b3e9d
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_back_piller.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_connector.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_connector.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..23da0e9f10b0195e1989f82c36d6823c8a1f1d5f
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_connector.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_floor.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_floor.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..ecc96bc983b194433b1ac5d28ae7e9cc66466685
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_floor.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_front_pillar.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_front_pillar.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..45afb30f73d17fbb06b17c5094f3b45f53953a20
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_front_pillar.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_long_wall.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_long_wall.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..45f4726ee04ed13fa708367db11e51e7a2b3d00a
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_long_wall.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_short_wall.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_short_wall.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..41b2612ae5c28c58726de02a01ac0653b9fe1c6b
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_short_wall.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_vertical_end_piller.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_vertical_end_piller.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..50a800b203f84ac8d8c20a92c5a52ffdd82e5c94
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomAssets_vertical_end_piller.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomTest.umap b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomTest.umap
new file mode 100644
index 0000000000000000000000000000000000000000..6be975361c9574680f74d95ff7bf292077eb7674
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/DemoRoomTest.umap differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/Entrance_Pillars.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/Entrance_Pillars.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..2bbac6b5b367deb14eb705d565330dff3e1e2c73
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/Entrance_Pillars.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/Floor.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/Floor.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..2d35c3d3567c1b1d933bd1d6d0856a73c55e0398
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/Floor.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/Frame.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/Frame.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..add5d5f739c5dabd1151080881594c4d0457dfb0
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/Frame.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/Inner_Walls.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/Inner_Walls.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..536ff38d226d282001023852d0ac859e52f198c7
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/Inner_Walls.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/Interior.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/Interior.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..a1416e648a43482d0dddcc8e8db12a5b6bcf9453
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/Interior.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/Outer_Pillars.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/Outer_Pillars.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..3f5d03a620faf69dccb1e197e26733a1f9f4a03d
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/Outer_Pillars.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/Outer_Walls.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/Outer_Walls.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..7d4cce614f650980991e92d295cfbd644d629768
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/Outer_Walls.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/S_RoomSettings.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/S_RoomSettings.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..8f0d598d8eb1c659cf39951b600768f0b66ba884
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/S_RoomSettings.uasset differ
diff --git a/Content/Examples/ContentExamples/DemoRoomAssets/demostation.uasset b/Content/Examples/ContentExamples/DemoRoomAssets/demostation.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..0ca2d2b37cb8d0f3e9d9a5207b87b50db51bbf2d
Binary files /dev/null and b/Content/Examples/ContentExamples/DemoRoomAssets/demostation.uasset differ
diff --git a/Content/Examples/ContentExamples/Pawns/BP_ContentExamplesPawn.uasset b/Content/Examples/ContentExamples/Pawns/BP_ContentExamplesPawn.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..12de4cfc6edddae40e7e026cb9ab082f1e8f4f57
Binary files /dev/null and b/Content/Examples/ContentExamples/Pawns/BP_ContentExamplesPawn.uasset differ
diff --git a/Content/Examples/ContentExamples/Pawns/BP_TeleportPawn.uasset b/Content/Examples/ContentExamples/Pawns/BP_TeleportPawn.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..df1abb51e6dc3aa7f555518abba1c2af5673e941
Binary files /dev/null and b/Content/Examples/ContentExamples/Pawns/BP_TeleportPawn.uasset differ
diff --git a/Content/Examples/ContentExamples/ToolkitExamples.umap b/Content/Examples/ContentExamples/ToolkitExamples.umap
new file mode 100644
index 0000000000000000000000000000000000000000..c6e4c2d650345e901032eb8d009b9d65375209a0
Binary files /dev/null and b/Content/Examples/ContentExamples/ToolkitExamples.umap differ
diff --git a/Content/Examples/ContentExamples/Trigger/ContinuousNavigationModeTrigger.uasset b/Content/Examples/ContentExamples/Trigger/ContinuousNavigationModeTrigger.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..b9a5a2d6c5c3600a9a06c3c61f93fa41d7cd9e1d
Binary files /dev/null and b/Content/Examples/ContentExamples/Trigger/ContinuousNavigationModeTrigger.uasset differ
diff --git a/Content/Examples/ContentExamples/Trigger/InteractionTechniqueSwapTrigger.uasset b/Content/Examples/ContentExamples/Trigger/InteractionTechniqueSwapTrigger.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..befe62fdd1270d6b73eb65b72389135736c48194
Binary files /dev/null and b/Content/Examples/ContentExamples/Trigger/InteractionTechniqueSwapTrigger.uasset differ
diff --git a/Content/Examples/ContentExamples/Trigger/InteractionTechniquesEnum.uasset b/Content/Examples/ContentExamples/Trigger/InteractionTechniquesEnum.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..e190eb6cdc40f4fa0ebbac9e2df65010861d5175
Binary files /dev/null and b/Content/Examples/ContentExamples/Trigger/InteractionTechniquesEnum.uasset differ
diff --git a/Content/Examples/ContentExamples/Trigger/MovementTechniqueSwapTrigger.uasset b/Content/Examples/ContentExamples/Trigger/MovementTechniqueSwapTrigger.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..a556443085f9812425130d006a164d2794663286
Binary files /dev/null and b/Content/Examples/ContentExamples/Trigger/MovementTechniqueSwapTrigger.uasset differ
diff --git a/Content/Examples/ContentExamples/Widgets/BP_PawnSwapWidgetActor.uasset b/Content/Examples/ContentExamples/Widgets/BP_PawnSwapWidgetActor.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..7de08ef1c98e59cc7d62d4bc8164f8b8f7f0064b
Binary files /dev/null and b/Content/Examples/ContentExamples/Widgets/BP_PawnSwapWidgetActor.uasset differ
diff --git a/Content/Examples/ContentExamples/Widgets/BP_WidgetDemoActor.uasset b/Content/Examples/ContentExamples/Widgets/BP_WidgetDemoActor.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..c2b90dabd57345042b7eee882cac86c362263fcf
Binary files /dev/null and b/Content/Examples/ContentExamples/Widgets/BP_WidgetDemoActor.uasset differ
diff --git a/Content/Examples/ContentExamples/Widgets/ClickMeWidget.uasset b/Content/Examples/ContentExamples/Widgets/ClickMeWidget.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..768cccd381e6301ccf231ab4c65a0d58013bd091
Binary files /dev/null and b/Content/Examples/ContentExamples/Widgets/ClickMeWidget.uasset differ
diff --git a/Content/Examples/ContentExamples/Widgets/DemostationTextboxWidget.uasset b/Content/Examples/ContentExamples/Widgets/DemostationTextboxWidget.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..a7229820c76120bf8512efb6e80774ba9234b7b1
Binary files /dev/null and b/Content/Examples/ContentExamples/Widgets/DemostationTextboxWidget.uasset differ
diff --git a/Content/Examples/ContentExamples/Widgets/PawnSwapButtonWidget.uasset b/Content/Examples/ContentExamples/Widgets/PawnSwapButtonWidget.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..9cecb1a60ef49a050785e4a8be89b1cecb3f429c
Binary files /dev/null and b/Content/Examples/ContentExamples/Widgets/PawnSwapButtonWidget.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_1.uasset b/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_1.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..508ca517427740d74f5e596b0d9e378f48117c33
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_1.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_2.uasset b/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_2.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..420f7e315158df8ef6e4028acbced2bbb51d85ae
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_2.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_3.uasset b/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_3.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..47afecc29c1e3f62b491acc7854bfa1d50db0a8d
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_3.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_4.uasset b/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_4.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..84b8c18241ae1ee4ab4c3f54c6ff62d42d54f712
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_4.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_5.uasset b/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_5.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..671644137e556a38dedb290ab37af6441f07cadc
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Blueprints/BP_RE_1_5.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Blueprints/BP_loc_NoReplication.uasset b/Content/Examples/ReplicationExamples/Blueprints/BP_loc_NoReplication.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..bae3d13ba6cb9a74392e09be4164398703e14b26
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Blueprints/BP_loc_NoReplication.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Blueprints/BP_loc_replication.uasset b/Content/Examples/ReplicationExamples/Blueprints/BP_loc_replication.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..e9cd209b391355e3fb07d6f55955bfd40d56673f
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Blueprints/BP_loc_replication.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Blueprints/BP_locomotive.uasset b/Content/Examples/ReplicationExamples/Blueprints/BP_locomotive.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..2724d42266c4cb10acf64f9a487febc5690129eb
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Blueprints/BP_locomotive.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Models/BP_locomotiveAnimation.uasset b/Content/Examples/ReplicationExamples/Models/BP_locomotiveAnimation.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..ddcbf601baf38f4f0472d2783f3ab7627b00fc2e
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Models/BP_locomotiveAnimation.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Models/Face.uasset b/Content/Examples/ReplicationExamples/Models/Face.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..7598f465681158ca6a69a0f28bb0af32ce720374
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Models/Face.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Models/Light_Wood.uasset b/Content/Examples/ReplicationExamples/Models/Light_Wood.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..863feba2dc1a30b9b4b4561a2e15c9745611e1d6
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Models/Light_Wood.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Models/Wood.uasset b/Content/Examples/ReplicationExamples/Models/Wood.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..bee85f8a54443363e77fa93bc3d24032e10d1a49
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Models/Wood.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Models/locomotive.uasset b/Content/Examples/ReplicationExamples/Models/locomotive.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..4a95384c5a33996a5e154071353d894a529fcce1
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Models/locomotive.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Models/locomotive_Anim.uasset b/Content/Examples/ReplicationExamples/Models/locomotive_Anim.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..e86db372697b2d2055ba03add82b8c44a2df4f35
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Models/locomotive_Anim.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Models/locomotive_PhysicsAsset.uasset b/Content/Examples/ReplicationExamples/Models/locomotive_PhysicsAsset.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..ec5180e98b5356e1fa56e38aa923bbbf64b3bb57
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Models/locomotive_PhysicsAsset.uasset differ
diff --git a/Content/Examples/ReplicationExamples/Models/locomotive_Skeleton.uasset b/Content/Examples/ReplicationExamples/Models/locomotive_Skeleton.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..eb26f1c4e6417620c517b3c9eb8b9b6cb88552d0
Binary files /dev/null and b/Content/Examples/ReplicationExamples/Models/locomotive_Skeleton.uasset differ
diff --git a/Content/Examples/ReplicationExamples/ReplicationExamples.umap b/Content/Examples/ReplicationExamples/ReplicationExamples.umap
new file mode 100644
index 0000000000000000000000000000000000000000..a1efcfc296c7bad836afe5394bdd832ac53862e5
Binary files /dev/null and b/Content/Examples/ReplicationExamples/ReplicationExamples.umap differ
diff --git a/Content/Input/Default_IMC/IMC_General.uasset b/Content/Input/Default_IMC/IMC_General.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..cc0bd4ea6d18ace71a9ae2a0b53af84f42689540
Binary files /dev/null and b/Content/Input/Default_IMC/IMC_General.uasset differ
diff --git a/Content/Input/Default_IMC/IMC_MovementLeftHand.uasset b/Content/Input/Default_IMC/IMC_MovementLeftHand.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..1be9e555bfd0713434a650308d6892ad2e0b7204
Binary files /dev/null and b/Content/Input/Default_IMC/IMC_MovementLeftHand.uasset differ
diff --git a/Content/Input/Default_IMC/IMC_MovementRightHand.uasset b/Content/Input/Default_IMC/IMC_MovementRightHand.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..4b8151454c391850d9a45ed68fce7babc360c10d
Binary files /dev/null and b/Content/Input/Default_IMC/IMC_MovementRightHand.uasset differ
diff --git a/Content/IntenSelect/DebugConeMaterial.uasset b/Content/IntenSelect/DebugConeMaterial.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..c4dab0863455baa2871fbeb2c871fbe0cc8c7d7c
Binary files /dev/null and b/Content/IntenSelect/DebugConeMaterial.uasset differ
diff --git a/Content/IntenSelect/DebugConeMesh.uasset b/Content/IntenSelect/DebugConeMesh.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..d0980e3b7ff615b970f3cb6e664e21d95a5c8370
Binary files /dev/null and b/Content/IntenSelect/DebugConeMesh.uasset differ
diff --git a/Content/IntenSelect/ForwadRayMaterial.uasset b/Content/IntenSelect/ForwadRayMaterial.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..a7334c00a1eaffa105f0412bc5c3b64b5b93ed6a
Binary files /dev/null and b/Content/IntenSelect/ForwadRayMaterial.uasset differ
diff --git a/Content/IntenSelect/ForwardRayParams.uasset b/Content/IntenSelect/ForwardRayParams.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..e2d764f568116dd7cc570374e9dbe09fd938afb8
Binary files /dev/null and b/Content/IntenSelect/ForwardRayParams.uasset differ
diff --git a/Content/IntenSelect/ForwardRayTransparencyCurve.uasset b/Content/IntenSelect/ForwardRayTransparencyCurve.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..f81383ff048dbcce6f1f41662fdc3a80ac78203a
Binary files /dev/null and b/Content/IntenSelect/ForwardRayTransparencyCurve.uasset differ
diff --git a/Content/IntenSelect/IntenSelectClick.uasset b/Content/IntenSelect/IntenSelectClick.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..e14a0945ac964c604bd4ed0e0365e22142de84c3
Binary files /dev/null and b/Content/IntenSelect/IntenSelectClick.uasset differ
diff --git a/Content/IntenSelect/OnSelectHapticFeedback.uasset b/Content/IntenSelect/OnSelectHapticFeedback.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..92bc614b540e759df6542d31d31c82f88a71ca4d
Binary files /dev/null and b/Content/IntenSelect/OnSelectHapticFeedback.uasset differ
diff --git a/Content/IntenSelect/OnSelectSound.uasset b/Content/IntenSelect/OnSelectSound.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..333e1cbc75a8dbf2b55213abec17152aa0cc16bf
Binary files /dev/null and b/Content/IntenSelect/OnSelectSound.uasset differ
diff --git a/Content/IntenSelect/RayMesh.uasset b/Content/IntenSelect/RayMesh.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..fd84f10b97df7c4733e742fffc20818b1b2d48ae
Binary files /dev/null and b/Content/IntenSelect/RayMesh.uasset differ
diff --git a/Content/IntenSelect/SelectionSplineMaterial.uasset b/Content/IntenSelect/SelectionSplineMaterial.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..51304ee722baefa035343f1a9b6295ef47abc286
Binary files /dev/null and b/Content/IntenSelect/SelectionSplineMaterial.uasset differ
diff --git a/Content/IntenSelect/sectionedCubeMesh.uasset b/Content/IntenSelect/sectionedCubeMesh.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..536e047dcc5dad08d21ef951d97c71c4887e2b7d
Binary files /dev/null and b/Content/IntenSelect/sectionedCubeMesh.uasset differ
diff --git a/Content/Pawn/BP_RWTHVRPawn_Default.uasset b/Content/Pawn/BP_RWTHVRPawn_Default.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..6171681e8ed6e3a4eae1879d475dac62e33c4c99
Binary files /dev/null and b/Content/Pawn/BP_RWTHVRPawn_Default.uasset differ
diff --git a/Content/Pawn/Base/BP_RWTHVRPawn_Base.uasset b/Content/Pawn/Base/BP_RWTHVRPawn_Base.uasset
new file mode 100644
index 0000000000000000000000000000000000000000..591070e44ae18b1c035eba19b12492d94c47c7e2
Binary files /dev/null and b/Content/Pawn/Base/BP_RWTHVRPawn_Base.uasset differ
diff --git a/Content/PointingRay/Ray_Mesh.uasset b/Content/PointingRay/Ray_Mesh.uasset
index 0da58a602c186aa1ac8d65ba57d2d966a78419b5..e502ceb154ffeb022d651c033f6e0e6ed9b5fbe2 100644
Binary files a/Content/PointingRay/Ray_Mesh.uasset and b/Content/PointingRay/Ray_Mesh.uasset differ
diff --git a/Content/RWTHVRCluster/BP_CaveSetup.uasset b/Content/RWTHVRCluster/BP_CaveSetup.uasset
index dc92619dc5d235655269978d874ea8e79228b564..fd882f7f9f9860373421e60fafde5f5b0c03a0cb 100644
Binary files a/Content/RWTHVRCluster/BP_CaveSetup.uasset and b/Content/RWTHVRCluster/BP_CaveSetup.uasset differ
diff --git a/Content/RWTHVRCluster/CAVEOverlay/BP_CaveOverlay.uasset b/Content/RWTHVRCluster/CAVEOverlay/BP_CaveOverlay.uasset
index b98ef4a0d92337e6354a2b13a7b5fe78156bca8e..ab15ee9eb49fa5f0687da7bfff83330b505d4e03 100644
Binary files a/Content/RWTHVRCluster/CAVEOverlay/BP_CaveOverlay.uasset and b/Content/RWTHVRCluster/CAVEOverlay/BP_CaveOverlay.uasset differ
diff --git a/Content/RWTHVRCluster/CAVEOverlay/IMC_Overlay.uasset b/Content/RWTHVRCluster/CAVEOverlay/IMC_Overlay.uasset
deleted file mode 100644
index 23003cc697e730b961e3f32adad94eb1c46d8f37..0000000000000000000000000000000000000000
Binary files a/Content/RWTHVRCluster/CAVEOverlay/IMC_Overlay.uasset and /dev/null differ
diff --git a/Content/RWTHVRCluster/Config/aixcave_two_player.uasset b/Content/RWTHVRCluster/Config/aixcave_two_player.uasset
index ea7cec76836a5ad51207c5b39a5baaebac7a81d9..f55c6f86b133bd41711850009ee28765f435949c 100644
Binary files a/Content/RWTHVRCluster/Config/aixcave_two_player.uasset and b/Content/RWTHVRCluster/Config/aixcave_two_player.uasset differ
diff --git a/Content/TestMap.umap b/Content/TestMap.umap
deleted file mode 100644
index 7011da4b6ba3919d325f4cce30ec9330e77770df..0000000000000000000000000000000000000000
Binary files a/Content/TestMap.umap and /dev/null differ
diff --git a/Source/RWTHVRCluster/Private/CAVEOverlay/CAVEOverlayController.cpp b/Source/RWTHVRCluster/Private/CAVEOverlay/CAVEOverlayController.cpp
index 157e44d8a64c5d79b5aa6c8a0376838bc2c1842e..08d44b21a4e33283daa9a6a29b556beec0289cfa 100644
--- a/Source/RWTHVRCluster/Private/CAVEOverlay/CAVEOverlayController.cpp
+++ b/Source/RWTHVRCluster/Private/CAVEOverlay/CAVEOverlayController.cpp
@@ -2,7 +2,6 @@
 
 #include "CoreMinimal.h"
 #include "EnhancedInputComponent.h"
-#include "EnhancedInputSubsystems.h"
 #include "IDisplayCluster.h"
 #include "MotionControllerComponent.h"
 #include "Camera/CameraComponent.h"
@@ -165,7 +164,7 @@ void ACAVEOverlayController::BeginPlay()
 	// Input config
 	if (URWTHVRUtilities::IsPrimaryNode())
 	{
-		if (CycleDoorTypeInputAction == nullptr || IMCCaveOverlayInputMapping == nullptr)
+		if (CycleDoorTypeInputAction == nullptr)
 		{
 			UE_LOGFMT(LogCAVEOverlay, Error, "Input action and mapping not set in CaveOverlayController!");
 			return;
@@ -174,15 +173,6 @@ void ACAVEOverlayController::BeginPlay()
 		UEnhancedInputComponent* Input = Cast<UEnhancedInputComponent>(PC->InputComponent);
 		Input->BindAction(CycleDoorTypeInputAction, ETriggerEvent::Triggered, this,
 						  &ACAVEOverlayController::CycleDoorType);
-
-		if (const ULocalPlayer* LocalPlayer = PC->GetLocalPlayer())
-		{
-			if (UEnhancedInputLocalPlayerSubsystem* InputSystem =
-					LocalPlayer->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
-			{
-				InputSystem->AddMappingContext(IMCCaveOverlayInputMapping, 0);
-			}
-		}
 	}
 
 	// Bind the cluster events that manage the door state.
diff --git a/Source/RWTHVRCluster/Public/CAVEOverlay/CAVEOverlayController.h b/Source/RWTHVRCluster/Public/CAVEOverlay/CAVEOverlayController.h
index 234344221310b07fe6fe657468100cb4e4e11714..148897a8713c726bc9583de176cf04040b657074 100644
--- a/Source/RWTHVRCluster/Public/CAVEOverlay/CAVEOverlayController.h
+++ b/Source/RWTHVRCluster/Public/CAVEOverlay/CAVEOverlayController.h
@@ -128,9 +128,6 @@ public:
 	UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "CAVEOverlay")
 	UInputAction* CycleDoorTypeInputAction;
 
-	UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "CAVEOverlay")
-	UInputMappingContext* IMCCaveOverlayInputMapping;
-
 	UPROPERTY()
 	UDoorOverlayData* Overlay;
 
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactables/GrabBehavior.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactables/GrabBehavior.cpp
index 0ff95d0c6fc823faef1016badc7fb8330beb9679..1537243da0b6c92a901decadce793bc8bd819bbb 100644
--- a/Source/RWTHVRToolkit/Private/Interaction/Interactables/GrabBehavior.cpp
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactables/GrabBehavior.cpp
@@ -3,8 +3,9 @@
 
 #include "Interaction/Interactables/GrabBehavior.h"
 #include "Interaction/Interactables/InteractableComponent.h"
-#include "Kismet/GameplayStatics.h"
+#include "Logging/StructuredLog.h"
 #include "Serialization/JsonTypes.h"
+#include "Utility/RWTHVRUtilities.h"
 
 UPrimitiveComponent* UGrabBehavior::GetFirstComponentSimulatingPhysics(const AActor* TargetActor)
 {
@@ -29,34 +30,42 @@ UPrimitiveComponent* UGrabBehavior::GetHighestParentSimulatingPhysics(UPrimitive
 	{
 		return GetHighestParentSimulatingPhysics(Cast<UPrimitiveComponent>(Comp->GetAttachParent()));
 	}
-	else
-	{
-		return Comp;
-	}
+
+	return Comp;
 }
 
 void UGrabBehavior::OnActionStart(USceneComponent* TriggeredComponent, const UInputAction* InputAction,
 								  const FInputActionValue& Value)
 {
-	const APawn* Player = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
-
-	USceneComponent* Hand = Cast<USceneComponent>(TriggeredComponent->GetAttachParent());
+	if (bObjectGrabbed)
+	{
+		return;
+	}
 
+	USceneComponent* CurrentAttachParent = Cast<USceneComponent>(TriggeredComponent->GetAttachParent());
 	const FAttachmentTransformRules Rules = FAttachmentTransformRules(EAttachmentRule::KeepWorld, false);
 
-	MyPhysicsComponent = GetFirstComponentSimulatingPhysics(GetOwner());
-
-	if (MyPhysicsComponent)
+	if (MyPhysicsComponent = GetFirstComponentSimulatingPhysics(GetOwner()); MyPhysicsComponent != nullptr)
 	{
+		bWasSimulatingPhysics = MyPhysicsComponent->IsSimulatingPhysics();
 		MyPhysicsComponent->SetSimulatePhysics(false);
-		MyPhysicsComponent->AttachToComponent(Hand, Rules);
+		bObjectGrabbed = MyPhysicsComponent->AttachToComponent(CurrentAttachParent, Rules);
 	}
 	else
 	{
-		GetOwner()->GetRootComponent()->AttachToComponent(Hand, Rules);
+		bObjectGrabbed = GetOwner()->GetRootComponent()->AttachToComponent(CurrentAttachParent, Rules);
 	}
 
+	if (!bObjectGrabbed)
+	{
+		UE_LOGFMT(Toolkit, Warning, "Grab failed! Cannot attach grabbed component to attach parent ({Parent})",
+				  CurrentAttachParent->GetName());
+		return;
+	}
 
+	// If we want to restrict other interactions while this component is grabbed we add the component
+	// that triggered the interaction to the whitelist of all interactables that are attached to the
+	// affected actor
 	if (bBlockOtherInteractionsWhileGrabbed)
 	{
 		TArray<UInteractableComponent*> Interactables;
@@ -66,21 +75,28 @@ void UGrabBehavior::OnActionStart(USceneComponent* TriggeredComponent, const UIn
 			Interactable->RestrictInteractionToComponent(TriggeredComponent);
 		}
 	}
+
+	OnGrabStartEvent.Broadcast(CurrentAttachParent, MyPhysicsComponent);
 }
 
 void UGrabBehavior::OnActionEnd(USceneComponent* TriggeredComponent, const UInputAction* InputAction,
 								const FInputActionValue& Value)
 {
-	if (MyPhysicsComponent)
-	{
-		MyPhysicsComponent->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform);
-		MyPhysicsComponent->SetSimulatePhysics(true);
-	}
-	else
+
+	USceneComponent* CurrentAttachParent = Cast<USceneComponent>(TriggeredComponent->GetAttachParent());
+
+	// We try to release the attached component. If it is not succesful we log and return. Otherwise, we continue.
+	if (!TryRelease())
 	{
-		GetOwner()->GetRootComponent()->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform);
+		UE_LOGFMT(Toolkit, Display,
+				  "UGrabBehavior::OnActionEnd: TryRelease failed to release with AttachParent {Parent}",
+				  CurrentAttachParent->GetName());
+		return;
 	}
 
+	OnGrabEndEvent.Broadcast(CurrentAttachParent, MyPhysicsComponent);
+
+	// Release the interation restriction on all component
 	if (bBlockOtherInteractionsWhileGrabbed)
 	{
 		TArray<UInteractableComponent*> Interactables;
@@ -91,3 +107,23 @@ void UGrabBehavior::OnActionEnd(USceneComponent* TriggeredComponent, const UInpu
 		}
 	}
 }
+
+bool UGrabBehavior::TryRelease()
+{
+	if (!bObjectGrabbed)
+	{
+		return false;
+	}
+
+	if (MyPhysicsComponent)
+	{
+		MyPhysicsComponent->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform);
+		MyPhysicsComponent->SetSimulatePhysics(bWasSimulatingPhysics);
+	}
+	else
+	{
+		GetOwner()->GetRootComponent()->DetachFromComponent(FDetachmentTransformRules::KeepWorldTransform);
+	}
+	bObjectGrabbed = false;
+	return true;
+}
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectable.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectable.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3cd0e3d97f05cd11f45f107103511fa3ec28c48a
--- /dev/null
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectable.cpp
@@ -0,0 +1,116 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#include "Interaction/Interactables/IntenSelect/IntenSelectable.h"
+
+#include "Interaction/Interactables/IntenSelect/IntenSelectableScoring.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableSinglePointScoring.h"
+#include "Kismet/KismetSystemLibrary.h"
+#include "Misc/MessageDialog.h"
+#include "Pawn/IntenSelectComponent.h"
+
+UIntenSelectable::UIntenSelectable() { PrimaryComponentTick.bCanEverTick = true; }
+
+TPair<FHitResult, float> UIntenSelectable::GetBestPointScorePair(const FVector& ConeOrigin,
+																 const FVector& ConeForwardDirection,
+																 const float ConeBackwardShiftDistance,
+																 const float ConeAngle, const float LastValue,
+																 const float DeltaTime) const
+{
+	checkf(ScoringBehaviour, TEXT("%s"), *GetOwner()->GetName()) return ScoringBehaviour->GetBestPointScorePair(
+		ConeOrigin, ConeForwardDirection, ConeBackwardShiftDistance, ConeAngle, LastValue, DeltaTime);
+}
+
+void UIntenSelectable::HandleOnSelectStartEvents(const UIntenSelectComponent* IntenSelect, const FHitResult& HitResult)
+{
+	for (const UHoverBehaviour* b : OnSelectBehaviours)
+	{
+		b->OnHoverStartEvent.Broadcast(IntenSelect, HitResult);
+	}
+}
+
+void UIntenSelectable::HandleOnSelectEndEvents(const UIntenSelectComponent* IntenSelect)
+{
+	for (const UHoverBehaviour* b : OnSelectBehaviours)
+	{
+		b->OnHoverEndEvent.Broadcast(IntenSelect);
+	}
+}
+
+void UIntenSelectable::HandleOnClickStartEvents(UIntenSelectComponent* IntenSelect)
+{
+	for (const UActionBehaviour* b : OnClickBehaviours)
+	{
+		FInputActionValue v{};
+		const UInputAction* a{};
+		b->OnActionBeginEvent.Broadcast(IntenSelect, a, v);
+	}
+}
+
+void UIntenSelectable::HandleOnClickEndEvents(UIntenSelectComponent* IntenSelect, FInputActionValue& InputValue)
+{
+	for (const UActionBehaviour* b : OnClickBehaviours)
+	{
+		const UInputAction* a{};
+		b->OnActionEndEvent.Broadcast(IntenSelect, a, InputValue);
+	}
+}
+
+void UIntenSelectable::InitDefaultBehaviourReferences()
+{
+	// Scoring
+	if (UIntenSelectableScoring* AttachedScoring =
+			Cast<UIntenSelectableScoring>(GetOwner()->GetComponentByClass(UIntenSelectableScoring::StaticClass())))
+	{
+		ScoringBehaviour = AttachedScoring;
+	}
+	else
+	{
+		ScoringBehaviour = NewObject<UIntenSelectableSinglePointScoring>(
+			this, UIntenSelectableSinglePointScoring::StaticClass(), "Default Scoring");
+		ScoringBehaviour->SetWorldLocation(GetOwner()->GetActorLocation());
+		ScoringBehaviour->AttachToComponent(GetOwner()->GetRootComponent(),
+											FAttachmentTransformRules::SnapToTargetNotIncludingScale);
+	}
+
+	// Selecting
+	TInlineComponentArray<UHoverBehaviour*> AttachedSelectionBehaviours;
+	GetOwner()->GetComponents(AttachedSelectionBehaviours, true);
+
+	this->OnSelectBehaviours = AttachedSelectionBehaviours;
+
+	// Clicking
+	TInlineComponentArray<UActionBehaviour*> AttachedClickBehaviours;
+	GetOwner()->GetComponents(AttachedClickBehaviours, true);
+
+	this->OnClickBehaviours = AttachedClickBehaviours;
+}
+
+void UIntenSelectable::ShowErrorAndQuit(const FString& Message) const
+{
+	UE_LOG(LogTemp, Error, TEXT("%s"), *Message)
+#if WITH_EDITOR
+	FMessageDialog::Open(EAppMsgType::Ok, FText::FromString(FString("RUNTIME ERROR")));
+#endif
+	UKismetSystemLibrary::QuitGame(this, nullptr, EQuitPreference::Quit, false);
+}
+
+void UIntenSelectable::BeginPlay()
+{
+	Super::BeginPlay();
+
+	TInlineComponentArray<UIntenSelectable*> AttachedIntenSelectables;
+	GetOwner()->GetComponents(AttachedIntenSelectables, false);
+
+	if (AttachedIntenSelectables.Num() > 1)
+	{
+		if (!ScoringBehaviour)
+		{
+			ShowErrorAndQuit(
+				"Please assign the Scoring Behaviour manually when using more than one IntenSelectable Component!");
+		}
+	}
+	else
+	{
+		InitDefaultBehaviourReferences();
+	}
+}
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableCircleScoring.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableCircleScoring.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c323f50d1148d8ecb4fc45930a9ca0f00775c69f
--- /dev/null
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableCircleScoring.cpp
@@ -0,0 +1,66 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#include "Interaction/Interactables/IntenSelect/IntenSelectableCircleScoring.h"
+
+#include "DrawDebugHelpers.h"
+#include "Kismet/KismetMathLibrary.h"
+
+// Sets default values for this component's properties
+UIntenSelectableCircleScoring::UIntenSelectableCircleScoring() { PrimaryComponentTick.bCanEverTick = true; }
+
+TPair<FHitResult, float>
+UIntenSelectableCircleScoring::GetBestPointScorePair(const FVector& ConeOrigin, const FVector& ConeForwardDirection,
+													 const float ConeBackwardShiftDistance, const float ConeAngle,
+													 const float LastValue, const float DeltaTime)
+{
+	const FVector Point = GetClosestSelectionPointTo(ConeOrigin, ConeForwardDirection);
+	float Score =
+		GetScore(ConeOrigin, ConeForwardDirection, ConeBackwardShiftDistance, ConeAngle, Point, LastValue, DeltaTime);
+	FHitResult Result = FHitResult{GetOwner(), nullptr, Point, FVector::ForwardVector};
+	return TPair<FHitResult, float>{Result, Score};
+}
+
+FVector UIntenSelectableCircleScoring::GetClosestSelectionPointTo(const FVector& Point, const FVector& Direction) const
+{
+	const FVector CenterWorld = this->GetComponentLocation();
+	const FVector CircleNormalWorld =
+		this->GetComponentTransform().TransformPositionNoScale(FVector::ForwardVector) - CenterWorld;
+
+	float t;
+	FVector Intersect;
+	if (!UKismetMathLibrary::LinePlaneIntersection_OriginNormal(Point, Point + Direction * 100000, CenterWorld,
+																CircleNormalWorld, t, Intersect))
+	{
+		return CenterWorld;
+	}
+
+	const FVector CenterToPoint = Intersect - CenterWorld;
+
+	FVector Result;
+	if (OnlyOutline)
+	{
+		Result = (CenterToPoint.GetSafeNormal() * Radius) + CenterWorld;
+	}
+	else
+	{
+		const float DistanceToCenter = CenterToPoint.Size();
+
+		if (DistanceToCenter >= Radius)
+		{
+			Result = (CenterToPoint.GetSafeNormal() * Radius) + CenterWorld;
+		}
+		else
+		{
+			Result = Intersect;
+		}
+	}
+
+	FVector Y = CenterToPoint.GetSafeNormal();
+	FVector Z = FVector::CrossProduct(Y, CircleNormalWorld.GetSafeNormal());
+
+	// Y = FVector(0, 0, 1);
+	// Z = FVector(1, 0, 0);
+	DrawDebugCircle(GetWorld(), CenterWorld, Radius, 80, FColor::Green, false, -1, 0, 1, Y, Z, false);
+
+	return Result;
+}
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableCubeScoring.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableCubeScoring.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f7e8f98116514adc45b63c2b81fa7a66acb95905
--- /dev/null
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableCubeScoring.cpp
@@ -0,0 +1,353 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#include "Interaction/Interactables/IntenSelect/IntenSelectableCubeScoring.h"
+
+#include "DrawDebugHelpers.h"
+#include "Intersection/IntrRay3AxisAlignedBox3.h"
+#include "Kismet/KismetMathLibrary.h"
+
+// Sets default values for this component's properties
+UIntenSelectableCubeScoring::UIntenSelectableCubeScoring()
+{
+	PrimaryComponentTick.bCanEverTick = true;
+	SetRelativeScale3D(FVector::One() * 100);
+}
+
+TPair<FHitResult, float>
+UIntenSelectableCubeScoring::GetBestPointScorePair(const FVector& ConeOrigin, const FVector& ConeForwardDirection,
+												   const float ConeBackwardShiftDistance, const float ConeAngle,
+												   const float LastValue, const float DeltaTime)
+{
+	FVector Point = GetClosestSelectionPointTo(ConeOrigin, ConeForwardDirection);
+	float Score = Super::GetScore(ConeOrigin, ConeForwardDirection, ConeBackwardShiftDistance, ConeAngle, Point,
+								  LastValue, DeltaTime);
+	FHitResult Result = FHitResult{GetOwner(), nullptr, Point, FVector::ForwardVector};
+	return TPair<FHitResult, float>{Result, Score};
+}
+
+FVector UIntenSelectableCubeScoring::GetClosestPointToRectangle(const FVector& StartPoint, const FVector& Direction,
+																const FVector& Corner00, const FVector& Corner01,
+																const FVector& Corner10, const FVector& Corner11) const
+{
+	const float X = FVector::Distance(Corner00, Corner10);
+	const float Y = FVector::Distance(Corner00, Corner01);
+	const FVector PlaneNormal = FVector::CrossProduct(Corner10 - Corner00, Corner01 - Corner00).GetSafeNormal();
+
+	FVector Intersection;
+	float T;
+	UKismetMathLibrary::LinePlaneIntersection_OriginNormal(StartPoint, StartPoint + Direction * 10000, Corner00,
+														   PlaneNormal, T, Intersection);
+
+	FVector LocalIntersection = this->GetComponentTransform().InverseTransformPosition(Intersection);
+
+	if (LocalIntersection.Y > X / 2)
+	{
+		LocalIntersection.Y = X / 2;
+	}
+	else if (LocalIntersection.Y < -X / 2)
+	{
+		LocalIntersection.Y = -X / 2;
+	}
+
+	if (LocalIntersection.Z > Y / 2)
+	{
+		LocalIntersection.Z = Y / 2;
+	}
+	else if (LocalIntersection.Z < -Y / 2)
+	{
+		LocalIntersection.Z = -Y / 2;
+	}
+
+	/*
+	if(OnlyOutline)
+	{
+		const float DistToBottom = LocalIntersection.Z + (YLength / 2);
+		const float DistToLeft = LocalIntersection.Y + (XLength / 2);
+
+		if(LocalIntersection.Z < 0)
+		{
+			if(LocalIntersection.Y < 0)
+			{
+				//Bottom and left
+				if(DistToLeft < DistToBottom)
+				{
+					//snap left
+					LocalIntersection.Y = -(XLength / 2);
+				}else
+				{
+					//snap bottom
+					LocalIntersection.Z = -(YLength / 2);
+				}
+			}else
+			{
+				//bottom and right
+				if(XLength - DistToLeft < DistToBottom)
+				{
+					//snap right
+					LocalIntersection.Y = XLength / 2;
+				}else
+				{
+					//snap bottom
+					LocalIntersection.Z = -(YLength / 2);
+				}
+			}
+		}else
+		{
+			if(LocalIntersection.Y < 0)
+			{
+				//top and left
+				if(DistToLeft < YLength - DistToBottom)
+				{
+					//snap left
+					LocalIntersection.Y = -(XLength / 2);
+				}else
+				{
+					//snap top
+					LocalIntersection.Z = (YLength / 2);
+				}
+			}else
+			{
+				//top and right
+				if(XLength - DistToLeft < YLength - DistToBottom)
+				{
+					//snap right
+					LocalIntersection.Y = XLength / 2;
+				}else
+				{
+					//snap top
+					LocalIntersection.Z = (YLength / 2);
+				}
+			}
+		}
+	}
+*/
+
+	return this->GetComponentTransform().TransformPosition(LocalIntersection);
+}
+
+bool UIntenSelectableCubeScoring::LineToLineIntersection(const FVector& FromA, const FVector& FromB, const FVector& ToA,
+														 const FVector& ToB, FVector& OutIntersection)
+{
+	const FVector Da = ToA - FromA;
+	const FVector DB = ToB - FromB;
+	const FVector DC = FromB - FromA;
+
+	const FVector CrossDaDb = FVector::CrossProduct(Da, DB);
+	const float Prod = CrossDaDb.X * CrossDaDb.X + CrossDaDb.Y * CrossDaDb.Y + CrossDaDb.Z * CrossDaDb.Z;
+
+	const float Res = FVector::DotProduct(FVector::CrossProduct(DC, DB), FVector::CrossProduct(Da, DB) / Prod);
+	if (Res >= -0.02f && Res <= 1.02f)
+	{
+		OutIntersection = FromA + Da * FVector(Res, Res, Res);
+		return true;
+	}
+
+	return false;
+}
+
+FVector UIntenSelectableCubeScoring::GetClosestSelectionPointTo(const FVector& RayOrigin, const FVector& RayDirection)
+{
+	auto Scale = GetRelativeTransform().GetScale3D();
+	const FVector X = this->GetForwardVector() * Scale.X;
+	const FVector Y = this->GetRightVector() * Scale.Y;
+	const FVector Z = this->GetUpVector() * Scale.Z;
+
+	TArray<FPlane> CubeSides;
+
+	// bottom
+	const FVector BottomWorld = this->GetComponentTransform().TransformPositionNoScale(-Z / 2);
+	CubeSides.Add(FPlane{BottomWorld, -this->GetUpVector()});
+
+	// top
+	const FVector TopWorld = this->GetComponentTransform().TransformPositionNoScale(Z / 2);
+	CubeSides.Add(FPlane{TopWorld, this->GetUpVector()});
+
+	// left
+	const FVector LeftWorld = this->GetComponentTransform().TransformPositionNoScale(-Y / 2);
+	CubeSides.Add(FPlane{LeftWorld, -this->GetRightVector()});
+
+	// right
+	const FVector RightWorld = this->GetComponentTransform().TransformPositionNoScale(Y / 2);
+	CubeSides.Add(FPlane{RightWorld, this->GetRightVector()});
+
+	// front
+	const FVector FrontWorld = this->GetComponentTransform().TransformPositionNoScale(-X / 2);
+	CubeSides.Add(FPlane{FrontWorld, -this->GetForwardVector()});
+
+	// back
+	const FVector BackWorld = this->GetComponentTransform().TransformPositionNoScale(X / 2);
+	CubeSides.Add(FPlane{BackWorld, this->GetForwardVector()});
+
+	/*
+	const TRay3<float> Ray{Point, Direction, false};
+	const TAxisAlignedBox3<float> Box;
+	float OutT;
+	if(TIntrRay3AxisAlignedBox3<float>::FindIntersection(Ray, Box, OutT))
+	{
+
+	}*/
+
+	float MinDistance = TNumericLimits<float>::Max();
+	FVector ClosestPoint = GetComponentLocation();
+	bool IsSet = false;
+	for (FPlane Plane : CubeSides)
+	{
+		const FVector PlaneToRayOrigin = RayOrigin - Plane.GetOrigin();
+		if (FVector::DotProduct(PlaneToRayOrigin.GetSafeNormal(), Plane.GetNormal()) < 0 && BackFaceCulling)
+		{
+			if (DrawDebug)
+			{
+				DrawDebugSolidPlane(GetWorld(), Plane, GetComponentLocation(), 20, FColor::Red.WithAlpha(9), false, -1,
+									0);
+			}
+			continue;
+		}
+		else
+		{
+			if (DrawDebug)
+			{
+				DrawDebugSolidPlane(GetWorld(), Plane, GetComponentLocation(), 20, FColor::Green.WithAlpha(9), false,
+									-1, 0);
+			}
+		}
+
+
+		FVector CurrentPoint = FMath::RayPlaneIntersection(RayOrigin, RayDirection, Plane);
+		FVector CurrentPointLocal = GetComponentTransform().InverseTransformPositionNoScale(CurrentPoint);
+
+		Scale = GetRelativeTransform().GetScale3D();
+		CurrentPointLocal.X = FMath::Clamp(CurrentPointLocal.X, -Scale.X / 2, Scale.X / 2);
+		CurrentPointLocal.Y = FMath::Clamp(CurrentPointLocal.Y, -Scale.Y / 2, Scale.Y / 2);
+		CurrentPointLocal.Z = FMath::Clamp(CurrentPointLocal.Z, -Scale.Z / 2, Scale.Z / 2);
+
+		if (OnlyOutline)
+		{
+			const float XSnapDist = (Scale.X / 2) - FMath::Abs(CurrentPointLocal.X);
+			const float YSnapDist = (Scale.Y / 2) - FMath::Abs(CurrentPointLocal.Y);
+			const float ZSnapDist = (Scale.Z / 2) - FMath::Abs(CurrentPointLocal.Z);
+
+			bool SnapX = true;
+			bool SnapY = true;
+			bool SnapZ = true;
+
+			if (FVector::Parallel(Plane.GetNormal(), GetRightVector()))
+			{
+				if (XSnapDist < ZSnapDist)
+				{
+					SnapZ = false;
+				}
+				else
+				{
+					SnapX = false;
+				}
+			}
+			else if (FVector::Parallel(Plane.GetNormal(), GetUpVector()))
+			{
+				if (XSnapDist < YSnapDist)
+				{
+					SnapY = false;
+				}
+				else
+				{
+					SnapX = false;
+				}
+			}
+			else if (FVector::Parallel(Plane.GetNormal(), GetForwardVector()))
+			{
+				if (YSnapDist < ZSnapDist)
+				{
+					SnapZ = false;
+				}
+				else
+				{
+					SnapY = false;
+				}
+			}
+
+
+			if (SnapX)
+			{
+				if (CurrentPointLocal.X > 0)
+				{
+					CurrentPointLocal.X = Scale.X / 2;
+				}
+				else
+				{
+					CurrentPointLocal.X = -Scale.X / 2;
+				}
+			}
+			if (SnapY)
+			{
+				if (CurrentPointLocal.Y > 0)
+				{
+					CurrentPointLocal.Y = Scale.Y / 2;
+				}
+				else
+				{
+					CurrentPointLocal.Y = -Scale.Y / 2;
+				}
+			}
+			if (SnapZ)
+			{
+				if (CurrentPointLocal.Z > 0)
+				{
+					CurrentPointLocal.Z = Scale.Z / 2;
+				}
+				else
+				{
+					CurrentPointLocal.Z = -Scale.Z / 2;
+				}
+			}
+		}
+
+		CurrentPoint = GetComponentTransform().TransformPositionNoScale(CurrentPointLocal);
+
+		const float Distance = FMath::PointDistToLine(CurrentPoint, RayDirection, RayOrigin);
+
+		// DrawDebugPoint(GetWorld(), CurrentPoint, 10, FColor::Black.WithAlpha(1), false, -1, 0);
+		// GEngine->AddOnScreenDebugMessage(INDEX_NONE, -1, FColor::Red, FString::SanitizeFloat(Distance));
+
+		if (Distance < 0.001)
+		{
+			if (MinDistance < 0.001)
+			{
+				const float DistToPlayerOld =
+					IsSet ? FVector::Distance(RayOrigin, ClosestPoint) : TNumericLimits<float>::Max();
+				const float DistToPlayerNew = FVector::Distance(RayOrigin, CurrentPoint);
+
+				if (DistToPlayerNew < DistToPlayerOld)
+				{
+					MinDistance = Distance;
+					ClosestPoint = CurrentPoint;
+					IsSet = true;
+				}
+			}
+			else
+			{
+				MinDistance = Distance;
+				ClosestPoint = CurrentPoint;
+				IsSet = true;
+			}
+		}
+		else
+		{
+			if (Distance < MinDistance)
+			{
+				MinDistance = Distance;
+				ClosestPoint = CurrentPoint;
+				IsSet = true;
+			}
+		}
+	}
+
+	if (DrawDebug)
+		DrawDebugBox(GetWorld(), GetComponentLocation(), FVector(Scale.X, Scale.Y, Scale.Z) / 2,
+					 GetComponentRotation().Quaternion(), FColor::Green, false, -1, 0, 2);
+	return ClosestPoint;
+}
+
+void UIntenSelectableCubeScoring::TickComponent(float DeltaTime, ELevelTick TickType,
+												FActorComponentTickFunction* ThisTickFunction)
+{
+	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
+}
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableCylinderScoring.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableCylinderScoring.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b4b08696f52712b1ed9dbcc688fda9787c75152c
--- /dev/null
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableCylinderScoring.cpp
@@ -0,0 +1,110 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+
+#include "Interaction/Interactables/IntenSelect/IntenSelectableCylinderScoring.h"
+
+#include "DrawDebugHelpers.h"
+#include "Kismet/KismetMathLibrary.h"
+
+// Sets default values for this component's properties
+UIntenSelectableCylinderScoring::UIntenSelectableCylinderScoring() { PrimaryComponentTick.bCanEverTick = true; }
+
+TPair<FHitResult, float>
+UIntenSelectableCylinderScoring::GetBestPointScorePair(const FVector& ConeOrigin, const FVector& ConeForwardDirection,
+													   const float ConeBackwardShiftDistance, const float ConeAngle,
+													   const float LastValue, const float DeltaTime)
+{
+	FVector Point = GetClosestSelectionPointTo(ConeOrigin, ConeForwardDirection);
+	float Score =
+		GetScore(ConeOrigin, ConeForwardDirection, ConeBackwardShiftDistance, ConeAngle, Point, LastValue, DeltaTime);
+	FHitResult Result = FHitResult{GetOwner(), nullptr, Point, FVector::ForwardVector};
+	return TPair<FHitResult, float>{Result, Score};
+}
+
+bool UIntenSelectableCylinderScoring::LineToLineIntersection(const FVector& FromA, const FVector& FromB,
+															 const FVector& ToA, const FVector& ToB,
+															 FVector& OutIntersection)
+{
+	const FVector Da = ToA - FromA;
+	const FVector DB = ToB - FromB;
+	const FVector DC = FromB - FromA;
+
+	const FVector CrossDaDb = FVector::CrossProduct(Da, DB);
+	const float Prod = CrossDaDb.X * CrossDaDb.X + CrossDaDb.Y * CrossDaDb.Y + CrossDaDb.Z * CrossDaDb.Z;
+
+	const float Res = FVector::DotProduct(FVector::CrossProduct(DC, DB), FVector::CrossProduct(Da, DB) / Prod);
+	if (Res >= -0.02f && Res <= 1.02f)
+	{
+		OutIntersection = FromA + Da * FVector(Res, Res, Res);
+		return true;
+	}
+
+	return false;
+}
+
+FVector UIntenSelectableCylinderScoring::GetClosestSelectionPointTo(const FVector& Point,
+																	const FVector& Direction) const
+{
+	const FVector CylinderStartWorld = this->GetComponentTransform().TransformPosition(LinePoints[0]);
+	const FVector CylinderEndWorld = this->GetComponentTransform().TransformPosition(LinePoints[1]);
+	const FVector CylinderDir = CylinderEndWorld - CylinderStartWorld;
+
+	const FVector CrossProd = UKismetMathLibrary::Cross_VectorVector(CylinderDir, Direction); // v
+	const FVector LineDifference = CylinderStartWorld - Point; // u
+
+	// Project v onto u =>
+	const FVector Proj = LineDifference.ProjectOnTo(CrossProd);
+	const float ProjLength = Proj.Size();
+
+	const FVector OffsetPoint = Point + Proj;
+
+	const FVector FromA = OffsetPoint;
+	const FVector FromB = CylinderStartWorld;
+	const FVector ToA = OffsetPoint + Direction * 10000;
+	const FVector ToB = CylinderEndWorld;
+	FVector Result;
+	LineToLineIntersection(FromA, FromB, ToA, ToB, Result);
+
+	const FVector LineDirRes = Result - CylinderStartWorld;
+
+	if (LineDirRes.Size() > CylinderDir.Size())
+	{
+		Result = CylinderEndWorld;
+	}
+
+	if (!LineDirRes.GetSafeNormal().Equals(CylinderDir.GetSafeNormal()))
+	{
+		Result = CylinderStartWorld;
+	}
+
+	const FVector ToSphere = Result - Point;
+	const FVector Projection = ToSphere.ProjectOnTo(Direction);
+	const FVector ProjectionToSphere = ToSphere - Projection;
+
+	if (ProjLength >= Radius)
+	{
+		FVector ShiftResult = ProjectionToSphere.GetSafeNormal() * Radius;
+		ShiftResult -= ShiftResult.ProjectOnTo(CylinderDir);
+		return Result - ShiftResult;
+	}
+	else
+	{
+		FVector ShiftResult = ProjectionToSphere.GetSafeNormal() * ProjLength;
+		ShiftResult -= ShiftResult.ProjectOnTo(CylinderDir);
+		return Result - ShiftResult;
+	}
+}
+
+void UIntenSelectableCylinderScoring::TickComponent(float DeltaTime, ELevelTick TickType,
+													FActorComponentTickFunction* ThisTickFunction)
+{
+	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
+
+	if (DrawDebug)
+	{
+		const FVector StartWorld = this->GetComponentTransform().TransformPosition(LinePoints[0]);
+		const FVector EndWorld = this->GetComponentTransform().TransformPosition(LinePoints[1]);
+
+		DrawDebugCylinder(GetWorld(), StartWorld, EndWorld, Radius, 20, FColor::Green, false, 0, 0, 2);
+	}
+}
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableLineScoring.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableLineScoring.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..be4cdd9065f3b92f6d640fc78d3c65afa144bcc7
--- /dev/null
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableLineScoring.cpp
@@ -0,0 +1,101 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#include "Interaction/Interactables/IntenSelect/IntenSelectableLineScoring.h"
+
+#include "DrawDebugHelpers.h"
+#include "Kismet/KismetMathLibrary.h"
+
+// Sets default values for this component's properties
+UIntenSelectableLineScoring::UIntenSelectableLineScoring()
+{
+	PrimaryComponentTick.bCanEverTick = true;
+	if (this->LinePoints.Num() == 2)
+	{
+		const FVector Average = (this->LinePoints[0] + this->LinePoints[1]) / 2;
+
+		this->SetWorldLocation(this->GetComponentTransform().TransformPositionNoScale(Average));
+		this->LinePoints[0] -= Average;
+		this->LinePoints[1] -= Average;
+	}
+}
+
+TPair<FHitResult, float>
+UIntenSelectableLineScoring::GetBestPointScorePair(const FVector& ConeOrigin, const FVector& ConeForwardDirection,
+												   const float ConeBackwardShiftDistance, const float ConeAngle,
+												   const float LastValue, const float DeltaTime)
+{
+	FVector Point = GetClosestSelectionPointTo(ConeOrigin, ConeForwardDirection);
+	float Score =
+		GetScore(ConeOrigin, ConeForwardDirection, ConeBackwardShiftDistance, ConeAngle, Point, LastValue, DeltaTime);
+	FHitResult Result = FHitResult{GetOwner(), nullptr, Point, FVector::ForwardVector};
+	return TPair<FHitResult, float>{Result, Score};
+}
+
+bool UIntenSelectableLineScoring::LineToLineIntersection(const FVector& FromA, const FVector& FromB, const FVector& ToA,
+														 const FVector& ToB, FVector& OutIntersection)
+{
+	const FVector Da = ToA - FromA;
+	const FVector DB = ToB - FromB;
+	const FVector DC = FromB - FromA;
+
+	const FVector CrossDaDb = FVector::CrossProduct(Da, DB);
+	const float Prod = CrossDaDb.X * CrossDaDb.X + CrossDaDb.Y * CrossDaDb.Y + CrossDaDb.Z * CrossDaDb.Z;
+
+	const float Res = FVector::DotProduct(FVector::CrossProduct(DC, DB), FVector::CrossProduct(Da, DB) / Prod);
+	if (Res >= -0.02f && Res <= 1.02f)
+	{
+		OutIntersection = FromA + Da * FVector(Res, Res, Res);
+		return true;
+	}
+
+	return false;
+}
+
+FVector UIntenSelectableLineScoring::GetClosestSelectionPointTo(const FVector& Point, const FVector& Direction) const
+{
+	const FVector StartWorld = this->GetComponentTransform().TransformPosition(LinePoints[0]);
+	const FVector EndWorld = this->GetComponentTransform().TransformPosition(LinePoints[1]);
+	const FVector LineDir = EndWorld - StartWorld;
+
+
+	const FVector CrossProd = UKismetMathLibrary::Cross_VectorVector(LineDir, Direction); // v
+	const FVector LineDifference = StartWorld - Point; // u
+
+	// Project v onto u =>
+	const FVector Proj = LineDifference.ProjectOnTo(CrossProd);
+
+	const FVector OffsetPoint = Point + Proj;
+
+	const FVector FromA = OffsetPoint;
+	const FVector FromB = StartWorld;
+	const FVector ToA = OffsetPoint + Direction * 10000;
+	const FVector ToB = EndWorld;
+	FVector Result;
+	LineToLineIntersection(FromA, FromB, ToA, ToB, Result);
+
+	const FVector LineDirRes = Result - StartWorld;
+	if (LineDirRes.Size() > LineDir.Size())
+	{
+		Result = EndWorld;
+	}
+
+	if (!LineDirRes.GetSafeNormal().Equals(LineDir.GetSafeNormal()))
+	{
+		Result = StartWorld;
+	}
+
+	return Result;
+}
+
+void UIntenSelectableLineScoring::TickComponent(float DeltaTime, ELevelTick TickType,
+												FActorComponentTickFunction* ThisTickFunction)
+{
+	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
+
+	if (DrawDebug)
+	{
+		const FVector StartWorld = this->GetComponentTransform().TransformPosition(LinePoints[0]);
+		const FVector EndWorld = this->GetComponentTransform().TransformPosition(LinePoints[1]);
+		DrawDebugLine(GetWorld(), StartWorld, EndWorld, FColor::Green, false, -1, 0, 2);
+	}
+}
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableMultiPointScoring.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableMultiPointScoring.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..03b04e32b549450947e0d663c4a5757e1ced9b76
--- /dev/null
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableMultiPointScoring.cpp
@@ -0,0 +1,52 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#include "Interaction/Interactables/IntenSelect/IntenSelectableMultiPointScoring.h"
+
+#include "Kismet/KismetMathLibrary.h"
+#include "Net/Core/PushModel/PushModel.h"
+
+// Sets default values for this component's properties
+UIntenSelectableMultiPointScoring::UIntenSelectableMultiPointScoring()
+{
+	PrimaryComponentTick.bCanEverTick = true;
+	PointsToSelect = TArray<FVector>{FVector::UpVector * 100, FVector::DownVector * 100, FVector::RightVector * 100,
+									 FVector::LeftVector * 100};
+}
+
+TPair<FHitResult, float>
+UIntenSelectableMultiPointScoring::GetBestPointScorePair(const FVector& ConeOrigin, const FVector& ConeForwardDirection,
+														 const float ConeBackwardShiftDistance, const float ConeAngle,
+														 const float LastValue, const float DeltaTime)
+{
+	FVector Point = GetClosestSelectionPointTo(ConeOrigin, ConeForwardDirection);
+	float Score = Super::GetScore(ConeOrigin, ConeForwardDirection, ConeBackwardShiftDistance, ConeAngle, Point,
+								  LastValue, DeltaTime);
+	FHitResult Result = FHitResult{GetOwner(), nullptr, Point, FVector::ForwardVector};
+	return TPair<FHitResult, float>{Result, Score};
+}
+
+void UIntenSelectableMultiPointScoring::UpdatePoints() {}
+
+FVector UIntenSelectableMultiPointScoring::GetClosestSelectionPointTo(const FVector& Point,
+																	  const FVector& Direction) const
+{
+	if (PointsToSelect.Num() == 0)
+	{
+		return this->GetComponentLocation();
+	}
+
+	FVector ClosestPoint = this->GetComponentTransform().TransformPositionNoScale(PointsToSelect[0]);
+	float MinDistance = UKismetMathLibrary::GetPointDistanceToLine(ClosestPoint, Point, Direction);
+
+	for (const FVector P : PointsToSelect)
+	{
+		const FVector PointToCheck = this->GetComponentTransform().TransformPositionNoScale(P);
+		const float Dist = UKismetMathLibrary::GetPointDistanceToLine(PointToCheck, Point, Direction);
+		if (Dist < MinDistance)
+		{
+			MinDistance = Dist;
+			ClosestPoint = PointToCheck;
+		}
+	}
+	return ClosestPoint;
+}
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableRectangleScoring.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableRectangleScoring.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..62737f8d1b07af27317ade5a57fd58a25eb0d92b
--- /dev/null
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableRectangleScoring.cpp
@@ -0,0 +1,177 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#include "Interaction/Interactables/IntenSelect/IntenSelectableRectangleScoring.h"
+
+#include "DrawDebugHelpers.h"
+#include "Kismet/KismetMathLibrary.h"
+
+// Sets default values for this component's properties
+UIntenSelectableRectangleScoring::UIntenSelectableRectangleScoring() { PrimaryComponentTick.bCanEverTick = true; }
+
+TPair<FHitResult, float>
+UIntenSelectableRectangleScoring::GetBestPointScorePair(const FVector& ConeOrigin, const FVector& ConeForwardDirection,
+														const float ConeBackwardShiftDistance, const float ConeAngle,
+														const float LastValue, const float DeltaTime)
+{
+	FVector Point = GetClosestSelectionPointTo(ConeOrigin, ConeForwardDirection);
+	float Score = Super::GetScore(ConeOrigin, ConeForwardDirection, ConeBackwardShiftDistance, ConeAngle, Point,
+								  LastValue, DeltaTime);
+	FHitResult Result = FHitResult{GetOwner(), nullptr, Point, FVector::ForwardVector};
+	return TPair<FHitResult, float>{Result, Score};
+}
+
+bool UIntenSelectableRectangleScoring::LineToLineIntersection(const FVector& FromA, const FVector& FromB,
+															  const FVector& ToA, const FVector& ToB,
+															  FVector& OutIntersection)
+{
+	const FVector Da = ToA - FromA;
+	const FVector DB = ToB - FromB;
+	const FVector DC = FromB - FromA;
+
+	const FVector CrossDaDb = FVector::CrossProduct(Da, DB);
+	const float Prod = CrossDaDb.X * CrossDaDb.X + CrossDaDb.Y * CrossDaDb.Y + CrossDaDb.Z * CrossDaDb.Z;
+
+	const float Res = FVector::DotProduct(FVector::CrossProduct(DC, DB), FVector::CrossProduct(Da, DB) / Prod);
+	if (Res >= -0.02f && Res <= 1.02f)
+	{
+		OutIntersection = FromA + Da * FVector(Res, Res, Res);
+		return true;
+	}
+
+	return false;
+}
+
+FVector UIntenSelectableRectangleScoring::GetClosestSelectionPointTo(const FVector& Point,
+																	 const FVector& Direction) const
+{
+	const FVector X = this->GetRightVector() * XLength;
+	const FVector Y = this->GetUpVector() * YLength;
+
+	const FVector CornerWorld00 =
+		this->GetComponentTransform().TransformPosition(FVector::ZeroVector) - (X / 2) - (Y / 2);
+	const FVector CornerWorld10 = CornerWorld00 + X;
+	const FVector CornerWorld01 = CornerWorld00 + Y;
+	const FVector CornerWorld11 = CornerWorld00 + X + Y;
+
+	const FVector PlaneNormal =
+		FVector::CrossProduct(CornerWorld10 - CornerWorld00, CornerWorld01 - CornerWorld00).GetSafeNormal();
+
+	FVector Intersection;
+	float T;
+	UKismetMathLibrary::LinePlaneIntersection_OriginNormal(Point, Point + Direction * 10000, CornerWorld00, PlaneNormal,
+														   T, Intersection);
+
+	FVector LocalIntersection = this->GetComponentTransform().InverseTransformPosition(Intersection);
+
+	if (LocalIntersection.Y > XLength / 2)
+	{
+		LocalIntersection.Y = XLength / 2;
+	}
+	else if (LocalIntersection.Y < -XLength / 2)
+	{
+		LocalIntersection.Y = -XLength / 2;
+	}
+
+	if (LocalIntersection.Z > YLength / 2)
+	{
+		LocalIntersection.Z = YLength / 2;
+	}
+	else if (LocalIntersection.Z < -YLength / 2)
+	{
+		LocalIntersection.Z = -YLength / 2;
+	}
+
+	if (OnlyOutline)
+	{
+		const float DistToBottom = LocalIntersection.Z + (YLength / 2);
+		const float DistToLeft = LocalIntersection.Y + (XLength / 2);
+
+		if (LocalIntersection.Z < 0)
+		{
+			if (LocalIntersection.Y < 0)
+			{
+				// Bottom and left
+				if (DistToLeft < DistToBottom)
+				{
+					// snap left
+					LocalIntersection.Y = -(XLength / 2);
+				}
+				else
+				{
+					// snap bottom
+					LocalIntersection.Z = -(YLength / 2);
+				}
+			}
+			else
+			{
+				// bottom and right
+				if (XLength - DistToLeft < DistToBottom)
+				{
+					// snap right
+					LocalIntersection.Y = XLength / 2;
+				}
+				else
+				{
+					// snap bottom
+					LocalIntersection.Z = -(YLength / 2);
+				}
+			}
+		}
+		else
+		{
+			if (LocalIntersection.Y < 0)
+			{
+				// top and left
+				if (DistToLeft < YLength - DistToBottom)
+				{
+					// snap left
+					LocalIntersection.Y = -(XLength / 2);
+				}
+				else
+				{
+					// snap top
+					LocalIntersection.Z = (YLength / 2);
+				}
+			}
+			else
+			{
+				// top and right
+				if (XLength - DistToLeft < YLength - DistToBottom)
+				{
+					// snap right
+					LocalIntersection.Y = XLength / 2;
+				}
+				else
+				{
+					// snap top
+					LocalIntersection.Z = (YLength / 2);
+				}
+			}
+		}
+	}
+
+	return this->GetComponentTransform().TransformPosition(LocalIntersection);
+}
+
+void UIntenSelectableRectangleScoring::TickComponent(float DeltaTime, ELevelTick TickType,
+													 FActorComponentTickFunction* ThisTickFunction)
+{
+	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
+
+	if (DrawDebug)
+	{
+		const FVector X = this->GetRightVector() * XLength;
+		const FVector Y = this->GetUpVector() * YLength;
+
+		const FVector CornerWorld00 =
+			this->GetComponentTransform().TransformPosition(FVector::ZeroVector) - (X / 2) - (Y / 2);
+		const FVector CornerWorld10 = CornerWorld00 + X;
+		const FVector CornerWorld01 = CornerWorld00 + Y;
+		const FVector CornerWorld11 = CornerWorld00 + X + Y;
+
+		DrawDebugLine(GetWorld(), CornerWorld00, CornerWorld01, FColor::Green, false, -1, 0, 2);
+		DrawDebugLine(GetWorld(), CornerWorld00, CornerWorld10, FColor::Green, false, -1, 0, 2);
+		DrawDebugLine(GetWorld(), CornerWorld01, CornerWorld11, FColor::Green, false, -1, 0, 2);
+		DrawDebugLine(GetWorld(), CornerWorld10, CornerWorld11, FColor::Green, false, -1, 0, 2);
+	}
+}
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableScoring.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableScoring.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..82455f7885caea8606e98deb229f0aa51a73cf14
--- /dev/null
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableScoring.cpp
@@ -0,0 +1,57 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+
+#include "Interaction/Interactables/IntenSelect/IntenSelectableScoring.h"
+
+float UIntenSelectableScoring::GetScore(const FVector& ConeOrigin, const FVector& ConeForwardDirection,
+										const float ConeBackwardShiftDistance, const float ConeAngle,
+										const FVector& TestPoint, const float LastValue, const float DeltaTime)
+{
+	const FVector ShiftedConeOrigin = ConeOrigin - (ConeForwardDirection * ConeBackwardShiftDistance);
+
+	const float D_Perspective = FMath::PointDistToLine(TestPoint, ConeForwardDirection, ShiftedConeOrigin);
+	const float D_Projection = (TestPoint - ShiftedConeOrigin).ProjectOnTo(ConeForwardDirection).Size();
+
+	const float Angle = FMath::RadiansToDegrees(
+		FMath::Atan(D_Perspective / (FMath::Pow(D_Projection / 100, CompensationConstant) * 100)));
+	float S_Contrib = 1 - (Angle / ConeAngle);
+	if (S_Contrib < 0)
+		S_Contrib = 0;
+
+	// GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Red, GetOwner()->GetName() + " - Contrib: " +
+	// FString::FromInt(S_Contrib));
+
+	if (LastValue != 0)
+	{
+		constexpr float Interpolate = 0.5;
+		if (S_Contrib > LastValue)
+		{
+			CurrentScore = LastValue +
+				(((LastValue * Interpolate) + (S_Contrib * (1 - Interpolate))) - LastValue) * DeltaTime * Snappiness;
+		}
+		else
+		{
+			CurrentScore = LastValue +
+				(((LastValue * Interpolate) + (S_Contrib * (1 - Interpolate))) - LastValue) * DeltaTime * Stickiness;
+		}
+	}
+	else
+	{
+		CurrentScore = S_Contrib * Snappiness * DeltaTime;
+	}
+	return CurrentScore;
+}
+
+// Sets default values for this component's properties
+UIntenSelectableScoring::UIntenSelectableScoring() { PrimaryComponentTick.bCanEverTick = true; }
+
+TPair<FHitResult, float> UIntenSelectableScoring::GetBestPointScorePair(const FVector& ConeOrigin,
+																		const FVector& ConeForwardDirection,
+																		const float ConeBackwardShiftDistance,
+																		const float ConeAngle, const float LastValue,
+																		const float DeltaTime)
+{
+	return {};
+}
+
+void UIntenSelectableScoring::BeginPlay() { Super::BeginPlay(); }
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableSinglePointScoring.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableSinglePointScoring.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e42770a89577caa97c2208b2a6905db8ca6bcbba
--- /dev/null
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableSinglePointScoring.cpp
@@ -0,0 +1,16 @@
+#include "Interaction/Interactables/IntenSelect/IntenSelectableSinglePointScoring.h"
+
+UIntenSelectableSinglePointScoring::UIntenSelectableSinglePointScoring() { PrimaryComponentTick.bCanEverTick = true; }
+
+TPair<FHitResult, float> UIntenSelectableSinglePointScoring::GetBestPointScorePair(
+	const FVector& ConeOrigin, const FVector& ConeForwardDirection, const float ConeBackwardShiftDistance,
+	const float ConeAngle, const float LastValue, const float DeltaTime)
+{
+	const FVector Point = this->GetComponentLocation();
+	float Score =
+		GetScore(ConeOrigin, ConeForwardDirection, ConeBackwardShiftDistance, ConeAngle, Point, LastValue, DeltaTime);
+	FHitResult Result = FHitResult{GetOwner(), nullptr, Point, FVector::ForwardVector};
+	return TPair<FHitResult, float>{Result, Score};
+}
+
+void UIntenSelectableSinglePointScoring::BeginPlay() { Super::BeginPlay(); }
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableSphereScoring.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableSphereScoring.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..36ddcbb571c7fe464ed38d9ff6c1cb5b60d40d04
--- /dev/null
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactables/IntenSelect/IntenSelectableSphereScoring.cpp
@@ -0,0 +1,82 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#include "Interaction/Interactables/IntenSelect/IntenSelectableSphereScoring.h"
+
+#include "DrawDebugHelpers.h"
+#include "Algo/IndexOf.h"
+#include "Kismet/GameplayStatics.h"
+#include "Kismet/KismetMathLibrary.h"
+
+// Sets default values for this component's properties
+UIntenSelectableSphereScoring::UIntenSelectableSphereScoring() { PrimaryComponentTick.bCanEverTick = true; }
+
+TPair<FHitResult, float>
+UIntenSelectableSphereScoring::GetBestPointScorePair(const FVector& ConeOrigin, const FVector& ConeForwardDirection,
+													 const float ConeBackwardShiftDistance, const float ConeAngle,
+													 const float LastValue, const float DeltaTime)
+{
+	FVector Point = GetClosestSelectionPointTo(ConeOrigin, ConeForwardDirection);
+	float Score =
+		GetScore(ConeOrigin, ConeForwardDirection, ConeBackwardShiftDistance, ConeAngle, Point, LastValue, DeltaTime);
+	FHitResult Result = FHitResult{GetOwner(), nullptr, Point, FVector::ForwardVector};
+	return TPair<FHitResult, float>{Result, Score};
+}
+
+FVector UIntenSelectableSphereScoring::GetClosestSelectionPointTo(const FVector& Point, const FVector& Direction) const
+{
+	const FVector CenterWorld = this->GetComponentLocation();
+
+	const FVector ToSphere = CenterWorld - Point;
+
+	const FVector Projection = ToSphere.ProjectOnTo(Direction);
+	const FVector ProjectionToSphere = ToSphere - Projection;
+
+	FVector Result = CenterWorld - ProjectionToSphere.GetSafeNormal() * Radius;
+
+	if (!OnlyOutline)
+	{
+		const float t = FVector::DotProduct(ToSphere, Direction.GetSafeNormal());
+		const FVector TPoint = Point + Direction.GetSafeNormal() * t;
+		const float Y = (CenterWorld - TPoint).Size();
+
+		if (Y <= Radius)
+		{
+			const float X = +FMath::Sqrt((Radius * Radius) - (Y * Y));
+
+			const FVector Result1 = Point + Direction.GetSafeNormal() * (t - X);
+			const FVector Result2 = Point + Direction.GetSafeNormal() * (t + X);
+
+			if (FVector::Distance(Point, Result1) < FVector::Distance(Point, Result2))
+			{
+				Result = Result1;
+			}
+			else
+			{
+				Result = Result2;
+			}
+		}
+
+		/*
+		TArray<FHitResult> Out;
+		const float Dist = FVector::Distance(Point, GetComponentLocation());
+		if(GetWorld()->LineTraceMultiByChannel(Out, Point, Point + (Direction.GetSafeNormal() * Dist),
+		ECollisionChannel::ECC_Visibility))
+		{
+			for(auto Hit : Out)
+			{
+				if(Hit.GetActor() == GetOwner())
+				{
+					Result = Hit.ImpactPoint;
+					break;
+				}
+			}
+		}*/
+	}
+
+	if (DrawDebug)
+	{
+		DrawDebugSphere(GetWorld(), CenterWorld, Radius, 20, FColor::Green, false, -1, 0, 1);
+	}
+
+	return Result;
+}
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactors/DirectInteractionComponent.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactors/DirectInteractionComponent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c8cf9ce35e45d0bc107cd73da08333ef5ba5b2d9
--- /dev/null
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactors/DirectInteractionComponent.cpp
@@ -0,0 +1,185 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+
+#include "Interaction/Interactors/DirectInteractionComponent.h"
+
+#include "EnhancedInputComponent.h"
+#include "Interaction/Interactables/InteractableComponent.h"
+#include "Interaction/Interactables/InteractionBitSet.h"
+
+#include "Kismet/GameplayStatics.h"
+#include "Logging/StructuredLog.h"
+#include "Utility/RWTHVRUtilities.h"
+
+// Sets default values for this component's properties
+UDirectInteractionComponent::UDirectInteractionComponent()
+{
+	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these
+	// features off to improve performance if you don't need them.
+	PrimaryComponentTick.bCanEverTick = true;
+	// ...
+}
+
+void UDirectInteractionComponent::TickComponent(float DeltaTime, ELevelTick TickType,
+												FActorComponentTickFunction* ThisTickFunction)
+{
+	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
+
+	TArray<UInteractableComponent*> CurrentInteractableCompsInRange;
+
+	TArray<FHitResult> OutHits;
+	const ETraceTypeQuery TraceType = UEngineTypes::ConvertToTraceType(ECollisionChannel::ECC_PhysicsBody);
+
+	auto DebugTrace = bShowDebugTrace ? EDrawDebugTrace::ForOneFrame : EDrawDebugTrace::None;
+
+	UKismetSystemLibrary::SphereTraceMulti(GetWorld(), GetAttachParent()->GetComponentLocation(),
+										   GetAttachParent()->GetComponentLocation(), InteractionSphereRadius,
+										   TraceType, true, ActorsToIgnore, DebugTrace, OutHits, true, FColor::Green);
+
+	for (FHitResult Hit : OutHits)
+	{
+		AActor* HitActor = Hit.GetActor();
+		if (HitActor)
+		{
+			UInteractableComponent* InteractableComp = SearchForInteractable(HitActor);
+			if (InteractableComp && InteractableComp->HasInteractionTypeFlag(EInteractorType::Direct) &&
+				InteractableComp->IsInteractable)
+			{
+				InteractableComp->HitResult = Hit;
+				CurrentInteractableCompsInRange.AddUnique(InteractableComp);
+			}
+		}
+	}
+
+	CurrentInteractableComponentsInRange = CurrentInteractableCompsInRange;
+
+	// Call hover start events on all components that were not in range before
+	for (UInteractableComponent* CurrentInteractableComp : CurrentInteractableCompsInRange)
+	{
+		if (!PreviousInteractableComponentsInRange.Contains(CurrentInteractableComp))
+		{
+			PreviousInteractableComponentsInRange.AddUnique(CurrentInteractableComp);
+			CurrentInteractableComp->HandleOnHoverStartEvents(this, EInteractorType::Direct);
+		}
+	}
+
+	TArray<UInteractableComponent*> ComponentsToRemove;
+
+	// Call hover end events on all components that were previously in range, but not anymore
+	for (UInteractableComponent* PrevInteractableComp : PreviousInteractableComponentsInRange)
+	{
+		if (!CurrentInteractableCompsInRange.Contains(PrevInteractableComp))
+		{
+			ComponentsToRemove.AddUnique(PrevInteractableComp);
+			PrevInteractableComp->HandleOnHoverEndEvents(this, EInteractorType::Direct);
+		}
+	}
+
+	for (UInteractableComponent* CompToRemove : ComponentsToRemove)
+	{
+		PreviousInteractableComponentsInRange.Remove(CompToRemove);
+	}
+}
+
+void UDirectInteractionComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent)
+{
+	IInputExtensionInterface::SetupPlayerInput(PlayerInputComponent);
+
+	const APawn* Pawn = Cast<APawn>(GetOwner());
+	if (!Pawn)
+		return;
+
+	// Probably not the best place to add this.
+	ActorsToIgnore.AddUnique(GetOwner());
+
+	UEnhancedInputComponent* EI = Cast<UEnhancedInputComponent>(Pawn->InputComponent);
+	if (EI == nullptr)
+		return;
+
+	EI->BindAction(InteractionInputAction, ETriggerEvent::Started, this,
+				   &UDirectInteractionComponent::OnBeginInteraction);
+	EI->BindAction(InteractionInputAction, ETriggerEvent::Completed, this,
+				   &UDirectInteractionComponent::OnEndInteraction);
+}
+
+void UDirectInteractionComponent::OnBeginInteraction(const FInputActionValue& Value)
+{
+	const FVector InteractionLocation = GetAttachParent()->GetComponentLocation();
+
+	if (CurrentInteractableComponentsInRange.IsEmpty())
+		return;
+
+	if (bOnlyInteractWithClosestActor)
+	{
+		auto MinElement = *Algo::MinElementBy(
+			CurrentInteractableComponentsInRange,
+			[&](auto Element)
+			{ return FVector(Element->GetOwner()->GetActorLocation() - InteractionLocation).Size(); });
+		MinElement->HandleOnActionStartEvents(this, InteractionInputAction, Value, EInteractorType::Direct);
+		CurrentlyInteractedComponents = {MinElement};
+	}
+	else
+	{
+		CurrentlyInteractedComponents.Reserve(CurrentlyInteractedComponents.Num() +
+											  CurrentInteractableComponentsInRange.Num());
+		for (UInteractableComponent* InteractableComp : CurrentInteractableComponentsInRange)
+		{
+			InteractableComp->HandleOnActionStartEvents(this, InteractionInputAction, Value, EInteractorType::Direct);
+			CurrentlyInteractedComponents.Add(InteractableComp);
+		}
+	}
+}
+
+void UDirectInteractionComponent::OnEndInteraction(const FInputActionValue& Value)
+{
+	for (auto& Component : CurrentlyInteractedComponents)
+	{
+		if (Component.IsValid())
+		{
+			Component->HandleOnActionEndEvents(this, InteractionInputAction, Value, EInteractorType::Direct);
+		}
+	}
+}
+
+UInteractableComponent* UDirectInteractionComponent::SearchForInteractable(AActor* HitActor)
+{
+	UInteractableComponent* InteractableComponent = nullptr;
+	if (!HitActor)
+	{
+		UE_LOGFMT(Toolkit, Warning,
+				  "UDirectInteractionComponent::SearchForInteractable: HitActor was nullptr, returning nullptr");
+		return nullptr;
+	}
+
+	if (HitActor->IsChildActor())
+	{
+		// search for UInteractable upwards from hit geometry and return first one found
+		InteractableComponent = HitActor->FindComponentByClass<UInteractableComponent>();
+		// if InteractableComponen is not valid search at parent
+		if (!InteractableComponent)
+		{
+			HitActor = HitActor->GetParentActor();
+			if (HitActor)
+			{
+				bSearchAtParent = true;
+				return SearchForInteractable(HitActor);
+			}
+		}
+	}
+	else if (!HitActor->IsChildActor())
+	{
+		InteractableComponent = HitActor->FindComponentByClass<UInteractableComponent>();
+	}
+
+	if (InteractableComponent)
+	{
+		// in the case, were we had to iterate up the hierarchy, check if we are allowed
+		// to interact with the parent via child geometry
+		if (bSearchAtParent && !InteractableComponent->bAllowInteractionFromChildGeometry)
+		{
+			InteractableComponent = nullptr;
+		}
+	}
+	bSearchAtParent = false;
+	return InteractableComponent;
+}
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactors/GrabComponent.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactors/GrabComponent.cpp
deleted file mode 100644
index fcc3abae942e3baa4d1fd01f453dabb6cf9d3b81..0000000000000000000000000000000000000000
--- a/Source/RWTHVRToolkit/Private/Interaction/Interactors/GrabComponent.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-// Fill out your copyright notice in the Description page of Project Settings.
-
-
-#include "Interaction/Interactors/GrabComponent.h"
-
-#include "EnhancedInputComponent.h"
-#include "EnhancedInputSubsystems.h"
-#include "Interaction/Interactables/InteractableComponent.h"
-#include "Interaction/Interactables/InteractionBitSet.h"
-
-#include "Kismet/GameplayStatics.h"
-
-// Sets default values for this component's properties
-UGrabComponent::UGrabComponent()
-{
-	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these
-	// features off to improve performance if you don't need them.
-	PrimaryComponentTick.bCanEverTick = true;
-
-	// ...
-}
-
-void UGrabComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
-{
-	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
-
-
-	TArray<UInteractableComponent*> CurrentGrabCompsInRange;
-
-	TArray<AActor*> ActorsToIgnore;
-	TArray<FHitResult> OutHits;
-	const ETraceTypeQuery TraceType = UEngineTypes::ConvertToTraceType(ECollisionChannel::ECC_PhysicsBody);
-
-	auto DebugTrace = bShowDebugTrace ? EDrawDebugTrace::ForOneFrame : EDrawDebugTrace::None;
-
-	UKismetSystemLibrary::SphereTraceMulti(GetWorld(), GetAttachParent()->GetComponentLocation(),
-										   GetAttachParent()->GetComponentLocation(), GrabSphereRadius, TraceType, true,
-										   ActorsToIgnore, DebugTrace, OutHits, true, FColor::Green);
-
-	for (FHitResult Hit : OutHits)
-	{
-		AActor* HitActor = Hit.GetActor();
-		if (HitActor)
-		{
-			UInteractableComponent* Grabbable = HitActor->FindComponentByClass<UInteractableComponent>();
-			if (Grabbable && Grabbable->HasInteractionTypeFlag(EInteractorType::Grab) && Grabbable->IsInteractable)
-			{
-				Grabbable->HitResult = Hit;
-				CurrentGrabCompsInRange.Add(Grabbable);
-			}
-		}
-	}
-
-	CurrentGrabbableInRange = CurrentGrabCompsInRange;
-
-	// Call hover start events on all components that were not in range before
-	for (UInteractableComponent* CurrentGrabbale : CurrentGrabCompsInRange)
-	{
-		if (!PreviousGrabbablesInRange.Contains(CurrentGrabbale))
-		{
-			PreviousGrabbablesInRange.Add(CurrentGrabbale);
-			CurrentGrabbale->HandleOnHoverStartEvents(this, EInteractorType::Grab);
-		}
-	}
-
-	TArray<UInteractableComponent*> ComponentsToRemove;
-
-	// Call hover end events on all components that were previously in range, but not anymore
-	for (UInteractableComponent* PrevGrabbale : PreviousGrabbablesInRange)
-	{
-		if (!CurrentGrabCompsInRange.Contains(PrevGrabbale))
-		{
-			ComponentsToRemove.Add(PrevGrabbale);
-			PrevGrabbale->HandleOnHoverEndEvents(this, EInteractorType::Grab);
-		}
-	}
-
-	for (UInteractableComponent* CompToRemove : ComponentsToRemove)
-	{
-		PreviousGrabbablesInRange.Remove(CompToRemove);
-	}
-}
-
-void UGrabComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent)
-{
-	IInputExtensionInterface::SetupPlayerInput(PlayerInputComponent);
-
-	const APawn* Pawn = Cast<APawn>(GetOwner());
-	if (!Pawn)
-		return;
-
-	auto* InputSubsystem = GetEnhancedInputLocalPlayerSubsystem(Pawn);
-	if (!InputSubsystem)
-		return;
-
-	// add Input Mapping context
-	InputSubsystem->AddMappingContext(IMCGrab, 0);
-
-	UEnhancedInputComponent* EI = Cast<UEnhancedInputComponent>(Pawn->InputComponent);
-	if (EI == nullptr)
-		return;
-
-	EI->BindAction(GrabInputAction, ETriggerEvent::Started, this, &UGrabComponent::OnBeginGrab);
-	EI->BindAction(GrabInputAction, ETriggerEvent::Completed, this, &UGrabComponent::OnEndGrab);
-}
-
-void UGrabComponent::OnBeginGrab(const FInputActionValue& Value)
-{
-	for (UInteractableComponent* Grabbale : CurrentGrabbableInRange)
-	{
-		Grabbale->HandleOnActionStartEvents(this, GrabInputAction, Value, EInteractorType::Grab);
-	}
-}
-
-void UGrabComponent::OnEndGrab(const FInputActionValue& Value)
-{
-	for (UInteractableComponent* Grabbale : CurrentGrabbableInRange)
-	{
-		Grabbale->HandleOnActionEndEvents(this, GrabInputAction, Value, EInteractorType::Grab);
-	}
-}
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactors/RWTHVRWidgetInteractionComponent.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactors/RWTHVRWidgetInteractionComponent.cpp
index bcbea769743979f8ca91339e038fe2ee0d3d99fd..3a87de65d2cb52a5bce0dd0aa71af9dd3b2f69bb 100644
--- a/Source/RWTHVRToolkit/Private/Interaction/Interactors/RWTHVRWidgetInteractionComponent.cpp
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactors/RWTHVRWidgetInteractionComponent.cpp
@@ -4,8 +4,7 @@
 #include "Interaction/Interactors/RWTHVRWidgetInteractionComponent.h"
 
 #include "EnhancedInputComponent.h"
-#include "EnhancedInputSubsystems.h"
-#include "Interaction/Interactors/GrabComponent.h"
+#include "Interaction/Interactors/DirectInteractionComponent.h"
 #include "Logging/StructuredLog.h"
 #include "Misc/Optional.h"
 #include "Utility/RWTHVRUtilities.h"
@@ -35,39 +34,32 @@ void URWTHVRWidgetInteractionComponent::SetupPlayerInput(UInputComponent* Player
 	if (!Pawn)
 	{
 		UE_LOGFMT(Toolkit, Warning,
-		          "URWTHVRWidgetInteractionComponent::SetupPlayerInput requires a Pawn as Owner, which is not the case. Not setting up any input actions.")
-		;
+				  "URWTHVRWidgetInteractionComponent::SetupPlayerInput requires a Pawn as Owner, which is not the "
+				  "case. Not setting up any input actions.");
 		return;
 	}
 
-	// We can be owned by a pawn, but not be the locally controlled pawn in a MP setting. In that case, just return and
-	// don't set up any inputs.
-	auto* InputSubsystem = GetEnhancedInputLocalPlayerSubsystem(Pawn);
-	if (!InputSubsystem)
-		return;
-
 	// Because we cannot use the regular debug ray (only works in editor), we set up our own (mesh) ray.
 	SetupInteractionRay();
 
-	// add Input Mapping context 
-	InputSubsystem->AddMappingContext(IMCWidgetInteraction, 0);
-
 	UEnhancedInputComponent* EI = Cast<UEnhancedInputComponent>(Pawn->InputComponent);
 	if (!EI)
 	{
 		UE_LOGFMT(Toolkit, Warning,
-		          "URWTHVRWidgetInteractionComponent::SetupPlayerInput: Cannot cast Pawn's InputComponent to UEnhancedInputComponent! Not binding any actions!")
-		;
+				  "URWTHVRWidgetInteractionComponent::SetupPlayerInput: Cannot cast Pawn's InputComponent to "
+				  "UEnhancedInputComponent! Not binding any actions!");
 		return;
 	}
 
-	EI->BindAction(WidgetClickInputAction, ETriggerEvent::Started, this, &URWTHVRWidgetInteractionComponent::OnBeginClick);
-	EI->BindAction(WidgetClickInputAction, ETriggerEvent::Completed, this, &URWTHVRWidgetInteractionComponent::OnEndClick);
+	EI->BindAction(WidgetClickInputAction, ETriggerEvent::Started, this,
+				   &URWTHVRWidgetInteractionComponent::OnBeginClick);
+	EI->BindAction(WidgetClickInputAction, ETriggerEvent::Completed, this,
+				   &URWTHVRWidgetInteractionComponent::OnEndClick);
 }
 
 // Called every frame
 void URWTHVRWidgetInteractionComponent::TickComponent(float DeltaTime, ELevelTick TickType,
-                                                  FActorComponentTickFunction* ThisTickFunction)
+													  FActorComponentTickFunction* ThisTickFunction)
 {
 	// We should only tick on the local owner (the controlling client). Not on the server, not on any other pawn.
 	// In theory, this should never happen as we only activate the component for the local player anyway.
@@ -103,7 +95,7 @@ void URWTHVRWidgetInteractionComponent::SetInteractionRayVisibility(EInteraction
 		InteractionRay->SetVisibility(NewVisibility == Visible);
 	else
 		UE_LOGFMT(Toolkit, Error,
-	          "URWTHVRWidgetInteractionComponent::SetInteractionRayVisibility: InteractionRay not set yet!");
+				  "URWTHVRWidgetInteractionComponent::SetInteractionRayVisibility: InteractionRay not set yet!");
 }
 
 // Forward the click to the WidgetInteraction
@@ -173,7 +165,7 @@ void URWTHVRWidgetInteractionComponent::SetupInteractionRay()
 	// turns off collisions as the InteractionRay is only meant to visualize the ray
 	InteractionRay->SetCollisionProfileName(TEXT("NoCollision"));
 
-	//the ray model has a length of 100cm (and is a bit too big in Y/Z dir)
+	// the ray model has a length of 100cm (and is a bit too big in Y/Z dir)
 	InteractionRay->SetRelativeScale3D(FVector(InteractionDistance / 100.0f, 0.5f, 0.5f));
 	SetInteractionRayVisibility(InteractionRayVisibility);
 
diff --git a/Source/RWTHVRToolkit/Private/Interaction/Interactors/RaycastSelectionComponent.cpp b/Source/RWTHVRToolkit/Private/Interaction/Interactors/RaycastInteractionComponent.cpp
similarity index 59%
rename from Source/RWTHVRToolkit/Private/Interaction/Interactors/RaycastSelectionComponent.cpp
rename to Source/RWTHVRToolkit/Private/Interaction/Interactors/RaycastInteractionComponent.cpp
index dc88e0375bf44a01c62aa2c91de71e9f18643bca..94afba4b4426fe1b861d787826f0e1cc11d6583b 100644
--- a/Source/RWTHVRToolkit/Private/Interaction/Interactors/RaycastSelectionComponent.cpp
+++ b/Source/RWTHVRToolkit/Private/Interaction/Interactors/RaycastInteractionComponent.cpp
@@ -1,15 +1,14 @@
 // Fill out your copyright notice in the Description page of Project Settings.
 
 
-#include "Interaction/Interactors/RaycastSelectionComponent.h"
+#include "Interaction/Interactors/RaycastInteractionComponent.h"
 
 #include "EnhancedInputComponent.h"
-#include "EnhancedInputSubsystems.h"
 #include "Interaction/Interactables/InteractableComponent.h"
 #include "Kismet/KismetSystemLibrary.h"
 
 // Sets default values for this component's properties
-URaycastSelectionComponent::URaycastSelectionComponent()
+URaycastInteractionComponent::URaycastInteractionComponent()
 {
 	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these
 	// features off to improve performance if you don't need them.
@@ -19,12 +18,12 @@ URaycastSelectionComponent::URaycastSelectionComponent()
 }
 
 // Called every frame
-void URaycastSelectionComponent::TickComponent(float DeltaTime, ELevelTick TickType,
-											   FActorComponentTickFunction* ThisTickFunction)
+void URaycastInteractionComponent::TickComponent(float DeltaTime, ELevelTick TickType,
+												 FActorComponentTickFunction* ThisTickFunction)
 {
 	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
 
-	UInteractableComponent* CurrentSelectable = nullptr;
+	UInteractableComponent* NewInteractableComponent = nullptr;
 
 
 	TArray<AActor*> ActorsToIgnore;
@@ -41,15 +40,15 @@ void URaycastSelectionComponent::TickComponent(float DeltaTime, ELevelTick TickT
 	AActor* HitActor = Hit.GetActor();
 	if (HitActor)
 	{
-		UInteractableComponent* Selectable = HitActor->FindComponentByClass<UInteractableComponent>();
-		if (Selectable && Selectable->IsInteractable)
+		UInteractableComponent* InteractableComponent = HitActor->FindComponentByClass<UInteractableComponent>();
+		if (InteractableComponent && InteractableComponent->IsInteractable)
 		{
-			CurrentSelectable = Selectable;
-			Selectable->HitResult = Hit;
+			NewInteractableComponent = InteractableComponent;
+			InteractableComponent->HitResult = Hit;
 		}
 	}
 
-	CurrentInteractable = CurrentSelectable;
+	CurrentInteractable = NewInteractableComponent;
 
 	if (CurrentInteractable != PreviousInteractable)
 	{
@@ -62,19 +61,19 @@ void URaycastSelectionComponent::TickComponent(float DeltaTime, ELevelTick TickT
 	PreviousInteractable = CurrentInteractable;
 }
 
-void URaycastSelectionComponent::OnBeginSelect(const FInputActionValue& Value)
+void URaycastInteractionComponent::OnBeginInteraction(const FInputActionValue& Value)
 {
 	if (CurrentInteractable && CurrentInteractable->HasInteractionTypeFlag(EInteractorType::Raycast))
-		CurrentInteractable->HandleOnActionStartEvents(this, RayCastSelectInputAction, Value, EInteractorType::Raycast);
+		CurrentInteractable->HandleOnActionStartEvents(this, InteractionInputAction, Value, EInteractorType::Raycast);
 }
 
-void URaycastSelectionComponent::OnEndSelect(const FInputActionValue& Value)
+void URaycastInteractionComponent::OnEndInteraction(const FInputActionValue& Value)
 {
 	if (CurrentInteractable && CurrentInteractable->HasInteractionTypeFlag(EInteractorType::Raycast))
-		CurrentInteractable->HandleOnActionEndEvents(this, RayCastSelectInputAction, Value, EInteractorType::Raycast);
+		CurrentInteractable->HandleOnActionEndEvents(this, InteractionInputAction, Value, EInteractorType::Raycast);
 }
 
-void URaycastSelectionComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent)
+void URaycastInteractionComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent)
 {
 	IInputExtensionInterface::SetupPlayerInput(PlayerInputComponent);
 
@@ -82,17 +81,12 @@ void URaycastSelectionComponent::SetupPlayerInput(UInputComponent* PlayerInputCo
 	if (!Pawn)
 		return;
 
-	auto* InputSubsystem = GetEnhancedInputLocalPlayerSubsystem(Pawn);
-	if (!InputSubsystem)
-		return;
-
-	// add Input Mapping context
-	InputSubsystem->AddMappingContext(IMCRaycastSelection, 0);
-
 	UEnhancedInputComponent* EI = Cast<UEnhancedInputComponent>(Pawn->InputComponent);
 	if (!EI)
 		return;
 
-	EI->BindAction(RayCastSelectInputAction, ETriggerEvent::Started, this, &URaycastSelectionComponent::OnBeginSelect);
-	EI->BindAction(RayCastSelectInputAction, ETriggerEvent::Completed, this, &URaycastSelectionComponent::OnEndSelect);
+	EI->BindAction(InteractionInputAction, ETriggerEvent::Started, this,
+				   &URaycastInteractionComponent::OnBeginInteraction);
+	EI->BindAction(InteractionInputAction, ETriggerEvent::Completed, this,
+				   &URaycastInteractionComponent::OnEndInteraction);
 }
diff --git a/Source/RWTHVRToolkit/Private/Pawn/InputExtensionInterface.cpp b/Source/RWTHVRToolkit/Private/Pawn/InputExtensionInterface.cpp
index ddee08706d0f68ad5a5ce1bd4c632642b3bc971f..03ea498fea124f6fe19b947e3cc370dd10295394 100644
--- a/Source/RWTHVRToolkit/Private/Pawn/InputExtensionInterface.cpp
+++ b/Source/RWTHVRToolkit/Private/Pawn/InputExtensionInterface.cpp
@@ -2,12 +2,3 @@
 
 
 #include "Pawn/InputExtensionInterface.h"
-
-UEnhancedInputLocalPlayerSubsystem*
-IInputExtensionInterface::GetEnhancedInputLocalPlayerSubsystem(const APawn* Pawn) const
-{
-	const APlayerController* PlayerController = Pawn ? Cast<APlayerController>(Pawn->GetController()) : nullptr;
-	const ULocalPlayer* LP = PlayerController ? PlayerController->GetLocalPlayer() : nullptr;
-
-	return LP->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>();
-}
diff --git a/Source/RWTHVRToolkit/Private/Pawn/IntenSelectComponent.cpp b/Source/RWTHVRToolkit/Private/Pawn/IntenSelectComponent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..644f30c91b22cad8ec4536347912b8791f0d4da8
--- /dev/null
+++ b/Source/RWTHVRToolkit/Private/Pawn/IntenSelectComponent.cpp
@@ -0,0 +1,792 @@
+#include "Pawn/IntenSelectComponent.h"
+#include "EnhancedInputComponent.h"
+#include "EnhancedInputSubsystems.h"
+#include "Components/WidgetComponent.h"
+#include "Haptics/HapticFeedbackEffect_Curve.h"
+#include "Kismet/GameplayStatics.h"
+#include "Materials/MaterialParameterCollection.h"
+#include "Materials/MaterialParameterCollectionInstance.h"
+#include "Misc/MessageDialog.h"
+#include "Templates/Tuple.h"
+
+
+//				INITIALIZATION
+
+// Sets default values for this component's properties
+UIntenSelectComponent::UIntenSelectComponent(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
+{
+	PrimaryComponentTick.bCanEverTick = true;
+	bShowDebug = false; // otherwise the WidgetInteractionComponent debug vis is shown
+	InteractionSource = EWidgetInteractionSource::Custom; // can also be kept at default (World), this way, however, we
+														  // efficiently reuse the line traces
+
+	ConstructorHelpers::FObjectFinder<UStaticMesh> DefaultConeMesh(
+		TEXT("StaticMesh'/RWTHVRToolkit/IntenSelect/DebugConeMesh.DebugConeMesh'"));
+	this->DebugConeMesh = DefaultConeMesh.Object;
+
+	ConstructorHelpers::FObjectFinder<UMaterialInterface> DefaultConeMeshMaterial(
+		TEXT("Material'/RWTHVRToolkit/IntenSelect/DebugConeMaterial.DebugConeMaterial'"));
+	this->DebugConeMaterial = DefaultConeMeshMaterial.Object;
+
+	ConstructorHelpers::FObjectFinder<UStaticMesh> DefaultSplineMesh(
+		TEXT("StaticMesh'/RWTHVRToolkit/IntenSelect/sectionedCubeMesh.sectionedCubeMesh'"));
+	this->SplineMesh = DefaultSplineMesh.Object;
+
+	ConstructorHelpers::FObjectFinder<UStaticMesh> DefaultForwardRayMesh(
+		TEXT("StaticMesh'/RWTHVRToolkit/IntenSelect/RayMesh.RayMesh'"));
+	this->ForwardRayMesh = DefaultForwardRayMesh.Object;
+
+	ConstructorHelpers::FObjectFinder<UMaterialInterface> DefaultSplineMaterial(
+		TEXT("Material'/RWTHVRToolkit/IntenSelect/SelectionSplineMaterial.SelectionSplineMaterial'"));
+	this->SplineMaterial = DefaultSplineMaterial.Object;
+
+	ConstructorHelpers::FObjectFinder<UMaterialInterface> DefaultForwardRayMaterial(
+		TEXT("Material'/RWTHVRToolkit/IntenSelect/ForwadRayMaterial.ForwadRayMaterial'"));
+	this->ForwardRayMaterial = DefaultForwardRayMaterial.Object;
+
+	ConstructorHelpers::FObjectFinder<UHapticFeedbackEffect_Curve> DefaultSelectionFeedbackHaptic(
+		TEXT("HapticFeedbackEffect_Curve'/RWTHVRToolkit/IntenSelect/OnSelectHapticFeedback.OnSelectHapticFeedback'"));
+	this->SelectionFeedbackHaptic = DefaultSelectionFeedbackHaptic.Object;
+
+	ConstructorHelpers::FObjectFinder<USoundBase> DefaultOnSelectSound(
+		TEXT("SoundWave'/RWTHVRToolkit/IntenSelect/OnSelectSound.OnSelectSound'"));
+	this->OnSelectSound = DefaultOnSelectSound.Object;
+
+	ConstructorHelpers::FObjectFinder<UMaterialParameterCollection> DefaultMaterialParamCollection(
+		TEXT("MaterialParameterCollection'/RWTHVRToolkit/IntenSelect/ForwardRayParams.ForwardRayParams'"));
+	this->MaterialParamCollection = DefaultMaterialParamCollection.Object;
+
+	ConstructorHelpers::FObjectFinder<UCurveFloat> DefaultForwardRayTransparencyCurve(
+		TEXT("CurveFloat'/RWTHVRToolkit/IntenSelect/ForwardRayTransparencyCurve.ForwardRayTransparencyCurve'"));
+	this->ForwardRayTransparencyCurve = DefaultForwardRayTransparencyCurve.Object;
+
+	ConstructorHelpers::FObjectFinder<UInputAction> InputActionClick(
+		TEXT("/Script/EnhancedInput.InputAction'/RWTHVRToolkit/IntenSelect/IntenSelectClick.IntenSelectClick'"));
+	this->InputClick = InputActionClick.Object;
+}
+
+// Called when the game starts
+void UIntenSelectComponent::BeginPlay()
+{
+	Super::BeginPlay();
+
+	this->InitSplineComponent();
+	this->InitSplineMeshComponent();
+	this->InitForwardRayMeshComponent();
+	this->InitDebugConeMeshComponent();
+	this->InitInputBindings();
+	this->InitMaterialParamCollection();
+
+	this->SphereCastRadius = CalculateSphereCastRadius();
+	this->InteractionDistance = this->MaxSelectionDistance;
+
+	this->SetActive(SetActiveOnStart, false);
+}
+
+void UIntenSelectComponent::InitInputBindings()
+{
+	const APlayerController* PC = UGameplayStatics::GetPlayerController(GetWorld(), 0);
+
+	UEnhancedInputLocalPlayerSubsystem* Subsystem =
+		ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer());
+
+	UInputComponent* PlayerInputComponent = PC->InputComponent;
+	UEnhancedInputComponent* PEI = Cast<UEnhancedInputComponent>(PlayerInputComponent);
+
+	if (!PEI)
+	{
+		const FString Message = "Could not get PlayerInputComponent for IntenSelect Input Assignment!";
+
+#if WITH_EDITOR
+		const FText Title = FText::FromString(FString("ERROR"));
+		FMessageDialog::Open(EAppMsgType::Ok, FText::FromString(Message), Title);
+#endif
+
+		UE_LOG(LogTemp, Error, TEXT("%s"), *Message)
+		UKismetSystemLibrary::QuitGame(this, nullptr, EQuitPreference::Quit, false);
+		return;
+	}
+
+	// Bind the actions
+	PEI->BindAction(InputClick, ETriggerEvent::Started, this, &UIntenSelectComponent::OnFireDown);
+	PEI->BindAction(InputClick, ETriggerEvent::Completed, this, &UIntenSelectComponent::OnFireUp);
+}
+
+void UIntenSelectComponent::InitSplineComponent()
+{
+	SplineComponent = NewObject<USplineComponent>(this, TEXT("SplineComponent"));
+
+	if (SplineComponent)
+	{
+		SplineComponent->SetupAttachment(this);
+		SplineComponent->SetMobility(EComponentMobility::Movable);
+		SplineComponent->RegisterComponent();
+		SplineComponent->CreationMethod = EComponentCreationMethod::Instance;
+	}
+	else
+	{
+		const FString Message = "Error while spawning SplineComponent!";
+#if WITH_EDITOR
+		const FText Title = FText::FromString(FString("ERROR"));
+		FMessageDialog::Open(EAppMsgType::Ok, FText::FromString(Message), Title);
+#endif
+
+		UE_LOG(LogTemp, Error, TEXT("%s"), *Message)
+	}
+}
+
+void UIntenSelectComponent::InitSplineMeshComponent()
+{
+	SplineMeshComponent =
+		NewObject<USplineMeshComponent>(this, USplineMeshComponent::StaticClass(), TEXT("SplineMeshComponent"));
+	if (SplineMeshComponent)
+	{
+		SplineMeshComponent->SetupAttachment(this);
+		SplineMeshComponent->SetMobility(EComponentMobility::Movable);
+		SplineMeshComponent->RegisterComponent();
+		SplineMeshComponent->CreationMethod = EComponentCreationMethod::Instance;
+
+		if (SplineMesh)
+		{
+			SplineMeshComponent->SetStaticMesh(SplineMesh);
+		}
+		else
+		{
+			UE_LOG(LogTemp, Warning, TEXT("SplineMesh not set!"));
+		}
+
+		if (SplineMaterial)
+		{
+			SplineMeshComponent->SetMaterial(0, SplineMaterial);
+		}
+		else
+		{
+			UE_LOG(LogTemp, Warning, TEXT("SplineMesh material not set! Using default material instead."));
+		}
+
+		SplineMeshComponent->SetForwardAxis(ESplineMeshAxis::Z);
+		SplineMeshComponent->CastShadow = false;
+	}
+	else
+	{
+		UE_LOG(LogTemp, Error, TEXT("Error while spawning SplineMeshComponent!"))
+	}
+}
+
+void UIntenSelectComponent::InitForwardRayMeshComponent()
+{
+	ForwardRayMeshComponent =
+		NewObject<UStaticMeshComponent>(this, UStaticMeshComponent::StaticClass(), TEXT("ForwardRay"));
+
+	if (ForwardRayMeshComponent)
+	{
+		ForwardRayMeshComponent->SetupAttachment(this);
+		ForwardRayMeshComponent->SetMobility((EComponentMobility::Movable));
+		ForwardRayMeshComponent->RegisterComponent();
+		ForwardRayMeshComponent->CreationMethod = EComponentCreationMethod::Instance;
+
+		ForwardRayMeshComponent->SetCastShadow(false);
+		ForwardRayMeshComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
+
+		const float MeshLength = MaxSelectionDistance > 1000 ? 1000 : MaxSelectionDistance;
+		ForwardRayMeshComponent->SetRelativeScale3D(FVector(MeshLength, ForwardRayWidth, ForwardRayWidth));
+		ForwardRayMeshComponent->SetRelativeLocation(FVector(MeshLength * 50, 0, 0));
+
+		// const ConstructorHelpers::FObjectFinder<UStaticMesh> CubeMesh(TEXT("/Engine/BasicShapes/Cube.Cube"));
+		if (ForwardRayMesh)
+		{
+			ForwardRayMeshComponent->SetStaticMesh(ForwardRayMesh);
+		}
+		else
+		{
+			UE_LOG(LogTemp, Warning, TEXT("Mesh for RayComponent not set!"));
+		}
+
+		UMaterialInstanceDynamic* DynamicMaterial =
+			UMaterialInstanceDynamic::Create(ForwardRayMaterial, ForwardRayMeshComponent);
+		this->ForwardRayMeshComponent->SetMaterial(0, DynamicMaterial);
+
+		ForwardRayMeshComponent->SetHiddenInGame(!bDrawForwardRay);
+	}
+	else
+	{
+		UE_LOG(LogTemp, Error, TEXT("Error while spawning ForwardRayMesh component!"));
+	}
+}
+
+void UIntenSelectComponent::InitMaterialParamCollection()
+{
+	if (MaterialParamCollection)
+	{
+		this->ParameterCollectionInstance = GetWorld()->GetParameterCollectionInstance(MaterialParamCollection);
+		if (this->ParameterCollectionInstance)
+		{
+			this->ParameterCollectionInstance->SetScalarParameterValue("Transparency", DebugRayTransparency);
+		}
+		else
+		{
+			UE_LOG(LogTemp, Warning,
+				   TEXT("MaterialParameterCollection required for rendering of IntenSelect could not be found!"))
+		}
+	}
+	else
+	{
+		UE_LOG(LogTemp, Warning, TEXT("MaterialParameterCollection required for InteSelect visualization is not set!"));
+	}
+}
+
+void UIntenSelectComponent::InitDebugConeMeshComponent()
+{
+	DebugConeMeshComponent =
+		NewObject<UStaticMeshComponent>(this, UStaticMeshComponent::StaticClass(), TEXT("DebugCone"));
+
+	if (DebugConeMeshComponent)
+	{
+		DebugConeMeshComponent->SetupAttachment(this);
+		DebugConeMeshComponent->SetMobility(EComponentMobility::Movable);
+		DebugConeMeshComponent->RegisterComponent();
+		DebugConeMeshComponent->CreationMethod = EComponentCreationMethod::Instance;
+
+
+		FTransform ConeTransform = DebugConeMeshComponent->GetRelativeTransform();
+		const float ConeScale = MaxSelectionDistance / 50 * FMath::Tan(FMath::DegreesToRadians(SelectionConeAngle));
+		ConeTransform.SetScale3D(FVector(ConeScale, ConeScale, MaxSelectionDistance / 100));
+
+		DebugConeMeshComponent->SetRelativeTransform(ConeTransform);
+		DebugConeMeshComponent->SetRelativeLocation(FVector(MaxSelectionDistance - ConeBackwardShiftDistance, 0, 0),
+													false);
+		DebugConeMeshComponent->SetRelativeRotation(DebugConeRotation, false);
+		DebugConeMeshComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
+
+		if (DebugConeMesh)
+		{
+			DebugConeMeshComponent->SetStaticMesh(DebugConeMesh);
+		}
+		else
+		{
+			UE_LOG(LogTemp, Warning, TEXT("DebugCone mesh not set!"))
+		}
+		if (DebugConeMaterial)
+		{
+			DebugConeMeshComponent->SetMaterial(0, DebugConeMaterial);
+		}
+		else
+		{
+			UE_LOG(LogTemp, Warning, TEXT("DebugCone material not set! Using default material instead."))
+		}
+
+		DebugConeMeshComponent->SetVisibility(bDrawDebugCone);
+	}
+	else
+	{
+		UE_LOG(LogTemp, Error, TEXT("Error while spawning DebugCone component!"))
+	}
+}
+
+
+//				SCORING FUNCTIONS
+
+float UIntenSelectComponent::CalculateSphereCastRadius() const
+{
+	return FMath::Tan(FMath::DegreesToRadians(SelectionConeAngle)) * MaxSelectionDistance;
+}
+
+bool UIntenSelectComponent::CheckPointInCone(const FVector ConeStartPoint, const FVector ConeForward,
+											 const FVector PointToTest, const float Angle) const
+{
+	const FVector ShiftedStartOriginPoint = ConeStartPoint - (ConeForward * ConeBackwardShiftDistance);
+	const FVector DirectionToTestPoint = (PointToTest - ShiftedStartOriginPoint).GetSafeNormal();
+
+	const float AngleToTestPoint =
+		FMath::RadiansToDegrees(FMath::Acos((FVector::DotProduct(ConeForward, DirectionToTestPoint))));
+
+	return AngleToTestPoint <= Angle;
+}
+
+void UIntenSelectComponent::OnNewSelected_Implementation(UIntenSelectable* Selection)
+{
+	CurrentSelection = Selection;
+
+	if (FeedbackCooldown == 0)
+	{
+		// UGameplayStatics::GetPlayerController(GetWorld(), 0)->PlayHapticEffect(SelectionFeedbackHaptic,
+		// EControllerHand::Right, 0.1, false);
+		UGameplayStatics::PlaySound2D(GetWorld(), OnSelectSound);
+		FeedbackCooldown = 0.1;
+	}
+}
+
+bool UIntenSelectComponent::GetActorsFromSphereCast(const FVector& SphereCastStart, TArray<FHitResult>& OutHits) const
+{
+	const FVector StartPos =
+		SphereCastStart + (GetComponentTransform().GetRotation().GetForwardVector() * SphereCastRadius);
+	const FVector EndPos =
+		StartPos + (this->GetComponentTransform().GetRotation().GetForwardVector() * (MaxSelectionDistance));
+
+	const FCollisionQueryParams Params = FCollisionQueryParams(FName(TEXT("SphereTraceMultiForObjects")), false);
+	// GetWorld()->SweepMultiByChannel(OutHits, StartPos, EndPos, FQuat::Identity, ECC_Visibility,
+	// FCollisionShape::MakeSphere(SphereCastRadius), Params);
+
+	GetWorld()->SweepMultiByChannel(OutHits, StartPos, EndPos, FQuat::Identity, ECC_Visibility,
+									FCollisionShape::MakeSphere(SphereCastRadius), Params);
+	// UKismetSystemLibrary::SphereTraceMulti(GetWorld(),StartPos,EndPos,SphereCastRadius,ETraceTypeQuery::TraceTypeQuery1,false,{},EDrawDebugTrace::ForOneFrame,OutHits,true);
+	return true;
+}
+
+UIntenSelectable* UIntenSelectComponent::GetMaxScoreActor(const float DeltaTime)
+{
+	const FVector ConeOrigin = this->GetComponentTransform().GetLocation();
+	const FVector ConeForward = this->GetComponentTransform().GetRotation().GetForwardVector();
+
+	TArray<FHitResult> OutHits;
+	if (GetActorsFromSphereCast(ConeOrigin, OutHits))
+	{
+		for (const FHitResult& Hit : OutHits)
+		{
+			const FVector PointToCheck = Hit.ImpactPoint;
+			const float DistanceToActor = FVector::Dist(ConeOrigin, PointToCheck);
+
+			const AActor* HitActor = Hit.GetActor();
+			if (HitActor)
+			{
+				const auto Selectable = HitActor->FindComponentByClass<UIntenSelectable>();
+
+				if (Selectable && Selectable->IsSelectable && DistanceToActor <= MaxSelectionDistance)
+				{
+					ScoreMap.FindOrAdd(Selectable, 0);
+				}
+			}
+		}
+	}
+
+	UIntenSelectable* MaxScoreSelectable = nullptr;
+	float MaxScore = TNumericLimits<float>::Min();
+	TArray<UIntenSelectable*> RemoveList;
+	TArray<TPair<UIntenSelectable*, FHitResult>> CandidateList;
+
+	for (TTuple<UIntenSelectable*, float>& OldScoreEntry : ScoreMap)
+	{
+		// GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Black,  OldScoreEntry.Key->GetOwner()->GetName() + "
+		// - Score: " + FString::SanitizeFloat(OldScoreEntry.Value));
+		if (!OldScoreEntry.Key)
+		{
+			continue;
+		}
+
+		TPair<FHitResult, float> NewScorePair = OldScoreEntry.Key->GetBestPointScorePair(
+			ConeOrigin, ConeForward, ConeBackwardShiftDistance, SelectionConeAngle, OldScoreEntry.Value, DeltaTime);
+
+		ContactPointMap.Add(OldScoreEntry.Key, NewScorePair.Key);
+		const float DistanceToActor = FVector::Dist(ConeOrigin, NewScorePair.Key.ImpactPoint);
+
+		const float Eps = 0.01;
+		if (NewScorePair.Value <= 0.01 || DistanceToActor >= MaxSelectionDistance || !OldScoreEntry.Key->IsSelectable)
+		{
+			RemoveList.Add(OldScoreEntry.Key);
+		}
+		else
+		{
+			OldScoreEntry.Value = NewScorePair.Value;
+
+			if (NewScorePair.Value > (1.0 - Eps) &&
+				this->CheckPointInCone(ConeOrigin, ConeForward, NewScorePair.Key.ImpactPoint, SelectionConeAngle))
+			{
+				CandidateList.Emplace(OldScoreEntry.Key, NewScorePair.Key);
+				MaxScore = NewScorePair.Value;
+				MaxScoreSelectable = OldScoreEntry.Key;
+			}
+			else if (NewScorePair.Value > MaxScore &&
+					 this->CheckPointInCone(ConeOrigin, ConeForward, NewScorePair.Key.ImpactPoint, SelectionConeAngle))
+			{
+				MaxScore = NewScorePair.Value;
+				MaxScoreSelectable = OldScoreEntry.Key;
+			}
+		}
+	}
+
+	for (const UIntenSelectable* i : RemoveList)
+	{
+		ContactPointMap.Remove(i);
+		ScoreMap.Remove(i);
+	}
+	if (CandidateList.Num() > 0)
+	{
+		auto DistanceToMaxScore =
+			FVector::Distance(MaxScoreSelectable->GetOwner()->GetActorLocation(), GetComponentLocation());
+		auto Dist = TNumericLimits<float>::Max();
+		for (const TPair<UIntenSelectable*, FHitResult>& Actor : CandidateList)
+		{
+			const auto DistanceToCandidate = FVector::Distance(Actor.Value.ImpactPoint, GetComponentLocation());
+			if (DistanceToCandidate < Dist)
+			{
+				MaxScoreSelectable = Actor.Key;
+				Dist = DistanceToCandidate;
+			}
+		}
+	}
+
+	return MaxScoreSelectable;
+}
+//				RAYCASTING
+
+
+void UIntenSelectComponent::HandleWidgetInteraction()
+{
+	const FVector Forward = this->GetComponentTransform().GetRotation().GetForwardVector();
+	const FVector Origin = this->GetComponentTransform().GetLocation();
+
+	TOptional<FHitResult> Hit = RaytraceForFirstHit(Origin, Origin + Forward * MaxSelectionDistance);
+
+	if (!Hit.IsSet())
+	{
+		IsWidgetInFocus = false;
+		return;
+	}
+
+	SetCustomHitResult(Hit.GetValue());
+	UWidgetComponent* FocusedWidget = Cast<UWidgetComponent>(Hit.GetValue().GetComponent());
+	IsWidgetInFocus = (FocusedWidget != nullptr);
+
+
+	/*
+	if(IsWidgetInFocus)
+	{
+		if (FocusedWidget != LastFocusedWidget)
+		{
+			//We can always execute the enter event as we are sure that a hit occured
+			if (FocusedWidget->GetOwner()->Implements<UTargetable>())
+			{
+				ITargetable::Execute_OnTargetedEnter(FocusedWidget->GetOwner());
+			}
+
+			//Only execute the Leave Event if there was an actor that was focused previously
+			if (LastFocusedWidget != nullptr && LastFocusedWidget->GetOwner()->Implements<UTargetable>())
+			{
+				ITargetable::Execute_OnTargetedLeave(LastFocusedWidget->GetOwner());
+			}
+		}
+
+		// for now uses the same distance as clicking
+		if (FocusedWidget->GetOwner()->Implements<UTargetable>())
+		{
+			ITargetable::Execute_OnTargeted(FocusedWidget->GetOwner(), Hit->Location);
+		}
+		LastFocusedWidget = FocusedWidget;
+
+		if(FocusedWidget->GetOwner()->GetClass()->ImplementsInterface(UIntenSelectableWidget::StaticClass()))
+		{
+			FVector pos = IIntenSelectableWidget::Execute_GetCoordinates(FocusedWidget->GetOwner());
+			GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Black, "C++ Pos: " + pos.ToString());
+			WidgetFocusPoint = pos;
+		}else
+		{
+			GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Black, "C++ Pos not available");
+		}
+	}*/
+}
+
+TOptional<FHitResult> UIntenSelectComponent::RaytraceForFirstHit(const FVector& Start, const FVector& End) const
+{
+	// will be filled by the Line Trace Function
+	FHitResult Hit;
+
+	FCollisionQueryParams Params;
+	Params.AddIgnoredActor(GetOwner()->GetUniqueID()); // prevents actor hitting itself
+	if (GetWorld()->LineTraceSingleByChannel(Hit, Start, End, ECollisionChannel::ECC_Visibility, Params))
+	{
+		return {Hit};
+	}
+	else
+	{
+		return {};
+	}
+}
+
+
+//				VISUALS
+
+void UIntenSelectComponent::DrawSelectionCurve(const FVector& EndPoint) const
+{
+	const FVector StartPoint = this->GetComponentTransform().GetLocation();
+	const FVector Forward = this->GetComponentTransform().GetRotation().GetForwardVector();
+
+	SplineComponent->ClearSplinePoints(true);
+	SplineMeshComponent->SetHiddenInGame(false);
+
+	AddSplinePointsDefault(StartPoint, Forward, EndPoint);
+
+	const FVector StartPosition = SplineComponent->GetLocationAtSplinePoint(0, ESplineCoordinateSpace::Local);
+	const FVector StartTangent = SplineComponent->GetTangentAtSplinePoint(0, ESplineCoordinateSpace::Local);
+	const FVector EndPosition = SplineComponent->GetLocationAtSplinePoint(1, ESplineCoordinateSpace::Local);
+	const FVector EndTangent = SplineComponent->GetTangentAtSplinePoint(1, ESplineCoordinateSpace::Local);
+
+	SplineMeshComponent->SetStartAndEnd(StartPosition, StartTangent, EndPosition, EndTangent, true);
+}
+
+void UIntenSelectComponent::AddSplinePointsDefault(const FVector& StartPoint, const FVector& Forward,
+												   const FVector& EndPoint) const
+{
+	SplineComponent->AddSplineWorldPoint(StartPoint);
+
+	const FVector StartToEnd = EndPoint - StartPoint;
+	const FVector ForwardProjection = StartToEnd.ProjectOnTo(Forward);
+
+	SplineComponent->AddSplineWorldPoint(EndPoint);
+
+	SplineComponent->SetSplinePointType(0, ESplinePointType::Curve, true);
+	SplineComponent->SetSplinePointType(1, ESplinePointType::Curve, true);
+
+	SplineComponent->SetTangentAtSplinePoint(0, Forward * ForwardProjection.Size() * SplineCurvatureStrength,
+											 ESplineCoordinateSpace::World, true);
+	SplineComponent->SetTangentAtSplinePoint(1, StartToEnd.GetSafeNormal(), ESplineCoordinateSpace::World, true);
+}
+
+void UIntenSelectComponent::UpdateForwardRay(const FVector& ReferencePoint) const
+{
+	if (ForwardRayTransparencyCurve)
+	{
+		const FVector ConeForward = this->GetComponentTransform().GetRotation().GetForwardVector();
+		const FVector ConeOrigin =
+			this->GetComponentTransform().GetLocation() - (ConeForward * ConeBackwardShiftDistance);
+
+		const FVector TestPointVector = (ReferencePoint - ConeOrigin).GetSafeNormal();
+		const float AngleToTestPoint =
+			FMath::RadiansToDegrees(FMath::Acos((FVector::DotProduct(ConeForward, TestPointVector))));
+
+		const float NewTransparency =
+			ForwardRayTransparencyCurve->GetFloatValue(AngleToTestPoint / SelectionConeAngle) * DebugRayTransparency;
+		ParameterCollectionInstance->SetScalarParameterValue("Transparency", NewTransparency);
+	}
+}
+
+//				INPUT-HANDLING
+
+void UIntenSelectComponent::OnFireDown()
+{
+	// start interaction of WidgetInteractionComponent
+	PressPointerKey(EKeys::LeftMouseButton);
+
+	if (!CurrentSelection)
+	{
+		return;
+	}
+
+	if (CurrentSelection)
+	{
+		const FHitResult GrabbedPoint = *ContactPointMap.Find(CurrentSelection);
+		CurrentSelection->HandleOnClickStartEvents(this);
+		LastKnownSelection = CurrentSelection;
+		LastKnownGrabPoint =
+			LastKnownSelection->GetOwner()->GetRootComponent()->GetComponentTransform().InverseTransformPosition(
+				GrabbedPoint.ImpactPoint);
+	}
+	else
+	{
+		LastKnownSelection = nullptr;
+	}
+
+	IsGrabbing = true;
+
+	if (bDrawForwardRay && ParameterCollectionInstance)
+	{
+		ParameterCollectionInstance->SetScalarParameterValue("Transparency", 0);
+	}
+}
+
+void UIntenSelectComponent::OnFireUp()
+{
+	// end interaction of WidgetInteractionComponent
+	ReleasePointerKey(EKeys::LeftMouseButton);
+
+	IsGrabbing = false;
+
+	if (LastKnownSelection)
+	{
+		FInputActionValue v;
+		LastKnownSelection->HandleOnClickEndEvents(this, v);
+	}
+}
+
+//				SELECTION-HANDLING
+
+void UIntenSelectComponent::SelectObject(UIntenSelectable* SelectableComponent, AActor* SelectedBy)
+{
+	CurrentSelection = SelectableComponent;
+}
+
+void UIntenSelectComponent::Unselect()
+{
+	IsGrabbing = false;
+
+	SplineMeshComponent->SetHiddenInGame(true);
+
+	CurrentSelection = nullptr;
+	this->CurrentSelection = nullptr;
+}
+
+void UIntenSelectComponent::SetActive(bool bNewActive, bool bReset)
+{
+	if (bNewActive)
+	{
+		ForwardRayMeshComponent->SetVisibility(true);
+		SplineMeshComponent->SetVisibility(true);
+
+		Super::SetActive(true, bReset);
+	}
+	else
+	{
+		if (CurrentSelection)
+		{
+			HandleNoActorSelected();
+		}
+
+		if (LastKnownSelection)
+		{
+			OnFireUp();
+		}
+
+		ForwardRayMeshComponent->SetVisibility(false);
+		SplineMeshComponent->SetVisibility(false);
+
+		Super::SetActive(false, bReset);
+	}
+}
+
+//				TICK
+
+void UIntenSelectComponent::HandleCooldown(const float DeltaTime)
+{
+	if (FeedbackCooldown > 0)
+	{
+		FeedbackCooldown -= DeltaTime;
+	}
+	else
+	{
+		FeedbackCooldown = 0;
+	}
+}
+
+void UIntenSelectComponent::HandleGrabbing(const float DeltaTime) const {}
+
+void UIntenSelectComponent::HandleActorSelected(UIntenSelectable* NewSelection)
+{
+	if (NewSelection != CurrentSelection)
+	{
+		if (CurrentSelection)
+		{
+			CurrentSelection->HandleOnSelectEndEvents(this);
+		}
+
+		if (NewSelection)
+		{
+			UIntenSelectable* NewIntenSelectable = NewSelection;
+			const FHitResult GrabbedPoint = *ContactPointMap.Find(NewIntenSelectable);
+			NewIntenSelectable->HandleOnSelectStartEvents(this, GrabbedPoint);
+		}
+
+		CurrentSelection = NewSelection;
+		OnNewSelected(NewSelection);
+	}
+
+	if (CurrentSelection)
+	{
+		const UIntenSelectable* NewIntenSelectable = NewSelection;
+		const auto V_Net = ContactPointMap.Find(NewIntenSelectable)->ImpactPoint;
+		const FVector PointToDrawTo = ConvertNetVector(V_Net);
+
+		if (bDrawForwardRay)
+		{
+			UpdateForwardRay(PointToDrawTo);
+		}
+
+		DrawSelectionCurve(PointToDrawTo);
+	}
+}
+
+FVector UIntenSelectComponent::ConvertNetVector(FVector_NetQuantize v)
+{
+	FVector Result;
+	Result.X = v.X;
+	Result.Y = v.Y;
+	Result.Z = v.Z;
+	return Result;
+}
+
+
+void UIntenSelectComponent::HandleNoActorSelected()
+{
+	SplineMeshComponent->SetHiddenInGame(true);
+
+	if (CurrentSelection)
+	{
+		CurrentSelection->HandleOnSelectEndEvents(this);
+	}
+
+	if (bDrawForwardRay && ParameterCollectionInstance)
+	{
+		ParameterCollectionInstance->SetScalarParameterValue("Transparency", DebugRayTransparency);
+	}
+	CurrentSelection = nullptr;
+}
+
+void UIntenSelectComponent::TickComponent(const float DeltaTime, const ELevelTick TickType,
+										  FActorComponentTickFunction* ThisTickFunction)
+{
+	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
+
+	this->HandleCooldown(DeltaTime);
+	UIntenSelectable* const NewSelection = GetMaxScoreActor(DeltaTime);
+
+	if (IsGrabbing && LastKnownSelection)
+	{
+		const FVector GrabPointWorld =
+			LastKnownSelection->GetOwner()->GetRootComponent()->GetComponentTransform().TransformPosition(
+				LastKnownGrabPoint);
+		DrawSelectionCurve(GrabPointWorld);
+
+		const FVector ConeOrigin = this->GetComponentLocation();
+		const FVector ConeForward = this->GetForwardVector().GetSafeNormal();
+
+		if (!this->CheckPointInCone(ConeOrigin, ConeForward, GrabPointWorld, MaxClickStickAngle))
+		{
+			OnFireUp();
+		}
+
+		return;
+	}
+	else if (CurrentSelection && ContactPointMap.Contains(CurrentSelection))
+	{
+		const FVector GrabbedPoint = ConvertNetVector(ContactPointMap.Find(CurrentSelection)->ImpactPoint);
+		DrawSelectionCurve(GrabbedPoint);
+	}
+
+	// this->HandleWidgetInteraction();
+	IsWidgetInFocus = false;
+	if (IsWidgetInFocus)
+	{
+		// GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Red, "Widget focused");
+		HandleNoActorSelected();
+
+		const FVector PointToDrawTo = WidgetFocusPoint;
+
+		if (bDrawForwardRay)
+		{
+			UpdateForwardRay(PointToDrawTo);
+		}
+
+		DrawSelectionCurve(PointToDrawTo);
+	}
+	else
+	{
+		if (NewSelection)
+		{
+			// GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Red, "Focused Actor:" + NewSelection->GetName());
+			HandleActorSelected(NewSelection);
+		}
+		else
+		{
+			// GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Red, "No Actor in Focus");
+			HandleNoActorSelected();
+		}
+	}
+}
diff --git a/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp b/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp
index f644f4add3b96e08f66f28a873e57fba8a504dbd..b565b58a43154ece41c681a371434770e5171d60 100644
--- a/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp
+++ b/Source/RWTHVRToolkit/Private/Pawn/Navigation/CollisionHandlingMovement.cpp
@@ -67,13 +67,21 @@ void UCollisionHandlingMovement::TickComponent(float DeltaTime, enum ELevelTick
 			}
 		}
 
+		// in case we are in a collision and collision checks are temporarily deactivated, we only allow physical
+		// movement without any checks, otherwise check collision during physical movement
+		if (bCollisionChecksTemporarilyDeactivated)
+		{
+			ConsumeInputVector();
+		}
+		else
+		{
+			// so we add stepping-up (for both walk and fly)
+			// and gravity for walking only
+			MoveByGravityOrStepUp(DeltaTime);
 
-		// so we add stepping-up (for both walk and fly)
-		// and gravity for walking only
-		MoveByGravityOrStepUp(DeltaTime);
-
-		// if we physically (in the tracking space) walked into something, move the world away (by moving the pawn)
-		CheckForPhysWalkingCollision();
+			// if we physically (in the tracking space) walked into something, move the world away (by moving the pawn)
+			CheckForPhysWalkingCollision();
+		}
 	}
 
 	if (NavigationMode == EVRNavigationModes::NAV_NONE)
@@ -150,6 +158,7 @@ void UCollisionHandlingMovement::CheckAndRevertCollisionSinceLastTick()
 		if (!CreateCapsuleTrace(CapsuleLocation, CapsuleLocation).bBlockingHit)
 		{
 			LastCollisionFreeCapsulePosition = CapsuleLocation;
+			bCollisionChecksTemporarilyDeactivated = false;
 		}
 		return;
 	}
@@ -157,8 +166,18 @@ void UCollisionHandlingMovement::CheckAndRevertCollisionSinceLastTick()
 	// check whether we are in a collision at the current position
 	if (CreateCapsuleTrace(CapsuleLocation, CapsuleLocation).bBlockingHit)
 	{
-		// if so move back to last position
-		UpdatedComponent->AddWorldOffset(LastCollisionFreeCapsulePosition.GetValue() - CapsuleLocation);
+		// if so move back to last position, but only if that position is still collision free
+		// since the user might have moveed physically in between
+		FVector LastCapsulePos = LastCollisionFreeCapsulePosition.GetValue();
+		if (!CreateCapsuleTrace(LastCapsulePos, LastCapsulePos).bBlockingHit)
+		{
+			UpdatedComponent->AddWorldOffset(LastCapsulePos - CapsuleLocation);
+		}
+		else
+		{
+			bCollisionChecksTemporarilyDeactivated = true;
+			LastCollisionFreeCapsulePosition.Reset();
+		}
 	}
 	else
 	{
@@ -175,6 +194,13 @@ void UCollisionHandlingMovement::MoveOutOfNewDynamicCollisions()
 		FVector ResolveDirection = 1.5f * ResolveDirectionOptional.GetValue(); // scale it up for security distance
 		UpdatedComponent->AddWorldOffset(ResolveDirection);
 
+		// check whether this helped in resolving the collision, and if not deactivate collision checks temporarily
+		if (CreateCapsuleTrace(UpdatedComponent->GetComponentLocation(), UpdatedComponent->GetComponentLocation())
+				.bBlockingHit)
+		{
+			bCollisionChecksTemporarilyDeactivated = true;
+		}
+
 		// invalidate the last collision-free position, since apparently something changed so we got into this collision
 		LastCollisionFreeCapsulePosition.Reset();
 	}
@@ -195,8 +221,8 @@ void UCollisionHandlingMovement::CheckForPhysWalkingCollision()
 	if (HitResult.bBlockingHit)
 	{
 		const FVector MoveOutVector = HitResult.Location - CapsuleLocation;
-		// move it out twice as far, to avoid getting stuck situations
-		UpdatedComponent->AddWorldOffset(2 * MoveOutVector);
+		// move it out a bit farther, to avoid getting stuck situations
+		UpdatedComponent->AddWorldOffset(1.2f * MoveOutVector);
 	}
 }
 
@@ -316,19 +342,18 @@ TOptional<FVector> UCollisionHandlingMovement::GetOverlapResolveDirection() cons
 {
 	TArray<UPrimitiveComponent*> OverlappingComponents;
 	TArray<TEnumAsByte<EObjectTypeQuery>> traceObjectTypes;
-	traceObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_Visibility));
+
+	// Ideally we would overlap with ECC_Visibility, but there is no object type this can be converted to that I know
+	// of. This returns everything, even triggers etc that are *not* visible, which is why we further check for a
+	// visibility trace and blocking hits.
+	traceObjectTypes.Add(EObjectTypeQuery::ObjectTypeQuery_MAX);
+
 	UKismetSystemLibrary::CapsuleOverlapComponents(GetWorld(), CapsuleColliderComponent->GetComponentLocation(),
 												   CapsuleColliderComponent->GetScaledCapsuleRadius(),
 												   CapsuleColliderComponent->GetScaledCapsuleHalfHeight(),
 												   traceObjectTypes, nullptr, ActorsToIgnore, OverlappingComponents);
 
-	if (OverlappingComponents.Num() == 0)
-	{
-		// return unset optional
-		return TOptional<FVector>();
-	}
-
-	FVector ResolveVector = FVector::ZeroVector;
+	TOptional<FVector> ResolveVector;
 	// check what to do to move out of these collisions (or nothing if none is there)
 	// we just add the penetrations so in very unfortunate conditions this can become problematic/blocking but for now
 	// and our regular use cases this works
@@ -336,7 +361,13 @@ TOptional<FVector> UCollisionHandlingMovement::GetOverlapResolveDirection() cons
 	{
 		FHitResult Hit = CreateCapsuleTrace(CapsuleColliderComponent->GetComponentLocation(),
 											OverlappingComp->GetComponentLocation(), false);
-		ResolveVector += Hit.ImpactNormal * Hit.PenetrationDepth;
+
+		if (Hit.bBlockingHit)
+		{
+			FVector Change = Hit.ImpactNormal * Hit.PenetrationDepth;
+			ResolveVector = ResolveVector.IsSet() ? ResolveVector.GetValue() + Change : Change;
+		}
 	}
+
 	return ResolveVector;
 }
diff --git a/Source/RWTHVRToolkit/Private/Pawn/Navigation/ContinuousMovementComponent.cpp b/Source/RWTHVRToolkit/Private/Pawn/Navigation/ContinuousMovementComponent.cpp
index 9954fc63fe80c2c19602fdd77ee2c52e1bffd848..fa07db5dd9dd15f582728d56ccbd7bff5b81eaf3 100644
--- a/Source/RWTHVRToolkit/Private/Pawn/Navigation/ContinuousMovementComponent.cpp
+++ b/Source/RWTHVRToolkit/Private/Pawn/Navigation/ContinuousMovementComponent.cpp
@@ -3,17 +3,17 @@
 #include "Pawn/Navigation/ContinuousMovementComponent.h"
 
 #include "EnhancedInputComponent.h"
-#include "EnhancedInputSubsystems.h"
 #include "Engine/LocalPlayer.h"
 #include "GameFramework/PlayerController.h"
 #include "Utility/RWTHVRUtilities.h"
 #include "MotionControllerComponent.h"
+#include "Camera/CameraComponent.h"
 
 void UContinuousMovementComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent)
 {
 	Super::SetupPlayerInput(PlayerInputComponent);
 
-	if (!VRPawn || !VRPawn->HasLocalNetOwner() || !InputSubsystem)
+	if (!VRPawn || !VRPawn->HasLocalNetOwner())
 	{
 		return;
 	}
@@ -23,18 +23,13 @@ void UContinuousMovementComponent::SetupPlayerInput(UInputComponent* PlayerInput
 	{
 		MovementHand = VRPawn->RightHand;
 		RotationHand = VRPawn->LeftHand;
-		IMCMovement = IMCMovementRight;
 	}
 	else
 	{
 		MovementHand = VRPawn->LeftHand;
 		RotationHand = VRPawn->RightHand;
-		IMCMovement = IMCMovementLeft;
 	}
 
-	// add Input Mapping context
-	InputSubsystem->AddMappingContext(IMCMovement, 0);
-
 	UEnhancedInputComponent* EI = Cast<UEnhancedInputComponent>(PlayerInputComponent);
 	if (!EI)
 	{
diff --git a/Source/RWTHVRToolkit/Private/Pawn/Navigation/MovementComponentBase.cpp b/Source/RWTHVRToolkit/Private/Pawn/Navigation/MovementComponentBase.cpp
index 48562102b52c22c22b8f6f874e451f74d150534e..2020468fb5fcaefc05c91b8d49dd498f42bfedd7 100644
--- a/Source/RWTHVRToolkit/Private/Pawn/Navigation/MovementComponentBase.cpp
+++ b/Source/RWTHVRToolkit/Private/Pawn/Navigation/MovementComponentBase.cpp
@@ -3,27 +3,13 @@
 
 #include "Pawn/Navigation/MovementComponentBase.h"
 
-#include "EnhancedInputSubsystems.h"
 #include "Engine/LocalPlayer.h"
 #include "GameFramework/PlayerController.h"
 #include "Pawn/RWTHVRPawn.h"
-#include "Utility/RWTHVRUtilities.h"
 
 void UMovementComponentBase::SetupPlayerInput(UInputComponent* PlayerInputComponent)
 {
 	IInputExtensionInterface::SetupPlayerInput(PlayerInputComponent);
 
 	VRPawn = Cast<ARWTHVRPawn>(GetOwner());
-
-	if (!VRPawn || !VRPawn->HasLocalNetOwner())
-	{
-		return;
-	}
-
-	InputSubsystem = GetEnhancedInputLocalPlayerSubsystem(VRPawn);
-	if (!InputSubsystem)
-	{
-		UE_LOG(Toolkit, Error, TEXT("InputSubsystem IS NOT VALID"));
-		return;
-	}
 }
diff --git a/Source/RWTHVRToolkit/Private/Pawn/Navigation/TeleportationComponent.cpp b/Source/RWTHVRToolkit/Private/Pawn/Navigation/TeleportationComponent.cpp
index 3e1e14b8f4ab4bf57ad956550afa9059ff93162a..3a1a7e054daf3e2f3e544313ee8505316ada9ff5 100644
--- a/Source/RWTHVRToolkit/Private/Pawn/Navigation/TeleportationComponent.cpp
+++ b/Source/RWTHVRToolkit/Private/Pawn/Navigation/TeleportationComponent.cpp
@@ -4,7 +4,6 @@
 #include "Pawn/Navigation/TeleportationComponent.h"
 
 #include "EnhancedInputComponent.h"
-#include "EnhancedInputSubsystems.h"
 #include "NavigationSystem.h"
 #include "Engine/LocalPlayer.h"
 #include "GameFramework/PlayerController.h"
@@ -19,7 +18,7 @@ void UTeleportationComponent::SetupPlayerInput(UInputComponent* PlayerInputCompo
 {
 	Super::SetupPlayerInput(PlayerInputComponent);
 
-	if (!VRPawn || !VRPawn->HasLocalNetOwner() || !InputSubsystem)
+	if (!VRPawn || !VRPawn->HasLocalNetOwner())
 	{
 		return;
 	}
@@ -28,14 +27,16 @@ void UTeleportationComponent::SetupPlayerInput(UInputComponent* PlayerInputCompo
 		GetWorld(), TeleportTraceSystem, VRPawn->GetActorLocation(), FRotator(0), FVector(1), true, true,
 		ENCPoolMethod::AutoRelease, true);
 
-	FActorSpawnParameters SpawnParameters = FActorSpawnParameters();
-	SpawnParameters.Name = "TeleportVisualizer";
-
-	if (BPTeleportVisualizer)
+	if (!BPTeleportVisualizer)
 	{
-		TeleportVisualizer = GetWorld()->SpawnActor<AActor>(BPTeleportVisualizer, VRPawn->GetActorLocation(),
-															VRPawn->GetActorRotation(), SpawnParameters);
+		UE_LOG(Toolkit, Error,
+			   TEXT("SetupPlayerInput: BPTeleportVisualizer must be set to an Actor class that can be spawned!"));
+		return;
 	}
+
+	TeleportVisualizer =
+		GetWorld()->SpawnActor<AActor>(BPTeleportVisualizer, VRPawn->GetActorLocation(), VRPawn->GetActorRotation());
+
 	TeleportTraceComponent->SetVisibility(false);
 	TeleportVisualizer->SetActorHiddenInGame(true);
 
@@ -44,18 +45,13 @@ void UTeleportationComponent::SetupPlayerInput(UInputComponent* PlayerInputCompo
 	{
 		TeleportationHand = VRPawn->RightHand;
 		RotationHand = VRPawn->LeftHand;
-		IMCMovement = IMCTeleportRight;
 	}
 	else
 	{
 		TeleportationHand = VRPawn->LeftHand;
 		RotationHand = VRPawn->RightHand;
-		IMCMovement = IMCTeleportLeft;
 	}
 
-	// add Input Mapping context
-	InputSubsystem->AddMappingContext(IMCMovement, 0);
-
 	UEnhancedInputComponent* EI = Cast<UEnhancedInputComponent>(PlayerInputComponent);
 	if (!EI)
 	{
diff --git a/Source/RWTHVRToolkit/Private/Pawn/Navigation/TurnComponent.cpp b/Source/RWTHVRToolkit/Private/Pawn/Navigation/TurnComponent.cpp
index 31e57513a8de14a7f2aab645ef6ec69a497d0bf4..bcf78e6bd57870bc4e3aef0bbeccb3b730aa0f0e 100644
--- a/Source/RWTHVRToolkit/Private/Pawn/Navigation/TurnComponent.cpp
+++ b/Source/RWTHVRToolkit/Private/Pawn/Navigation/TurnComponent.cpp
@@ -4,7 +4,6 @@
 #include "Pawn/Navigation/TurnComponent.h"
 
 #include "EnhancedInputComponent.h"
-#include "EnhancedInputSubsystems.h"
 #include "Pawn/RWTHVRPawn.h"
 #include "Utility/RWTHVRUtilities.h"
 
@@ -12,7 +11,7 @@ void UTurnComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent)
 {
 	Super::SetupPlayerInput(PlayerInputComponent);
 
-	if (!VRPawn || !VRPawn->HasLocalNetOwner() || !InputSubsystem)
+	if (!VRPawn || !VRPawn->HasLocalNetOwner())
 	{
 		return;
 	}
@@ -21,22 +20,12 @@ void UTurnComponent::SetupPlayerInput(UInputComponent* PlayerInputComponent)
 	if (bTurnWithLeftHand)
 	{
 		RotationHand = VRPawn->LeftHand;
-		// we use the same IMC for movement and turning
-		// therefore if we move with the right hand, we turn with the left hand
-		IMCTurn = IMCMovement_Right;
 	}
 	else
 	{
 		RotationHand = VRPawn->RightHand;
-		// we use the same IMC for movement and turning
-		// therefore if we move with the left hand, we turn with the right hand
-		IMCTurn = IMCMovement_Left;
 	}
 
-	// add Input Mapping context
-	InputSubsystem->AddMappingContext(URWTHVRUtilities::IsDesktopMode() ? IMCDesktopRotation : IMCTurn, 0);
-
-
 	UEnhancedInputComponent* EI = Cast<UEnhancedInputComponent>(PlayerInputComponent);
 	if (!EI)
 	{
diff --git a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp
index eee711326be2929cae7f232537c7dc74c37d42c6..56d56cf05728cc0ce2140f47d0b39a19e0dc665c 100644
--- a/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp
+++ b/Source/RWTHVRToolkit/Private/Pawn/RWTHVRPawn.cpp
@@ -2,6 +2,7 @@
 
 #include "Pawn/RWTHVRPawn.h"
 
+#include "EnhancedInputSubsystems.h"
 #include "Engine/LocalPlayer.h"
 #include "GameFramework/PlayerController.h"
 #include "ILiveLinkClient.h"
@@ -77,9 +78,13 @@ void ARWTHVRPawn::NotifyControllerChanged()
 			// If we are also the authority (standalone or listen server), directly attach it to us.
 			// If we are not (client), ask the server to do it.
 			if (HasAuthority())
+			{
 				AttachDCRAtoPawn();
+			}
 			else
+			{
 				ServerAttachDCRAtoPawnRpc();
+			}
 		}
 	}
 }
@@ -88,6 +93,8 @@ void ARWTHVRPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponen
 {
 	Super::SetupPlayerInputComponent(PlayerInputComponent);
 
+	ActivePlayerInputComponent = PlayerInputComponent;
+
 	APlayerController* PlayerController = Cast<APlayerController>(GetController());
 	if (!PlayerController)
 	{
@@ -132,6 +139,42 @@ void ARWTHVRPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponen
 	{
 		Cast<IInputExtensionInterface>(Comp)->SetupPlayerInput(PlayerInputComponent);
 	}
+
+	// bind the current mapping contexts
+	for (const auto& Mapping : InputMappingContexts)
+	{
+		AddInputMappingContext(PlayerController, Mapping);
+	}
+}
+
+UInputComponent* ARWTHVRPawn::GetPlayerInputComponent() { return ActivePlayerInputComponent; }
+
+
+void ARWTHVRPawn::AddInputMappingContext(const APlayerController* PC, const UInputMappingContext* Context) const
+{
+	if (Context)
+	{
+		if (const ULocalPlayer* LP = PC->GetLocalPlayer())
+		{
+			if (UEnhancedInputLocalPlayerSubsystem* InputSub = LP->GetSubsystem<UEnhancedInputLocalPlayerSubsystem>())
+			{
+				InputSub->AddMappingContext(Context, 0);
+			}
+			else
+			{
+				UE_LOGFMT(Toolkit, Warning,
+						  "ARWTHVRPawn::AddInputMappingContext: UEnhancedInputLocalPlayerSubsystem is nullptr!");
+			}
+		}
+		else
+		{
+			UE_LOGFMT(Toolkit, Warning, "ARWTHVRPawn::AddInputMappingContext: LocalPlayer is nullptr!");
+		}
+	}
+	else
+	{
+		UE_LOGFMT(Toolkit, Warning, "ARWTHVRPawn::AddInputMappingContext: Context is nullptr!");
+	}
 }
 
 void ARWTHVRPawn::EvaluateLivelink() const
@@ -151,7 +194,9 @@ void ARWTHVRPawn::EvaluateLivelink() const
 																		  HeadSubjectRepresentation.Role, SubjectData);
 
 		if (!bHasValidData)
+		{
 			return;
+		}
 
 		// Assume we are using a Transform Role to track the components! This is a slightly dangerous assumption, and
 		// could be further improved.
@@ -205,7 +250,6 @@ void ARWTHVRPawn::AttachDCRAtoPawn()
 	{
 		const auto CaveSetupActor = FoundActors[0];
 		FAttachmentTransformRules AttachmentRules = FAttachmentTransformRules::SnapToTargetNotIncludingScale;
-		AttachmentRules.RotationRule = EAttachmentRule::KeepWorld;
 		CaveSetupActor->AttachToActor(this, AttachmentRules);
 		UE_LOGFMT(Toolkit, Display, "VirtualRealityPawn: Attaching CaveSetup to our pawn!");
 	}
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/GrabBehavior.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/GrabBehavior.h
index 9978823ad96b612d920c6135886d333717a90d7a..d10affdff4aa25e2e4c22818219375580f342c8f 100644
--- a/Source/RWTHVRToolkit/Public/Interaction/Interactables/GrabBehavior.h
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/GrabBehavior.h
@@ -8,6 +8,12 @@
 #include "GrabBehavior.generated.h"
 
 
+DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnGrabStart, USceneComponent*, NewAttachParent, UPrimitiveComponent*,
+											 HeldComponent);
+
+DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnGrabEnd, USceneComponent*, PreviousAttachParent, UPrimitiveComponent*,
+											 HeldComponent);
+
 UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
 class RWTHVRTOOLKIT_API UGrabBehavior : public UActionBehaviour
 {
@@ -22,6 +28,19 @@ public:
 	virtual void OnActionEnd(USceneComponent* TriggeredComponent, const UInputAction* InputAction,
 							 const FInputActionValue& Value) override;
 
+
+	/**
+	 * Called after the object was successfully attached to the hand
+	 */
+	UPROPERTY(BlueprintAssignable)
+	FOnGrabStart OnGrabStartEvent;
+
+	/**
+	 * Called after the object was successfully detached from the hand
+	 */
+	UPROPERTY(BlueprintAssignable)
+	FOnGrabEnd OnGrabEndEvent;
+
 	UPrimitiveComponent* GetFirstComponentSimulatingPhysics(const AActor* TargetActor);
 
 	// recursively goes up the hierarchy and returns the highest parent simulating physics
@@ -29,4 +48,20 @@ public:
 
 	UPROPERTY()
 	UPrimitiveComponent* MyPhysicsComponent;
+
+	UFUNCTION(BlueprintPure)
+	bool IsObjectGrabbed() const { return bObjectGrabbed; }
+
+private:
+	/**
+	 * Try to detach the object from the hand. Keep this private for now as this does not broadcast the GrabEnd Event
+	 * correctly.
+	 * @return true if object was successfully detached. If detachment failed or if object was not grabbed before,
+	 * return false.
+	 */
+	bool TryRelease();
+
+	bool bObjectGrabbed = false;
+
+	bool bWasSimulatingPhysics;
 };
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectable.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectable.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea8fccb95d7a1fad3a1a5e87ed78ea2a50c90861
--- /dev/null
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectable.h
@@ -0,0 +1,53 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "InputActionValue.h"
+#include "Components/ActorComponent.h"
+#include "IntenSelectable.generated.h"
+
+
+class UIntenSelectableScoring;
+class UClickBehaviour;
+class USelectionBehaviour;
+class UIntenSelectComponent;
+
+UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
+class RWTHVRTOOLKIT_API UIntenSelectable : public UActorComponent
+{
+	GENERATED_BODY()
+
+public:
+	UPROPERTY(EditAnywhere, BlueprintReadWrite)
+	bool IsSelectable = true;
+
+	UPROPERTY(EditAnywhere, BlueprintReadWrite)
+	UIntenSelectableScoring* ScoringBehaviour;
+
+	UPROPERTY(EditAnywhere, BlueprintReadWrite)
+	TArray<UHoverBehaviour*> OnSelectBehaviours;
+
+	UPROPERTY(EditAnywhere, BlueprintReadWrite)
+	TArray<UActionBehaviour*> OnClickBehaviours;
+
+
+public:
+	UIntenSelectable();
+
+	TPair<FHitResult, float> GetBestPointScorePair(const FVector& ConeOrigin, const FVector& ConeForwardDirection,
+												   const float ConeBackwardShiftDistance, const float ConeAngle,
+												   const float LastValue, const float DeltaTime) const;
+
+	void HandleOnSelectStartEvents(const UIntenSelectComponent* IntenSelect, const FHitResult& HitResult);
+	void HandleOnSelectEndEvents(const UIntenSelectComponent* IntenSelect);
+	void HandleOnClickStartEvents(UIntenSelectComponent* IntenSelect);
+	void HandleOnClickEndEvents(UIntenSelectComponent* IntenSelect, FInputActionValue& InputValue);
+
+	void InitDefaultBehaviourReferences();
+
+	void ShowErrorAndQuit(const FString& Message) const;
+
+protected:
+	virtual void BeginPlay() override;
+};
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableCircleScoring.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableCircleScoring.h
new file mode 100644
index 0000000000000000000000000000000000000000..28046b36670ec03e2f8333b7a46d8d4d50ff6c28
--- /dev/null
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableCircleScoring.h
@@ -0,0 +1,30 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "IntenSelectableScoring.h"
+#include "IntenSelectableCircleScoring.generated.h"
+
+UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
+class RWTHVRTOOLKIT_API UIntenSelectableCircleScoring : public UIntenSelectableScoring
+{
+	GENERATED_BODY()
+
+protected:
+	FVector GetClosestSelectionPointTo(const FVector& Point, const FVector& Direction) const;
+
+public:
+	UIntenSelectableCircleScoring();
+
+	UPROPERTY(EditAnywhere)
+	bool OnlyOutline = true;
+
+	UPROPERTY(EditAnywhere)
+	float Radius = 50;
+
+	virtual TPair<FHitResult, float> GetBestPointScorePair(const FVector& ConeOrigin,
+														   const FVector& ConeForwardDirection,
+														   const float ConeBackwardShiftDistance, const float ConeAngle,
+														   const float LastValue, const float DeltaTime) override;
+};
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableCubeScoring.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableCubeScoring.h
new file mode 100644
index 0000000000000000000000000000000000000000..34d8b637040fbfd282cfaeeea6b4891eb4f50e7d
--- /dev/null
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableCubeScoring.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include "CoreMinimal.h"
+#include "IntenSelectableScoring.h"
+#include "IntenSelectableCubeScoring.generated.h"
+
+UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
+class RWTHVRTOOLKIT_API UIntenSelectableCubeScoring : public UIntenSelectableScoring
+{
+	GENERATED_BODY()
+
+protected:
+	static bool LineToLineIntersection(const FVector& FromA, const FVector& FromB, const FVector& ToA,
+									   const FVector& ToB, FVector& OutIntersection);
+
+	FVector GetClosestSelectionPointTo(const FVector& RayOrigin, const FVector& RayDirection);
+
+	virtual void TickComponent(float DeltaTime, ELevelTick TickType,
+							   FActorComponentTickFunction* ThisTickFunction) override;
+
+public:
+	UIntenSelectableCubeScoring();
+
+	UPROPERTY(EditAnywhere)
+	bool DrawDebug = true;
+
+	UPROPERTY(EditAnywhere)
+	bool BackFaceCulling = false;
+
+	UPROPERTY(EditAnywhere)
+	bool OnlyOutline = false;
+
+	// UPROPERTY(EditAnywhere)
+	// float XLength = 100;
+
+	// UPROPERTY(EditAnywhere)
+	// float YLength = 100;
+
+	// UPROPERTY(EditAnywhere)
+	// float ZLength = 100;
+
+	virtual TPair<FHitResult, float> GetBestPointScorePair(const FVector& ConeOrigin,
+														   const FVector& ConeForwardDirection,
+														   const float ConeBackwardShiftDistance, const float ConeAngle,
+														   const float LastValue, const float DeltaTime) override;
+
+	FVector GetClosestPointToRectangle(const FVector& StartPoint, const FVector& Direction, const FVector& Corner00,
+									   const FVector& Corner01, const FVector& Corner10, const FVector& Corner11) const;
+};
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableCylinderScoring.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableCylinderScoring.h
new file mode 100644
index 0000000000000000000000000000000000000000..d32e6a1ef1bc20489f1d2aa7046b2d2b101ec6b9
--- /dev/null
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableCylinderScoring.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "CoreMinimal.h"
+#include "IntenSelectableScoring.h"
+#include "IntenSelectableCylinderScoring.generated.h"
+
+UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
+class RWTHVRTOOLKIT_API UIntenSelectableCylinderScoring : public UIntenSelectableScoring
+{
+	GENERATED_BODY()
+
+protected:
+	static bool LineToLineIntersection(const FVector& FromA, const FVector& FromB, const FVector& ToA,
+									   const FVector& ToB, FVector& OutIntersection);
+
+	FVector GetClosestSelectionPointTo(const FVector& Point, const FVector& Direction) const;
+
+	virtual void TickComponent(float DeltaTime, ELevelTick TickType,
+							   FActorComponentTickFunction* ThisTickFunction) override;
+
+public:
+	UIntenSelectableCylinderScoring();
+
+	UPROPERTY(EditAnywhere)
+	bool DrawDebug = true;
+
+	virtual TPair<FHitResult, float> GetBestPointScorePair(const FVector& ConeOrigin,
+														   const FVector& ConeForwardDirection,
+														   const float ConeBackwardShiftDistance, const float ConeAngle,
+														   const float LastValue, const float DeltaTime) override;
+
+	UPROPERTY(EditAnywhere)
+	TArray<FVector> LinePoints{FVector::UpVector * 50, FVector::DownVector * 50};
+
+	UPROPERTY(EditAnywhere)
+	float Radius = 50;
+};
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableLineScoring.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableLineScoring.h
new file mode 100644
index 0000000000000000000000000000000000000000..fab919a87338f3bc4a17892f1024116cf320f9ec
--- /dev/null
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableLineScoring.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "CoreMinimal.h"
+#include "IntenSelectableScoring.h"
+#include "IntenSelectableLineScoring.generated.h"
+
+UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
+class RWTHVRTOOLKIT_API UIntenSelectableLineScoring : public UIntenSelectableScoring
+{
+	GENERATED_BODY()
+
+protected:
+	static bool LineToLineIntersection(const FVector& FromA, const FVector& FromB, const FVector& ToA,
+									   const FVector& ToB, FVector& OutIntersection);
+
+	FVector GetClosestSelectionPointTo(const FVector& Point, const FVector& Direction) const;
+
+	virtual void TickComponent(float DeltaTime, ELevelTick TickType,
+							   FActorComponentTickFunction* ThisTickFunction) override;
+
+public:
+	UIntenSelectableLineScoring();
+
+	UPROPERTY(EditAnywhere)
+	bool DrawDebug = true;
+
+	virtual TPair<FHitResult, float> GetBestPointScorePair(const FVector& ConeOrigin,
+														   const FVector& ConeForwardDirection,
+														   const float ConeBackwardShiftDistance, const float ConeAngle,
+														   const float LastValue, const float DeltaTime) override;
+
+	UPROPERTY(EditAnywhere, meta = (EditFixedSize))
+	TArray<FVector> LinePoints{FVector::RightVector * 50, FVector::LeftVector * 50};
+};
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableMultiPointScoring.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableMultiPointScoring.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa2742e320b50dc7930be04efec380802f6c0e7c
--- /dev/null
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableMultiPointScoring.h
@@ -0,0 +1,29 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "IntenSelectableScoring.h"
+#include "IntenSelectableMultiPointScoring.generated.h"
+
+UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
+class RWTHVRTOOLKIT_API UIntenSelectableMultiPointScoring : public UIntenSelectableScoring
+{
+	GENERATED_BODY()
+
+protected:
+	FVector GetClosestSelectionPointTo(const FVector& Point, const FVector& Direction) const;
+
+public:
+	UIntenSelectableMultiPointScoring();
+
+	virtual TPair<FHitResult, float> GetBestPointScorePair(const FVector& ConeOrigin,
+														   const FVector& ConeForwardDirection,
+														   const float ConeBackwardShiftDistance, const float ConeAngle,
+														   const float LastValue, const float DeltaTime) override;
+
+	void UpdatePoints();
+
+	UPROPERTY(EditAnywhere, BlueprintReadWrite)
+	TArray<FVector> PointsToSelect;
+};
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableRectangleScoring.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableRectangleScoring.h
new file mode 100644
index 0000000000000000000000000000000000000000..12eceb0e803def69c1672f676b50c0aa14d88014
--- /dev/null
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableRectangleScoring.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "CoreMinimal.h"
+#include "IntenSelectableScoring.h"
+#include "IntenSelectableRectangleScoring.generated.h"
+
+UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
+class RWTHVRTOOLKIT_API UIntenSelectableRectangleScoring : public UIntenSelectableScoring
+{
+	GENERATED_BODY()
+
+protected:
+	static bool LineToLineIntersection(const FVector& FromA, const FVector& FromB, const FVector& ToA,
+									   const FVector& ToB, FVector& OutIntersection);
+
+	FVector GetClosestSelectionPointTo(const FVector& Point, const FVector& Direction) const;
+
+	virtual void TickComponent(float DeltaTime, ELevelTick TickType,
+							   FActorComponentTickFunction* ThisTickFunction) override;
+
+public:
+	UIntenSelectableRectangleScoring();
+
+	UPROPERTY(EditAnywhere)
+	bool DrawDebug = true;
+
+	UPROPERTY(EditAnywhere)
+	bool OnlyOutline = false;
+
+	UPROPERTY(EditAnywhere)
+	float XLength = 100;
+
+	UPROPERTY(EditAnywhere)
+	float YLength = 100;
+
+	virtual TPair<FHitResult, float> GetBestPointScorePair(const FVector& ConeOrigin,
+														   const FVector& ConeForwardDirection,
+														   const float ConeBackwardShiftDistance, const float ConeAngle,
+														   const float LastValue, const float DeltaTime) override;
+};
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableScoring.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableScoring.h
new file mode 100644
index 0000000000000000000000000000000000000000..529fcd36af3cf04393313110b79f5c0f05a7e6cd
--- /dev/null
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableScoring.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "CoreMinimal.h"
+#include "Components/SceneComponent.h"
+#include "IntenSelectableScoring.generated.h"
+
+UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
+class RWTHVRTOOLKIT_API UIntenSelectableScoring : public USceneComponent
+{
+	GENERATED_BODY()
+
+protected:
+	float GetScore(const FVector& ConeOrigin, const FVector& ConeForwardDirection,
+				   const float ConeBackwardShiftDistance, const float ConeAngle, const FVector& TestPoint,
+				   const float LastValue, const float DeltaTime);
+
+public:
+	UIntenSelectableScoring();
+
+	UPROPERTY(BlueprintReadOnly)
+	float CurrentScore = 0;
+	UPROPERTY(EditAnywhere)
+	bool IsSelectable = true;
+	UPROPERTY(EditAnywhere)
+	float Stickiness = 10;
+	UPROPERTY(EditAnywhere)
+	float Snappiness = 15;
+	UPROPERTY(EditAnywhere)
+	float CompensationConstant = 0.8;
+
+	bool bOverwritingContrib = false;
+	float Contrib = 0;
+
+	virtual TPair<FHitResult, float> GetBestPointScorePair(const FVector& ConeOrigin,
+														   const FVector& ConeForwardDirection,
+														   const float ConeBackwardShiftDistance, const float ConeAngle,
+														   const float LastValue, const float DeltaTime);
+
+	virtual void BeginPlay() override;
+};
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableSinglePointScoring.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableSinglePointScoring.h
new file mode 100644
index 0000000000000000000000000000000000000000..f8dc22e8d9fa3594d9ac821b155ccc57c3d110c9
--- /dev/null
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableSinglePointScoring.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "CoreMinimal.h"
+#include "IntenSelectableScoring.h"
+#include "IntenSelectableSinglePointScoring.generated.h"
+
+UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
+class RWTHVRTOOLKIT_API UIntenSelectableSinglePointScoring : public UIntenSelectableScoring
+{
+	GENERATED_BODY()
+
+public:
+	UIntenSelectableSinglePointScoring();
+
+	virtual TPair<FHitResult, float> GetBestPointScorePair(const FVector& ConeOrigin,
+														   const FVector& ConeForwardDirection,
+														   const float ConeBackwardShiftDistance, const float ConeAngle,
+														   const float LastValue, const float DeltaTime) override;
+
+	virtual void BeginPlay() override;
+};
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableSphereScoring.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableSphereScoring.h
new file mode 100644
index 0000000000000000000000000000000000000000..42100b8d9857b49a5e21bb8062ed99602f532cc7
--- /dev/null
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/IntenSelect/IntenSelectableSphereScoring.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "CoreMinimal.h"
+#include "IntenSelectableScoring.h"
+#include "IntenSelectableSphereScoring.generated.h"
+
+UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
+class RWTHVRTOOLKIT_API UIntenSelectableSphereScoring : public UIntenSelectableScoring
+{
+	GENERATED_BODY()
+
+protected:
+	FVector GetClosestSelectionPointTo(const FVector& Point, const FVector& Direction) const;
+
+public:
+	UIntenSelectableSphereScoring();
+
+	UPROPERTY(EditAnywhere)
+	UMaterialInstance* DebugMaterial;
+
+	UPROPERTY(EditAnywhere)
+	bool OnlyOutline = false;
+
+	UPROPERTY(EditAnywhere)
+	float Radius = 50;
+
+	UPROPERTY(EditAnywhere)
+	bool DrawDebug = true;
+
+	virtual TPair<FHitResult, float> GetBestPointScorePair(const FVector& ConeOrigin,
+														   const FVector& ConeForwardDirection,
+														   const float ConeBackwardShiftDistance, const float ConeAngle,
+														   const float LastValue, const float DeltaTime) override;
+};
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/InteractableComponent.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/InteractableComponent.h
index 8332a897126c46ccb62418b04da0808b6a1bd2b0..da85ad8b003814098fc21e112de423a097a80535 100644
--- a/Source/RWTHVRToolkit/Public/Interaction/Interactables/InteractableComponent.h
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/InteractableComponent.h
@@ -46,6 +46,12 @@ public:
 	UPROPERTY(EditAnywhere, BlueprintReadWrite)
 	TArray<UActionBehaviour*> OnActionBehaviours;
 
+	/**
+	 * If true, allow a grab to be triggered by the geometry of a child actor.
+	 */
+	UPROPERTY(EditAnywhere, BlueprintReadWrite)
+	bool bAllowInteractionFromChildGeometry = true;
+
 	UFUNCTION(BlueprintCallable)
 	FORCEINLINE bool HasInteractionTypeFlag(EInteractorType type) { return type & InteractorFilter; }
 
@@ -76,7 +82,7 @@ public:
 								 const FInputActionValue& Value, const EInteractorType Interactor);
 
 	/**
-	 * @brief If click and grab behaviors are not explicitly specified, load all existing ones
+	 * @brief If hover and action behaviors are not explicitly specified, load all existing ones
 	 */
 	void InitDefaultBehaviourReferences();
 
@@ -91,7 +97,4 @@ public:
 	TArray<USceneComponent*> AllowedComponents;
 
 	bool IsComponentAllowed(USceneComponent* Component) const;
-
-private:
-	bool bInitOnce = true;
 };
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactables/InteractionBitSet.h b/Source/RWTHVRToolkit/Public/Interaction/Interactables/InteractionBitSet.h
index a317318d9d4af78e1a640c76ce6e7629dbbefae7..f2faaebab1f5288633cf68fba9773a4cd076c952 100644
--- a/Source/RWTHVRToolkit/Public/Interaction/Interactables/InteractionBitSet.h
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactables/InteractionBitSet.h
@@ -6,7 +6,7 @@ enum EInteractorType : int
 	None = 0 UMETA(Hidden),
 	Raycast = 1 << 0,
 	Spherecast = 1 << 1,
-	Grab = 1 << 2,
+	Direct = 1 << 2,
 	Reserved2 = 1 << 3,
 	Reserved3 = 1 << 4,
 	Reserved4 = 1 << 5,
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactors/DirectInteractionComponent.h b/Source/RWTHVRToolkit/Public/Interaction/Interactors/DirectInteractionComponent.h
new file mode 100644
index 0000000000000000000000000000000000000000..69ef74ff844a727c11a333047a7f011a12d01241
--- /dev/null
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactors/DirectInteractionComponent.h
@@ -0,0 +1,58 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "Components/SceneComponent.h"
+#include "Interaction/Interactables/InteractableComponent.h"
+#include "Pawn/InputExtensionInterface.h"
+#include "DirectInteractionComponent.generated.h"
+
+UCLASS(Abstract, Blueprintable)
+class RWTHVRTOOLKIT_API UDirectInteractionComponent : public USceneComponent, public IInputExtensionInterface
+{
+	GENERATED_BODY()
+
+public:
+	// Sets default values for this component's properties
+	UDirectInteractionComponent();
+
+	virtual void TickComponent(float DeltaTime, ELevelTick TickType,
+							   FActorComponentTickFunction* ThisTickFunction) override;
+
+	UPROPERTY(EditAnywhere, Category = "Input")
+	class UInputAction* InteractionInputAction;
+
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Direct Interaction")
+	float InteractionSphereRadius = 15.0;
+
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Direct Interaction")
+	bool bShowDebugTrace = false;
+
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Direct Interaction")
+	bool bOnlyInteractWithClosestActor = false;
+
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Direct Interaction")
+	TArray<AActor*> ActorsToIgnore;
+
+	virtual void SetupPlayerInput(UInputComponent* PlayerInputComponent) override;
+
+private:
+	UFUNCTION()
+	void OnBeginInteraction(const FInputActionValue& Value);
+
+	UFUNCTION()
+	void OnEndInteraction(const FInputActionValue& Value);
+
+	UPROPERTY()
+	TArray<UInteractableComponent*> PreviousInteractableComponentsInRange;
+
+	UPROPERTY()
+	TArray<UInteractableComponent*> CurrentInteractableComponentsInRange;
+
+	TArray<TWeakObjectPtr<UInteractableComponent>> CurrentlyInteractedComponents;
+
+	UInteractableComponent* SearchForInteractable(AActor* HitActor);
+
+	bool bSearchAtParent = false;
+};
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactors/GrabComponent.h b/Source/RWTHVRToolkit/Public/Interaction/Interactors/GrabComponent.h
deleted file mode 100644
index 84e1eea6a0eb35fe03519d7eebf39fc93fa0fde0..0000000000000000000000000000000000000000
--- a/Source/RWTHVRToolkit/Public/Interaction/Interactors/GrabComponent.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Fill out your copyright notice in the Description page of Project Settings.
-
-#pragma once
-
-#include "CoreMinimal.h"
-#include "Components/SceneComponent.h"
-#include "Interaction/Interactables/InteractableComponent.h"
-#include "Pawn/InputExtensionInterface.h"
-#include "GrabComponent.generated.h"
-
-class UGrabbableComponent;
-
-UCLASS(Abstract, Blueprintable)
-class RWTHVRTOOLKIT_API UGrabComponent : public USceneComponent, public IInputExtensionInterface
-{
-	GENERATED_BODY()
-
-public:
-	// Sets default values for this component's properties
-	UGrabComponent();
-
-	virtual void TickComponent(float DeltaTime, ELevelTick TickType,
-							   FActorComponentTickFunction* ThisTickFunction) override;
-
-	UPROPERTY(EditDefaultsOnly, Category = "Input")
-	class UInputMappingContext* IMCGrab;
-
-	UPROPERTY(EditAnywhere, Category = "Input")
-	class UInputAction* GrabInputAction;
-
-	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Grabbing")
-	float GrabSphereRadius = 15.0;
-
-	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Grabbing")
-	bool bShowDebugTrace = false;
-
-	virtual void SetupPlayerInput(UInputComponent* PlayerInputComponent) override;
-
-private:
-	UFUNCTION()
-	void OnBeginGrab(const FInputActionValue& Value);
-
-	UFUNCTION()
-	void OnEndGrab(const FInputActionValue& Value);
-
-	UPROPERTY()
-	TArray<UInteractableComponent*> PreviousGrabbablesInRange;
-
-	UPROPERTY()
-	TArray<UInteractableComponent*> CurrentGrabbableInRange;
-};
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactors/RWTHVRWidgetInteractionComponent.h b/Source/RWTHVRToolkit/Public/Interaction/Interactors/RWTHVRWidgetInteractionComponent.h
index 35e32044552e9f84fa5314042b8f926678da5e01..4b1139cf89724faea664f4ac4e2e42f9cf1bb9db 100644
--- a/Source/RWTHVRToolkit/Public/Interaction/Interactors/RWTHVRWidgetInteractionComponent.h
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactors/RWTHVRWidgetInteractionComponent.h
@@ -11,16 +11,15 @@ UENUM()
 enum EInteractionRayVisibility
 {
 	Visible UMETA(DisplayName = "Interaction ray visible"),
-	VisibleOnHoverOnly UMETA(
-		DisplayName =
-		"Interaction ray only visible when hovering over interactable world UI widgets"),
+	VisibleOnHoverOnly UMETA(DisplayName =
+								 "Interaction ray only visible when hovering over interactable world UI widgets"),
 	Invisible UMETA(DisplayName = "Interaction ray invisible")
 };
 
 
-UCLASS(Blueprintable, Abstract, ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
+UCLASS(Blueprintable, Abstract, ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
 class RWTHVRTOOLKIT_API URWTHVRWidgetInteractionComponent : public UWidgetInteractionComponent,
-                                                        public IInputExtensionInterface
+															public IInputExtensionInterface
 {
 	GENERATED_BODY()
 
@@ -30,7 +29,7 @@ public:
 	virtual void SetupPlayerInput(UInputComponent* PlayerInputComponent) override;
 
 	virtual void TickComponent(float DeltaTime, ELevelTick TickType,
-	                           FActorComponentTickFunction* ThisTickFunction) override;
+							   FActorComponentTickFunction* ThisTickFunction) override;
 
 	UFUNCTION(BlueprintCallable)
 	void SetInteractionRayVisibility(EInteractionRayVisibility NewVisibility);
@@ -44,9 +43,6 @@ public:
 	UPROPERTY(EditAnywhere)
 	TEnumAsByte<EInteractionRayVisibility> InteractionRayVisibility = EInteractionRayVisibility::Invisible;
 
-	UPROPERTY(EditDefaultsOnly, Category = "Input")
-	class UInputMappingContext* IMCWidgetInteraction;
-
 	UPROPERTY(EditAnywhere, Category = "Input")
 	class UInputAction* WidgetClickInputAction;
 
diff --git a/Source/RWTHVRToolkit/Public/Interaction/Interactors/RaycastSelectionComponent.h b/Source/RWTHVRToolkit/Public/Interaction/Interactors/RaycastInteractionComponent.h
similarity index 68%
rename from Source/RWTHVRToolkit/Public/Interaction/Interactors/RaycastSelectionComponent.h
rename to Source/RWTHVRToolkit/Public/Interaction/Interactors/RaycastInteractionComponent.h
index 45095c3ac50cc2b81e691e9463d3af2253815173..f5c93123e8ba136e747796825f93309b285109b0 100644
--- a/Source/RWTHVRToolkit/Public/Interaction/Interactors/RaycastSelectionComponent.h
+++ b/Source/RWTHVRToolkit/Public/Interaction/Interactors/RaycastInteractionComponent.h
@@ -6,28 +6,25 @@
 
 #include "CoreMinimal.h"
 #include "Components/SceneComponent.h"
-#include "RaycastSelectionComponent.generated.h"
+#include "Interaction/Interactables/InteractableComponent.h"
+#include "RaycastInteractionComponent.generated.h"
 
 
 UCLASS(Abstract, Blueprintable)
-class RWTHVRTOOLKIT_API URaycastSelectionComponent : public USceneComponent, public IInputExtensionInterface
+class RWTHVRTOOLKIT_API URaycastInteractionComponent : public USceneComponent, public IInputExtensionInterface
 {
 	GENERATED_BODY()
 
 public:
 	// Sets default values for this component's properties
-	URaycastSelectionComponent();
+	URaycastInteractionComponent();
 
 	// Called every frame
 	virtual void TickComponent(float DeltaTime, ELevelTick TickType,
 							   FActorComponentTickFunction* ThisTickFunction) override;
 
-
-	UPROPERTY(EditDefaultsOnly, Category = "Input")
-	class UInputMappingContext* IMCRaycastSelection;
-
 	UPROPERTY(EditAnywhere, Category = "Input")
-	class UInputAction* RayCastSelectInputAction;
+	class UInputAction* InteractionInputAction;
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Raycast")
 	float TraceLength = 3000.0;
@@ -36,10 +33,10 @@ public:
 
 private:
 	UFUNCTION()
-	void OnBeginSelect(const FInputActionValue& Value);
+	void OnBeginInteraction(const FInputActionValue& Value);
 
 	UFUNCTION()
-	void OnEndSelect(const FInputActionValue& Value);
+	void OnEndInteraction(const FInputActionValue& Value);
 
 public:
 	virtual void SetupPlayerInput(UInputComponent* PlayerInputComponent) override;
diff --git a/Source/RWTHVRToolkit/Public/Pawn/InputExtensionInterface.h b/Source/RWTHVRToolkit/Public/Pawn/InputExtensionInterface.h
index 51963c0a1514950229a8b8286ad41e407accd362..5d38f4f28172c1053ba3fed15bc0ce0c3c1c8252 100644
--- a/Source/RWTHVRToolkit/Public/Pawn/InputExtensionInterface.h
+++ b/Source/RWTHVRToolkit/Public/Pawn/InputExtensionInterface.h
@@ -24,7 +24,4 @@ class RWTHVRTOOLKIT_API IInputExtensionInterface
 public:
 	// Called by VirtualRealityPawn::SetupPlayerInputComponent
 	virtual void SetupPlayerInput(UInputComponent* PlayerInputComponent) {}
-
-	// Helper function to get the local player subsystem
-	virtual UEnhancedInputLocalPlayerSubsystem* GetEnhancedInputLocalPlayerSubsystem(const APawn* Pawn) const;
 };
diff --git a/Source/RWTHVRToolkit/Public/Pawn/IntenSelectComponent.h b/Source/RWTHVRToolkit/Public/Pawn/IntenSelectComponent.h
new file mode 100644
index 0000000000000000000000000000000000000000..ebb11aae55a37e1cd0974a0578c0ea3c712a3715
--- /dev/null
+++ b/Source/RWTHVRToolkit/Public/Pawn/IntenSelectComponent.h
@@ -0,0 +1,201 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#pragma region /** Includes */
+#include "Components/SplineComponent.h"
+#include "Components/SplineMeshComponent.h"
+#include "CoreMinimal.h"
+#include "InputAction.h"
+#include "Components/WidgetInteractionComponent.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectable.h"
+#include "IntenSelectComponent.generated.h"
+#pragma endregion
+
+DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnNewComponent);
+
+UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
+class RWTHVRTOOLKIT_API UIntenSelectComponent : public UWidgetInteractionComponent
+{
+	GENERATED_BODY()
+
+
+	//	VARIABLES
+
+#pragma region /** INTERNAL VARIABLES */
+private:
+	float SphereCastRadius;
+	float FeedbackCooldown;
+	bool IsGrabbing;
+	bool IsWidgetInFocus;
+	FVector WidgetFocusPoint;
+
+	UPROPERTY()
+	UWidgetComponent* LastFocusedWidget;
+	UPROPERTY()
+	TMap<UIntenSelectable*, float> ScoreMap;
+	UPROPERTY()
+	TMap<UIntenSelectable*, FHitResult> ContactPointMap;
+	UPROPERTY()
+	UIntenSelectable* CurrentSelection;
+	UPROPERTY()
+	UIntenSelectable* LastKnownSelection;
+	UPROPERTY()
+	FVector LastKnownGrabPoint;
+	UPROPERTY()
+	UStaticMeshComponent* DebugConeMeshComponent;
+	UPROPERTY()
+	UStaticMeshComponent* ForwardRayMeshComponent;
+	UPROPERTY()
+	USplineComponent* SplineComponent;
+	UPROPERTY()
+	USplineMeshComponent* SplineMeshComponent;
+	UPROPERTY()
+	UMaterialParameterCollectionInstance* ParameterCollectionInstance;
+	UPROPERTY()
+	UStaticMesh* DebugConeMesh;
+	UPROPERTY()
+	UMaterialInterface* DebugConeMaterial;
+	UPROPERTY()
+	UStaticMesh* ForwardRayMesh;
+#pragma endregion
+
+#pragma region /** SETTINGS */
+public:
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "IntenSelect|Settings")
+	bool SetActiveOnStart = true;
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "IntenSelect|Settings")
+	float MaxSelectionDistance = 5000;
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "IntenSelect|Settings")
+	float SelectionConeAngle = 5;
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "IntenSelect|Settings")
+	float SplineCurvatureStrength = 1;
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "IntenSelect|Settings")
+	float ConeBackwardShiftDistance = 0;
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "IntenSelect|Settings")
+	float MaxClickStickAngle = 10;
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "IntenSelect|Settings")
+	float ForwardRayWidth = 0.01;
+#pragma endregion
+
+#pragma region /** REFERENCES */
+public:
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|References")
+	UStaticMesh* SplineMesh;
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|References")
+	UMaterialInterface* SplineMaterial;
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|References")
+	UMaterialInterface* ForwardRayMaterial;
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|References")
+	UHapticFeedbackEffect_Base* SelectionFeedbackHaptic;
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|References")
+	USoundBase* OnSelectSound;
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|References")
+	UMaterialParameterCollection* MaterialParamCollection;
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|References")
+	UCurveFloat* ForwardRayTransparencyCurve;
+#pragma endregion
+
+#pragma region /** DEBUG */
+public:
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|Debug")
+	bool bDrawDebugCone = false;
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|Debug")
+	bool bDrawForwardRay = true;
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|Debug")
+	FRotator DebugConeRotation = FRotator(90, 0, 0);
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|Debug")
+	FVector DebugConeScale = FVector(1, 1, 1);
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|Debug")
+	FVector DebugConePosition = FVector(-90, 0, 0);
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|Debug")
+	float DebugRayTransparency = 1;
+#pragma endregion
+
+
+#pragma region /** Input */
+public:
+	UPROPERTY(EditAnywhere, Category = "IntenSelect|Input")
+	UInputAction* InputClick;
+
+#pragma endregion
+
+#pragma region /** EVENTS */
+public:
+	UPROPERTY(BlueprintAssignable)
+	FOnNewComponent OnNewSelectedEvent;
+#pragma endregion
+
+
+	// FUNCTIONS
+
+#pragma region /** INITIALIZATION */
+private:
+	void InitInputBindings();
+	void InitDebugConeMeshComponent();
+	void InitSplineMeshComponent();
+	void InitSplineComponent();
+	void InitForwardRayMeshComponent();
+	void InitMaterialParamCollection();
+#pragma endregion
+
+#pragma region /** SCORING */
+private:
+	float CalculateSphereCastRadius() const;
+	bool GetActorsFromSphereCast(const FVector& SphereCastStart, TArray<FHitResult>& OutHits) const;
+	bool CheckPointInCone(const FVector ConeStartPoint, const FVector ConeForward, const FVector PointToTest,
+						  const float Angle) const;
+	UIntenSelectable* GetMaxScoreActor(const float DeltaTime);
+#pragma endregion
+
+#pragma region /** VISUALS */
+private:
+	void DrawSelectionCurve(const FVector& EndPoint) const;
+	void AddSplinePointsDefault(const FVector& StartPoint, const FVector& Forward, const FVector& EndPoint) const;
+	void UpdateForwardRay(const FVector& ReferencePoint) const;
+#pragma endregion
+
+#pragma region /** RAYCASTING */
+private:
+	void HandleWidgetInteraction();
+	TOptional<FHitResult> RaytraceForFirstHit(const FVector& Start, const FVector& End) const;
+#pragma endregion
+
+#pragma region /** INPUT-HANDLING */
+private:
+	UFUNCTION(BlueprintCallable)
+	void OnFireDown();
+	UFUNCTION(BlueprintCallable)
+	void OnFireUp();
+#pragma endregion
+
+#pragma region /** OTHER */
+private:
+	void HandleCooldown(const float DeltaTime);
+	void HandleGrabbing(const float DeltaTime) const;
+	void HandleNoActorSelected();
+	void HandleActorSelected(UIntenSelectable* NewSelection);
+	FVector ConvertNetVector(FVector_NetQuantize v);
+#pragma endregion
+
+public:
+	UIntenSelectComponent(const FObjectInitializer& ObjectInitializer);
+
+#pragma region /** SELECTION */
+	void SelectObject(UIntenSelectable* SelectableComponent, AActor* SelectedBy);
+	void Unselect();
+#pragma endregion
+
+	virtual void SetActive(bool bNewActive, bool bReset) override;
+
+	UFUNCTION(BlueprintNativeEvent)
+	void OnNewSelected(UIntenSelectable* Selection);
+
+protected:
+	// Called when the game starts
+	virtual void BeginPlay() override;
+
+	// Called every frame
+	virtual void TickComponent(float DeltaTime, ELevelTick TickType,
+							   FActorComponentTickFunction* ThisTickFunction) override;
+};
diff --git a/Source/RWTHVRToolkit/Public/Pawn/Navigation/CollisionHandlingMovement.h b/Source/RWTHVRToolkit/Public/Pawn/Navigation/CollisionHandlingMovement.h
index afa154c74c033ec47ae80862018b441fe113594b..6166c84a1c6f2aee1adfdd2d7b5080ac027d23cd 100644
--- a/Source/RWTHVRToolkit/Public/Pawn/Navigation/CollisionHandlingMovement.h
+++ b/Source/RWTHVRToolkit/Public/Pawn/Navigation/CollisionHandlingMovement.h
@@ -8,14 +8,14 @@
 
 /*
  * This Movement component is needed since in VR not only the pawn itself (UpdatedComponent) is moved but also the
- * user herself can walk and thereby move the CameraComponent, which can also lead to collisions or e.g. going up steps 
+ * user herself can walk and thereby move the CameraComponent, which can also lead to collisions or e.g. going up steps
  *
  * The four modes are:
- * None: No controller movement is applied and no corrections regarding steps or collisions with walls are done
- * Ghost: The same as above but now the Inputs can be used for unconstrained flying (also through objects)
- * Fly: The user can fly but not through walls etc. When the user walks against a wall the scene is moved with her to avoid walking through
- *      The user can also walk up stairs with a maximum step height of MaxStepHeight
- * Walk: Additionally to Fly now gravity keeps the user on the floor
+ * - None: No controller movement is applied and no corrections regarding steps or collisions with walls are done
+ * - Ghost: The same as above but now the Inputs can be used for unconstrained flying (also through objects)
+ * - Fly: The user can fly but not through walls etc. When the user walks against a wall the scene is moved with her to
+ *     avoid walking through The user can also walk up stairs with a maximum step height of MaxStepHeight
+ * - Walk: Additionally to Fly, now gravity keeps the user on the floor
  */
 
 UENUM(BlueprintType)
@@ -38,14 +38,14 @@ public:
 
 	void MoveOutOfNewDynamicCollisions();
 	virtual void TickComponent(float DeltaTime, enum ELevelTick TickType,
-	                           FActorComponentTickFunction* ThisTickFunction) override;
+							   FActorComponentTickFunction* ThisTickFunction) override;
 
 	void SetHeadComponent(USceneComponent* NewHeadComponent);
 
 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement")
 	EVRNavigationModes NavigationMode = EVRNavigationModes::NAV_WALK;
 
-	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement", meta = (ClampMin="0.0"))
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement", meta = (ClampMin = "0.0"))
 	float MaxStepHeight = 40.0f;
 
 	// if the height that the pawn would fall (in walking mode) is higher
@@ -53,17 +53,17 @@ public:
 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement")
 	float MaxFallingDepth = 1000.0f;
 
-	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement", meta = (ClampMax="0.0"))
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement", meta = (ClampMax = "0.0"))
 	float GravityAcceleration = -981.0f;
 
-	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement", meta = (ClampMin="0.0"))
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement", meta = (ClampMin = "0.0"))
 	float UpSteppingAcceleration = 981.0f;
 
-	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement", meta = (ClampMin="0.0"))
+	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement", meta = (ClampMin = "0.0"))
 	float CapsuleRadius = 40.0f;
 
 private:
-	//check for
+	// check for
 	FHitResult CreateCapsuleTrace(const FVector& Start, const FVector& End, bool DrawDebug = false) const;
 	TOptional<FVector> GetOverlapResolveDirection() const;
 	void SetCapsuleColliderToUserSize() const;
@@ -82,7 +82,11 @@ private:
 	TOptional<FVector> LastCollisionFreeCapsulePosition;
 	FVector LastSteeringCollisionVector;
 
-	//just stored for performance gains;
+	// just stored for performance gains;
 	UPROPERTY(VisibleAnywhere, Transient, DuplicateTransient)
 	TArray<AActor*> ActorsToIgnore;
+
+	// if a collision happens and cannot be resolved (e.g. the user crouched, walked under something and stood up)
+	// we remporarily deactivate all checks until the user is in a collision free situation again
+	bool bCollisionChecksTemporarilyDeactivated = false;
 };
diff --git a/Source/RWTHVRToolkit/Public/Pawn/Navigation/ContinuousMovementComponent.h b/Source/RWTHVRToolkit/Public/Pawn/Navigation/ContinuousMovementComponent.h
index adbcef6f926e48e57d379423f0b1829f699fe4e3..06e715c52436b903f07978de0ec6508432fedbf1 100644
--- a/Source/RWTHVRToolkit/Public/Pawn/Navigation/ContinuousMovementComponent.h
+++ b/Source/RWTHVRToolkit/Public/Pawn/Navigation/ContinuousMovementComponent.h
@@ -31,12 +31,6 @@ public:
 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement")
 	bool bMoveWithRightHand = true;
 
-	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VR Movement|Input")
-	UInputMappingContext* IMCMovementLeft;
-
-	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VR Movement|Input")
-	UInputMappingContext* IMCMovementRight;
-
 	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VR Movement|Input|Actions")
 	UInputAction* Move;
 
@@ -53,9 +47,6 @@ public:
 	virtual void SetupPlayerInput(UInputComponent* PlayerInputComponent) override;
 
 private:
-	UPROPERTY()
-	class UInputMappingContext* IMCMovement;
-
 	UPROPERTY()
 	UMotionControllerComponent* MovementHand;
 
diff --git a/Source/RWTHVRToolkit/Public/Pawn/Navigation/MovementComponentBase.h b/Source/RWTHVRToolkit/Public/Pawn/Navigation/MovementComponentBase.h
index d2a687130b4f8caf850c25a75b92a4c9364aa66c..ef8548c76182a54a42dca18a62291347b5bbf626 100644
--- a/Source/RWTHVRToolkit/Public/Pawn/Navigation/MovementComponentBase.h
+++ b/Source/RWTHVRToolkit/Public/Pawn/Navigation/MovementComponentBase.h
@@ -19,12 +19,10 @@ class RWTHVRTOOLKIT_API UMovementComponentBase : public UActorComponent, public
 
 public:
 	// Already sets up VRPawn and InputSubsystem properties that can be used by child classes.
+	UFUNCTION(BlueprintCallable)
 	virtual void SetupPlayerInput(UInputComponent* PlayerInputComponent) override;
 
 protected:
 	UPROPERTY()
 	ARWTHVRPawn* VRPawn;
-
-	UPROPERTY()
-	UEnhancedInputLocalPlayerSubsystem* InputSubsystem;
 };
diff --git a/Source/RWTHVRToolkit/Public/Pawn/Navigation/TeleportationComponent.h b/Source/RWTHVRToolkit/Public/Pawn/Navigation/TeleportationComponent.h
index e66968a3b77531ba983d24ad05bcda0451282a8c..308634643f4a0ad6520ab882e384a8bbe8ff8e96 100644
--- a/Source/RWTHVRToolkit/Public/Pawn/Navigation/TeleportationComponent.h
+++ b/Source/RWTHVRToolkit/Public/Pawn/Navigation/TeleportationComponent.h
@@ -34,12 +34,6 @@ public:
 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VR Movement|Teleport")
 	float TeleportLaunchSpeed = 800;
 
-	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VR Movement|Input")
-	UInputMappingContext* IMCTeleportLeft;
-
-	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VR Movement|Input")
-	UInputMappingContext* IMCTeleportRight;
-
 	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VR Movement|Input|Actions")
 	UInputAction* Move;
 
@@ -73,9 +67,6 @@ private:
 	UPROPERTY()
 	UMotionControllerComponent* RotationHand;
 
-	UPROPERTY()
-	UInputMappingContext* IMCMovement;
-
 	bool bTeleportTraceActive;
 	float TeleportProjectileRadius = 3.6;
 	float RotationArrowRadius = 10.0;
diff --git a/Source/RWTHVRToolkit/Public/Pawn/Navigation/TurnComponent.h b/Source/RWTHVRToolkit/Public/Pawn/Navigation/TurnComponent.h
index de3f274e28caf8f353349798a84c4f2dfc02356d..25576574f32fdbfc5bf095bad2c6d9dfeafee066 100644
--- a/Source/RWTHVRToolkit/Public/Pawn/Navigation/TurnComponent.h
+++ b/Source/RWTHVRToolkit/Public/Pawn/Navigation/TurnComponent.h
@@ -39,16 +39,6 @@ public:
 	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VR Movement|Input|Actions")
 	class UInputAction* DesktopRotation;
 
-	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VR Movement|Input")
-	class UInputMappingContext* IMCMovement_Left;
-
-	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VR Movement|Input")
-	class UInputMappingContext* IMCMovement_Right;
-
-	/**Input Mapping Context that maps buttons for desktop mode*/
-	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "VR Movement|Input")
-	class UInputMappingContext* IMCDesktopRotation;
-
 	/**
 	 * Called every tick as long as stick input is received to allow for continuous turning
 	 * @param Value Stick input value determines turn direction and turn speed
@@ -75,9 +65,6 @@ private:
 	UPROPERTY()
 	UMotionControllerComponent* RotationHand;
 
-	UPROPERTY()
-	class UInputMappingContext* IMCTurn;
-
 	/**
 	 * If we just use VRPawn->AddControllerYawInput(Yaw), rotation is around tracking origin instead of the actual
 	 * player position This function updates the pawns rotation and location to result in a rotation around the users
diff --git a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h
index 50b98e0e84c1cfb5461c2d5764147fe6de77ca32..490dffdf9445a9578e43cf15f6b062b73b70baf1 100644
--- a/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h
+++ b/Source/RWTHVRToolkit/Public/Pawn/RWTHVRPawn.h
@@ -31,6 +31,9 @@ public:
 
 	virtual void NotifyControllerChanged() override;
 
+	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Pawn|Input")
+	TArray<UInputMappingContext*> InputMappingContexts;
+
 	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pawn|MotionControllers")
 	UMotionControllerComponent* RightHand;
 
@@ -82,6 +85,10 @@ public:
 
 protected:
 	virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override;
+	void AddInputMappingContext(const APlayerController* PC, const UInputMappingContext* Context) const;
+
+	UFUNCTION(BlueprintCallable)
+	UInputComponent* GetPlayerInputComponent();
 
 	/* LiveLink helper function called on tick */
 	void EvaluateLivelink() const;
@@ -105,4 +112,7 @@ protected:
 
 	/* Set device specific motion controller sources (None, L/R, Livelink) */
 	void SetupMotionControllerSources();
+
+private:
+	UInputComponent* ActivePlayerInputComponent;
 };
diff --git a/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableCircleScoringVisualizer.cpp b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableCircleScoringVisualizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b0dc19d143b2f2f2edc95dac79ee2c3f27690ff7
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableCircleScoringVisualizer.cpp
@@ -0,0 +1,184 @@
+#include "Interaction/IntenSelectableCircleScoringVisualizer.h"
+
+#include "ActorEditorUtils.h"
+#include "SceneManagement.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableCircleScoring.h"
+#include "Kismet/KismetMathLibrary.h"
+
+IMPLEMENT_HIT_PROXY(FCircleProxy, HComponentVisProxy);
+
+FIntenSelectableCircleScoringVisualizer::FIntenSelectableCircleScoringVisualizer()
+{
+	PointsProperty = FindFProperty<FProperty>(UIntenSelectableCircleScoring::StaticClass(),
+											  GET_MEMBER_NAME_CHECKED(UIntenSelectableCircleScoring, Radius));
+}
+
+FIntenSelectableCircleScoringVisualizer::~FIntenSelectableCircleScoringVisualizer() {}
+
+FVector FIntenSelectableCircleScoringVisualizer::GetCurrentVectorWorld() const
+{
+	switch (CurrentSelectionIndex)
+	{
+	case 0:
+		return GetEditedScoringComponent()->GetComponentLocation();
+	case 1:
+		{
+			const FVector CenterWorld = GetEditedScoringComponent()->GetComponentLocation();
+			const FVector NormalWorldPoint =
+				GetEditedScoringComponent()->GetComponentTransform().TransformPosition(FVector::ForwardVector);
+			const FVector WorldNormalDir = NormalWorldPoint - CenterWorld;
+			const FVector Y =
+				WorldNormalDir.RotateAngleAxis(90, GetEditedScoringComponent()->GetRightVector()).GetSafeNormal() *
+				GetEditedScoringComponent()->Radius;
+			return CenterWorld + Y;
+		}
+	default:
+		return FVector::ZeroVector;
+	}
+}
+
+bool FIntenSelectableCircleScoringVisualizer::IsVisualizingArchetype() const
+{
+	return GetEditedScoringComponent() && GetEditedScoringComponent()->GetOwner() &&
+		FActorEditorUtils::IsAPreviewOrInactiveActor(GetEditedScoringComponent()->GetOwner());
+}
+
+UIntenSelectableCircleScoring* FIntenSelectableCircleScoringVisualizer::GetEditedScoringComponent() const
+{
+	return Cast<UIntenSelectableCircleScoring>(ScoringBehaviourPropertyPath.GetComponent());
+}
+
+bool FIntenSelectableCircleScoringVisualizer::ShowWhenSelected() { return false; }
+
+bool FIntenSelectableCircleScoringVisualizer::ShouldShowForSelectedSubcomponents(const UActorComponent* Component)
+{
+	return false;
+}
+
+bool FIntenSelectableCircleScoringVisualizer::VisProxyHandleClick(FEditorViewportClient* InViewportClient,
+																  HComponentVisProxy* VisProxy,
+																  const FViewportClick& Click)
+{
+	bool bEditing = false;
+
+	// UE_LOG(LogTemp, Warning, TEXT("Handling Click"));
+
+	if (VisProxy && VisProxy->Component.IsValid())
+	{
+		bEditing = true;
+
+		if (VisProxy->IsA(FCircleProxy::StaticGetType()))
+		{
+			const UIntenSelectableCircleScoring* T =
+				Cast<const UIntenSelectableCircleScoring>(VisProxy->Component.Get());
+			ScoringBehaviourPropertyPath = FComponentPropertyPath(T);
+
+			FCircleProxy* Proxy = (FCircleProxy*)VisProxy;
+			CurrentSelectionIndex = Proxy->TargetIndex;
+		}
+		else
+		{
+			CurrentSelectionIndex = INDEX_NONE;
+		}
+	}
+	else
+	{
+		CurrentSelectionIndex = INDEX_NONE;
+	}
+
+	return bEditing;
+}
+
+void FIntenSelectableCircleScoringVisualizer::DrawVisualization(const UActorComponent* Component,
+																const FSceneView* View, FPrimitiveDrawInterface* PDI)
+{
+	const UIntenSelectableCircleScoring* ComponentCasted = Cast<UIntenSelectableCircleScoring>(Component);
+
+	if (ComponentCasted != nullptr)
+	{
+		PDI->SetHitProxy(new FCircleProxy(Component, 0));
+
+		const FVector CenterWorld = ComponentCasted->GetComponentLocation();
+		PDI->DrawPoint(CenterWorld, FColor::Green, 20.f, SDPG_Foreground);
+		PDI->SetHitProxy(nullptr);
+
+		PDI->SetHitProxy(new FCircleProxy(Component, 1));
+		const FVector NormalWorldPoint =
+			ComponentCasted->GetComponentTransform().TransformPosition(FVector::ForwardVector);
+		const FVector WorldNormalDir = NormalWorldPoint - CenterWorld;
+		const FVector Y = WorldNormalDir.RotateAngleAxis(90, ComponentCasted->GetRightVector());
+		const FVector Z = FVector::CrossProduct(Y.GetSafeNormal(), WorldNormalDir);
+		DrawCircle(PDI, CenterWorld, Y.GetSafeNormal(), Z.GetSafeNormal(), FColor::Green, ComponentCasted->Radius, 100,
+				   SDPG_Foreground, 2);
+
+		PDI->SetHitProxy(nullptr);
+	}
+}
+
+void FIntenSelectableCircleScoringVisualizer::EndEditing() {}
+
+UActorComponent* FIntenSelectableCircleScoringVisualizer::GetEditedComponent() const
+{
+	return GetEditedScoringComponent();
+}
+
+bool FIntenSelectableCircleScoringVisualizer::HandleInputDelta(FEditorViewportClient* ViewportClient,
+															   FViewport* Viewport, FVector& DeltaTranslate,
+															   FRotator& DeltaRotate, FVector& DeltaScale)
+{
+	bool bHandled = false;
+
+	if (CurrentSelectionIndex != INDEX_NONE)
+	{
+		// UE_LOG(LogTemp, Warning, TEXT("Current Selection! %s"), *DeltaTranslate.ToString());
+
+		if (CurrentSelectionIndex == 0)
+		{
+			const FVector LocalCenter = GetEditedScoringComponent()->GetComponentLocation();
+			const FVector NewCenter = LocalCenter + DeltaTranslate;
+			GetEditedScoringComponent()->SetWorldLocation(NewCenter);
+			GetEditedScoringComponent()->AddWorldRotation(DeltaRotate);
+
+			bHandled = true;
+		}
+		else if (CurrentSelectionIndex == 1)
+		{
+			const FVector CenterWorld = GetEditedScoringComponent()->GetComponentLocation();
+			const FVector NormalWorldPoint =
+				GetEditedScoringComponent()->GetComponentTransform().TransformPosition(FVector::ForwardVector);
+			const FVector WorldNormalDir = NormalWorldPoint - CenterWorld;
+			const FVector RadiusVector =
+				WorldNormalDir.RotateAngleAxis(90, GetEditedScoringComponent()->GetRightVector()).GetSafeNormal() *
+				GetEditedScoringComponent()->Radius;
+
+			const FVector ClampedTranslate =
+				DeltaTranslate.Size() > 100 ? DeltaTranslate.GetSafeNormal() * 100 : DeltaTranslate;
+			GetEditedScoringComponent()->Radius =
+				FVector::Distance(CenterWorld, CenterWorld + RadiusVector + ClampedTranslate);
+			bHandled = true;
+		}
+
+		TArray<FProperty*> Properties;
+		Properties.Add(PointsProperty);
+		NotifyPropertiesModified(GetEditedScoringComponent(), Properties, EPropertyChangeType::ValueSet);
+	}
+	else
+	{
+		// UE_LOG(LogTemp, Warning, TEXT("No Current Selection!"));
+	}
+
+	return bHandled;
+}
+
+bool FIntenSelectableCircleScoringVisualizer::GetWidgetLocation(const FEditorViewportClient* ViewportClient,
+																FVector& OutLocation) const
+{
+	if (CurrentSelectionIndex != INDEX_NONE)
+	{
+		OutLocation = GetCurrentVectorWorld();
+
+		return true;
+	}
+
+	return false;
+}
diff --git a/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableCubeScoringVisualizer.cpp b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableCubeScoringVisualizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..719a5bc4eca4e981730cd047cfff1c21d6a06e39
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableCubeScoringVisualizer.cpp
@@ -0,0 +1,144 @@
+#include "Interaction/IntenSelectableCubeScoringVisualizer.h"
+
+#include "ActorEditorUtils.h"
+#include "DrawDebugHelpers.h"
+#include "SceneManagement.h"
+#include "MaterialShared.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableCubeScoring.h"
+#include "Materials/MaterialInstance.h"
+#include "Materials/MaterialRenderProxy.h"
+
+IMPLEMENT_HIT_PROXY(FCubeProxy, HComponentVisProxy);
+
+FIntenSelectableCubeScoringVisualizer::FIntenSelectableCubeScoringVisualizer() :
+	DebugMaterial(FColoredMaterialRenderProxy(GEngine->ConstraintLimitMaterial->GetRenderProxy(), FColor::Green))
+{
+}
+
+FIntenSelectableCubeScoringVisualizer::~FIntenSelectableCubeScoringVisualizer() {}
+
+FVector FIntenSelectableCubeScoringVisualizer::GetCurrentVectorWorld() const
+{
+	return GetEditedScoringComponent()->GetComponentLocation();
+}
+
+bool FIntenSelectableCubeScoringVisualizer::IsVisualizingArchetype() const
+{
+	return GetEditedScoringComponent() && GetEditedScoringComponent()->GetOwner() &&
+		FActorEditorUtils::IsAPreviewOrInactiveActor(GetEditedScoringComponent()->GetOwner());
+}
+
+UIntenSelectableCubeScoring* FIntenSelectableCubeScoringVisualizer::GetEditedScoringComponent() const
+{
+	return Cast<UIntenSelectableCubeScoring>(ScoringBehaviourPropertyPath.GetComponent());
+}
+
+bool FIntenSelectableCubeScoringVisualizer::ShowWhenSelected() { return false; }
+
+bool FIntenSelectableCubeScoringVisualizer::ShouldShowForSelectedSubcomponents(const UActorComponent* Component)
+{
+	return false;
+}
+
+bool FIntenSelectableCubeScoringVisualizer::VisProxyHandleClick(FEditorViewportClient* InViewportClient,
+																HComponentVisProxy* VisProxy,
+																const FViewportClick& Click)
+{
+	bool bEditing = false;
+
+	// UE_LOG(LogTemp, Warning, TEXT("Handling Click"));
+
+	if (VisProxy && VisProxy->Component.IsValid())
+	{
+		bEditing = true;
+
+		if (VisProxy->IsA(FCubeProxy::StaticGetType()))
+		{
+			const UIntenSelectableCubeScoring* T = Cast<const UIntenSelectableCubeScoring>(VisProxy->Component.Get());
+			ScoringBehaviourPropertyPath = FComponentPropertyPath(T);
+
+			FCubeProxy* Proxy = (FCubeProxy*)VisProxy;
+			CurrentSelectionIndex = Proxy->TargetIndex;
+		}
+		else
+		{
+			CurrentSelectionIndex = INDEX_NONE;
+		}
+	}
+	else
+	{
+		CurrentSelectionIndex = INDEX_NONE;
+	}
+
+	return bEditing;
+}
+
+void FIntenSelectableCubeScoringVisualizer::DrawVisualization(const UActorComponent* Component, const FSceneView* View,
+															  FPrimitiveDrawInterface* PDI)
+{
+	const UIntenSelectableCubeScoring* ComponentCasted = Cast<UIntenSelectableCubeScoring>(Component);
+
+	if (ComponentCasted != nullptr)
+	{
+		PDI->SetHitProxy(new FCubeProxy(Component, 0));
+
+		const auto Scale = ComponentCasted->GetRelativeTransform().GetScale3D();
+		const FVector Radii{Scale.X, Scale.Y, Scale.Z};
+		DrawBox(PDI, ComponentCasted->GetComponentTransform().ToMatrixNoScale(), Radii / 2, &DebugMaterial, 0);
+		PDI->DrawPoint(ComponentCasted->GetComponentLocation(), FColor::Green, 20, 0);
+
+		PDI->SetHitProxy(nullptr);
+	}
+}
+
+void FIntenSelectableCubeScoringVisualizer::EndEditing() {}
+
+UActorComponent* FIntenSelectableCubeScoringVisualizer::GetEditedComponent() const
+{
+	return GetEditedScoringComponent();
+}
+
+bool FIntenSelectableCubeScoringVisualizer::HandleInputDelta(FEditorViewportClient* ViewportClient, FViewport* Viewport,
+															 FVector& DeltaTranslate, FRotator& DeltaRotate,
+															 FVector& DeltaScale)
+{
+	bool bHandled = false;
+
+	if (CurrentSelectionIndex != INDEX_NONE)
+	{
+		// UE_LOG(LogTemp, Warning, TEXT("Current Selection! %s"), *DeltaTranslate.ToString());
+
+		const FVector LocalCenter = GetEditedScoringComponent()->GetComponentLocation();
+		const FVector NewCenter = LocalCenter + DeltaTranslate;
+		GetEditedScoringComponent()->SetWorldLocation(NewCenter);
+		GetEditedScoringComponent()->AddWorldRotation(DeltaRotate);
+
+		auto Scale = GetEditedScoringComponent()->GetRelativeTransform().GetScale3D();
+
+		Scale.X += DeltaScale.X * 3;
+		Scale.Y += DeltaScale.Y * 3;
+		Scale.Z += DeltaScale.Z * 3;
+
+		GetEditedScoringComponent()->GetRelativeTransform().SetScale3D(Scale);
+		bHandled = true;
+	}
+	else
+	{
+		// UE_LOG(LogTemp, Warning, TEXT("No Current Selection!"));
+	}
+
+	return bHandled;
+}
+
+bool FIntenSelectableCubeScoringVisualizer::GetWidgetLocation(const FEditorViewportClient* ViewportClient,
+															  FVector& OutLocation) const
+{
+	if (CurrentSelectionIndex != INDEX_NONE)
+	{
+		OutLocation = GetCurrentVectorWorld();
+
+		return true;
+	}
+
+	return false;
+}
diff --git a/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableCylinderScoringVisualizer.cpp b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableCylinderScoringVisualizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..076cf8e42e290a4bfb229c3b19c029f664ecdde8
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableCylinderScoringVisualizer.cpp
@@ -0,0 +1,209 @@
+#include "Interaction/IntenSelectableCylinderScoringVisualizer.h"
+#include "ActorEditorUtils.h"
+#include "SceneManagement.h"
+
+IMPLEMENT_HIT_PROXY(FCylinderPointProxy, HComponentVisProxy);
+
+FIntenSelectableCylinderScoringVisualizer::FIntenSelectableCylinderScoringVisualizer() :
+	DebugMaterial(FColoredMaterialRenderProxy(GEngine->ConstraintLimitMaterial->GetRenderProxy(), FColor::Green))
+{
+	RadiusProperty = FindFProperty<FProperty>(UIntenSelectableCylinderScoring::StaticClass(),
+											  GET_MEMBER_NAME_CHECKED(UIntenSelectableCylinderScoring, Radius));
+	PointsProperty = FindFProperty<FProperty>(UIntenSelectableCylinderScoring::StaticClass(),
+											  GET_MEMBER_NAME_CHECKED(UIntenSelectableCylinderScoring, LinePoints));
+}
+
+FIntenSelectableCylinderScoringVisualizer::~FIntenSelectableCylinderScoringVisualizer() {}
+
+bool FIntenSelectableCylinderScoringVisualizer::IsVisualizingArchetype() const
+{
+	return GetEditedScoringComponent() && GetEditedScoringComponent()->GetOwner() &&
+		FActorEditorUtils::IsAPreviewOrInactiveActor(GetEditedScoringComponent()->GetOwner());
+}
+
+FVector FIntenSelectableCylinderScoringVisualizer::GetCurrentVectorWorld() const
+{
+	if (GetEditedScoringComponent())
+	{
+		if (CurrentCylinderSelectionIndex == INDEX_NONE)
+		{
+			return GetEditedScoringComponent()->GetComponentLocation();
+		}
+		return GetEditedScoringComponent()->GetComponentTransform().TransformPositionNoScale(
+			GetEditedScoringComponent()->LinePoints[CurrentCylinderSelectionIndex]);
+	}
+
+	return FVector::ZeroVector;
+}
+
+bool FIntenSelectableCylinderScoringVisualizer::ShowWhenSelected() { return false; }
+
+bool FIntenSelectableCylinderScoringVisualizer::ShouldShowForSelectedSubcomponents(const UActorComponent* Component)
+{
+	return false;
+}
+
+bool FIntenSelectableCylinderScoringVisualizer::VisProxyHandleClick(FEditorViewportClient* InViewportClient,
+																	HComponentVisProxy* VisProxy,
+																	const FViewportClick& Click)
+{
+	bool bEditing = false;
+
+	// UE_LOG(LogTemp, Warning, TEXT("Handling Click"));
+
+	if (VisProxy && VisProxy->Component.IsValid())
+	{
+		bEditing = true;
+
+		if (VisProxy->IsA(FCylinderPointProxy::StaticGetType()))
+		{
+			const UIntenSelectableCylinderScoring* T =
+				Cast<const UIntenSelectableCylinderScoring>(VisProxy->Component.Get());
+			ScoringBehaviourPropertyPath = FComponentPropertyPath(T);
+
+			FCylinderPointProxy* Proxy = (FCylinderPointProxy*)VisProxy;
+			CurrentCylinderSelectionIndex = Proxy->TargetIndex;
+		}
+		else
+		{
+			CurrentCylinderSelectionIndex = INDEX_NONE;
+		}
+	}
+	else
+	{
+		CurrentCylinderSelectionIndex = INDEX_NONE;
+	}
+
+	return bEditing;
+}
+
+void FIntenSelectableCylinderScoringVisualizer::DrawVisualization(const UActorComponent* Component,
+																  const FSceneView* View, FPrimitiveDrawInterface* PDI)
+{
+	const UIntenSelectableCylinderScoring* ComponentCasted = Cast<UIntenSelectableCylinderScoring>(Component);
+
+	if (ComponentCasted != nullptr)
+	{
+		for (int i = 0; i < ComponentCasted->LinePoints.Num(); i++)
+		{
+			PDI->SetHitProxy(new FCylinderPointProxy(Component, i));
+
+			FVector PointWorld =
+				ComponentCasted->GetComponentTransform().TransformPositionNoScale(ComponentCasted->LinePoints[i]);
+			PDI->DrawPoint(PointWorld, FColor::Green, 20.f, SDPG_Foreground);
+
+			PDI->SetHitProxy(nullptr);
+		}
+
+		const FVector Start =
+			ComponentCasted->GetComponentTransform().TransformPositionNoScale(ComponentCasted->LinePoints[0]);
+		const FVector End =
+			ComponentCasted->GetComponentTransform().TransformPositionNoScale(ComponentCasted->LinePoints[1]);
+		PDI->DrawLine(Start, End, FColor::Green, SDPG_World);
+
+		const float Dist = (End - Start).Size();
+		DrawCylinder(PDI, Start, End, ComponentCasted->Radius, 20, &DebugMaterial, 0);
+	}
+}
+
+void FIntenSelectableCylinderScoringVisualizer::EndEditing()
+{
+	CurrentCylinderSelectionIndex = INDEX_NONE;
+	// GetEditedScoringComponent()->MarkRenderStateDirty();
+	// GEditor->RedrawLevelEditingViewports(true);
+}
+
+UActorComponent* FIntenSelectableCylinderScoringVisualizer::GetEditedComponent() const
+{
+	return GetEditedScoringComponent();
+}
+
+UIntenSelectableCylinderScoring* FIntenSelectableCylinderScoringVisualizer::GetEditedScoringComponent() const
+{
+	return Cast<UIntenSelectableCylinderScoring>(ScoringBehaviourPropertyPath.GetComponent());
+}
+
+bool FIntenSelectableCylinderScoringVisualizer::HandleInputDelta(FEditorViewportClient* ViewportClient,
+																 FViewport* Viewport, FVector& DeltaTranslate,
+																 FRotator& DeltaRotate, FVector& DeltaScale)
+{
+	bool bHandled = false;
+
+	UIntenSelectableCylinderScoring* ScoringComponent = GetEditedScoringComponent();
+
+	if (ScoringComponent)
+	{
+		if (CurrentCylinderSelectionIndex != INDEX_NONE)
+		{
+			ScoringComponent->Modify();
+
+			const FVector WorldSelection = ScoringComponent->GetComponentTransform().TransformPositionNoScale(
+				ScoringComponent->LinePoints[CurrentCylinderSelectionIndex]);
+			const FVector NewWorldPos = ScoringComponent->GetComponentTransform().InverseTransformPositionNoScale(
+				WorldSelection + DeltaTranslate);
+
+			ScoringComponent->LinePoints[CurrentCylinderSelectionIndex] += DeltaTranslate;
+
+			// UE_LOG(LogTemp, Warning, TEXT("Component: %s"),
+			// *(ScoringComponent->LinePoints[CurrentCylinderSelectionIndex]).ToString());
+
+
+			TArray<FProperty*> Properties;
+			Properties.Add(PointsProperty);
+			Properties.Add(RadiusProperty);
+			NotifyPropertiesModified(ScoringComponent, Properties, EPropertyChangeType::ValueSet);
+
+			/*
+			const FVector Average = (ScoringComponent->LinePoints[0] + ScoringComponent->LinePoints[1]) / 2;
+
+			ScoringComponent->SetWorldLocation(ScoringComponent->GetComponentTransform().TransformPositionNoScale(Average));
+			ScoringComponent->LinePoints[0] -= Average;
+			ScoringComponent->LinePoints[1] -= Average;
+
+			ScoringComponent->MarkRenderStateDirty();
+			GEditor->RedrawLevelEditingViewports(true);
+
+			ScoringComponent->PostEditChange();
+			GEditor->NoteActorMovement();
+
+			// If you're modifying an actor's component, it might be a good idea to also mark the actor as modified
+			ScoringComponent->GetOwner()->Modify();
+			ScoringComponent->GetOwner()->PostEditChange();
+
+			// If the component's package might be unsaved, mark it dirty to ensure changes aren't lost
+			ScoringComponent->GetOuter()->MarkPackageDirty();*/
+
+			GEditor->RedrawLevelEditingViewports(true);
+
+			bHandled = true;
+		}
+		else
+		{
+			// ScoringComponent->AddWorldOffset(DeltaTranslate);
+			// ScoringComponent->AddWorldRotation(DeltaRotate);
+
+			ScoringComponent->Modify();
+			ScoringComponent->MarkRenderStateDirty();
+			GEditor->RedrawLevelEditingViewports(true);
+
+			// UE_LOG(LogTemp, Warning, TEXT("Cylinder Selected!"));
+
+			return false;
+		}
+	}
+
+	return bHandled;
+}
+
+bool FIntenSelectableCylinderScoringVisualizer::GetWidgetLocation(const FEditorViewportClient* ViewportClient,
+																  FVector& OutLocation) const
+{
+	if (GetEditedComponent() && CurrentCylinderSelectionIndex != INDEX_NONE)
+	{
+		OutLocation = GetCurrentVectorWorld();
+
+		return true;
+	}
+
+	return false;
+}
diff --git a/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableLineScoringVisualizer.cpp b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableLineScoringVisualizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..59c8e11f79ec3f58b6588e89439f483a096913b1
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableLineScoringVisualizer.cpp
@@ -0,0 +1,187 @@
+#include "Interaction/IntenSelectableLineScoringVisualizer.h"
+
+#include "ActorEditorUtils.h"
+#include "SceneManagement.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableLineScoring.h"
+
+IMPLEMENT_HIT_PROXY(FLinePointProxy, HComponentVisProxy);
+
+FIntenSelectableLineScoringVisualizer::FIntenSelectableLineScoringVisualizer()
+{
+	PointsProperty = FindFProperty<FProperty>(UIntenSelectableLineScoring::StaticClass(),
+											  GET_MEMBER_NAME_CHECKED(UIntenSelectableLineScoring, LinePoints));
+}
+
+FIntenSelectableLineScoringVisualizer::~FIntenSelectableLineScoringVisualizer() {}
+
+FVector FIntenSelectableLineScoringVisualizer::GetCurrentVectorWorld() const
+{
+	if (CurrentLineSelectionIndex == INDEX_NONE)
+	{
+		return FVector::ZeroVector;
+	}
+	else if (CurrentLineSelectionIndex == 2)
+	{
+		return GetEditedScoringComponent()->GetComponentLocation();
+	}
+	return GetEditedScoringComponent()->GetComponentTransform().TransformPositionNoScale(
+		GetEditedScoringComponent()->LinePoints[CurrentLineSelectionIndex]);
+}
+
+bool FIntenSelectableLineScoringVisualizer::IsVisualizingArchetype() const
+{
+	return (GetEditedScoringComponent() && GetEditedScoringComponent()->GetOwner() &&
+			FActorEditorUtils::IsAPreviewOrInactiveActor(GetEditedScoringComponent()->GetOwner()));
+}
+
+bool FIntenSelectableLineScoringVisualizer::ShowWhenSelected() { return false; }
+
+bool FIntenSelectableLineScoringVisualizer::ShouldShowForSelectedSubcomponents(const UActorComponent* Component)
+{
+	return false;
+}
+
+bool FIntenSelectableLineScoringVisualizer::VisProxyHandleClick(FEditorViewportClient* InViewportClient,
+																HComponentVisProxy* VisProxy,
+																const FViewportClick& Click)
+{
+	bool bEditing = false;
+
+	// UE_LOG(LogTemp, Warning, TEXT("Handling Click"));
+
+	if (VisProxy && VisProxy->Component.IsValid())
+	{
+		bEditing = true;
+
+		if (VisProxy->IsA(FLinePointProxy::StaticGetType()))
+		{
+			const UIntenSelectableLineScoring* T = Cast<const UIntenSelectableLineScoring>(VisProxy->Component.Get());
+			ScoringBehaviourPropertyPath = FComponentPropertyPath(T);
+
+			FLinePointProxy* Proxy = (FLinePointProxy*)VisProxy;
+			CurrentLineSelectionIndex = Proxy->TargetIndex;
+		}
+		else
+		{
+			CurrentLineSelectionIndex = INDEX_NONE;
+		}
+	}
+	else
+	{
+		CurrentLineSelectionIndex = INDEX_NONE;
+	}
+
+	return bEditing;
+}
+
+void FIntenSelectableLineScoringVisualizer::DrawVisualization(const UActorComponent* Component, const FSceneView* View,
+															  FPrimitiveDrawInterface* PDI)
+{
+	const UIntenSelectableLineScoring* ComponentCasted = Cast<UIntenSelectableLineScoring>(Component);
+
+	if (ComponentCasted != nullptr && ComponentCasted->LinePoints.Num() == 2)
+	{
+		for (int i = 0; i < ComponentCasted->LinePoints.Num() && i <= 2; i++)
+		{
+			PDI->SetHitProxy(new FLinePointProxy(Component, i));
+
+			FVector PointWorld =
+				ComponentCasted->GetComponentTransform().TransformPosition(ComponentCasted->LinePoints[i]);
+			PDI->DrawPoint(PointWorld, FColor::Green, 20.f, SDPG_Foreground);
+
+			PDI->SetHitProxy(nullptr);
+		}
+
+		PDI->SetHitProxy(new FLinePointProxy(Component, 2));
+
+		const FVector Start =
+			ComponentCasted->GetComponentTransform().TransformPosition(ComponentCasted->LinePoints[0]);
+		const FVector End = ComponentCasted->GetComponentTransform().TransformPosition(ComponentCasted->LinePoints[1]);
+		PDI->DrawLine(Start, End, FColor::Green, SDPG_Foreground, 3);
+
+		PDI->SetHitProxy(nullptr);
+	}
+}
+
+void FIntenSelectableLineScoringVisualizer::EndEditing()
+{
+	GetEditedScoringComponent()->MarkRenderStateDirty();
+	GEditor->RedrawLevelEditingViewports(true);
+}
+
+UActorComponent* FIntenSelectableLineScoringVisualizer::GetEditedComponent() const
+{
+	return GetEditedScoringComponent();
+}
+
+UIntenSelectableLineScoring* FIntenSelectableLineScoringVisualizer::GetEditedScoringComponent() const
+{
+	return Cast<UIntenSelectableLineScoring>(ScoringBehaviourPropertyPath.GetComponent());
+}
+
+bool FIntenSelectableLineScoringVisualizer::HandleInputDelta(FEditorViewportClient* ViewportClient, FViewport* Viewport,
+															 FVector& DeltaTranslate, FRotator& DeltaRotate,
+															 FVector& DeltaScale)
+{
+	bool bHandled = false;
+
+	if (CurrentLineSelectionIndex != INDEX_NONE)
+	{
+		UIntenSelectableLineScoring* ScoringComponent = GetEditedScoringComponent();
+
+		if (ScoringComponent->LinePoints.Num() == 2)
+		{
+
+			if (CurrentLineSelectionIndex == 2)
+			{
+				ScoringComponent->AddWorldOffset(DeltaTranslate);
+				ScoringComponent->AddWorldRotation(DeltaRotate);
+			}
+			else
+			{
+				// UE_LOG(LogTemp, Warning, TEXT("Current Selection! %s"), *DeltaTranslate.ToString());
+
+				const FVector WorldSelection = ScoringComponent->GetComponentTransform().TransformPositionNoScale(
+					GetEditedScoringComponent()->LinePoints[CurrentLineSelectionIndex]);
+				const FVector NewWorldPos = ScoringComponent->GetComponentTransform().InverseTransformPositionNoScale(
+					WorldSelection + DeltaTranslate);
+				ScoringComponent->LinePoints[CurrentLineSelectionIndex] = NewWorldPos;
+
+				const FVector Average = (ScoringComponent->LinePoints[0] + ScoringComponent->LinePoints[1]) / 2;
+
+				ScoringComponent->SetWorldLocation(
+					ScoringComponent->GetComponentTransform().TransformPositionNoScale(Average));
+				ScoringComponent->LinePoints[0] -= Average;
+				ScoringComponent->LinePoints[1] -= Average;
+			}
+
+
+			TArray<FProperty*> Properties;
+			Properties.Add(PointsProperty);
+			NotifyPropertiesModified(ScoringComponent, Properties, EPropertyChangeType::ValueSet);
+
+			ScoringComponent->MarkRenderStateDirty();
+			GEditor->RedrawLevelEditingViewports(true);
+			bHandled = true;
+		}
+	}
+	else
+	{
+		// UE_LOG(LogTemp, Warning, TEXT("No Current Selection!"));
+	}
+
+	return bHandled;
+}
+
+bool FIntenSelectableLineScoringVisualizer::GetWidgetLocation(const FEditorViewportClient* ViewportClient,
+															  FVector& OutLocation) const
+{
+	if (GetEditedScoringComponent() && CurrentLineSelectionIndex != INDEX_NONE)
+	{
+		OutLocation = GetCurrentVectorWorld();
+
+		return true;
+	}
+
+	return false;
+}
diff --git a/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableMultiPointScoringVisualizer.cpp b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableMultiPointScoringVisualizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fd6d48ce19f48b35dfbb3524f3204b4fda59516c
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableMultiPointScoringVisualizer.cpp
@@ -0,0 +1,156 @@
+#include "Interaction/IntenSelectableMultiPointScoringVisualizer.h"
+#include "ActorEditorUtils.h"
+#include "SceneManagement.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableMultiPointScoring.h"
+
+IMPLEMENT_HIT_PROXY(FMultiPointProxy, HComponentVisProxy);
+
+FIntenSelectableMultiPointScoringVisualizer::FIntenSelectableMultiPointScoringVisualizer()
+{
+	PointsProperty =
+		FindFProperty<FProperty>(UIntenSelectableMultiPointScoring::StaticClass(),
+								 GET_MEMBER_NAME_CHECKED(UIntenSelectableMultiPointScoring, PointsToSelect));
+}
+
+FIntenSelectableMultiPointScoringVisualizer::~FIntenSelectableMultiPointScoringVisualizer() {}
+
+FVector FIntenSelectableMultiPointScoringVisualizer::GetCurrentVectorWorld() const
+{
+	if (CurrentSelectionIndex == INDEX_NONE)
+	{
+		return FVector::ZeroVector;
+	}
+	return GetEditedScoringComponent()->GetComponentTransform().TransformPosition(
+		GetEditedScoringComponent()->PointsToSelect[CurrentSelectionIndex]);
+}
+
+bool FIntenSelectableMultiPointScoringVisualizer::IsVisualizingArchetype() const
+{
+	return GetEditedScoringComponent() && GetEditedScoringComponent()->GetOwner() &&
+		FActorEditorUtils::IsAPreviewOrInactiveActor(GetEditedScoringComponent()->GetOwner());
+}
+
+bool FIntenSelectableMultiPointScoringVisualizer::ShowWhenSelected() { return false; }
+
+bool FIntenSelectableMultiPointScoringVisualizer::ShouldShowForSelectedSubcomponents(const UActorComponent* Component)
+{
+	return false;
+}
+
+bool FIntenSelectableMultiPointScoringVisualizer::VisProxyHandleClick(FEditorViewportClient* InViewportClient,
+																	  HComponentVisProxy* VisProxy,
+																	  const FViewportClick& Click)
+{
+	bool bEditing = false;
+
+	if (VisProxy && VisProxy->Component.IsValid())
+	{
+		bEditing = true;
+
+		if (VisProxy->IsA(FMultiPointProxy::StaticGetType()))
+		{
+			const UIntenSelectableMultiPointScoring* T =
+				Cast<const UIntenSelectableMultiPointScoring>(VisProxy->Component.Get());
+			ScoringBehaviourPropertyPath = FComponentPropertyPath(T);
+
+			FMultiPointProxy* Proxy = (FMultiPointProxy*)VisProxy;
+			CurrentSelectionIndex = Proxy->TargetIndex;
+			// UE_LOG(LogTemp, Warning, TEXT("Handling Click %i"), CurrentSelectionIndex);
+		}
+		else
+		{
+			CurrentSelectionIndex = INDEX_NONE;
+			// UE_LOG(LogTemp, Warning, TEXT("Handling Click => no selection"));
+		}
+	}
+	else
+	{
+		CurrentSelectionIndex = INDEX_NONE;
+		// UE_LOG(LogTemp, Warning, TEXT("Handling Click => no selection"));
+	}
+
+	return bEditing;
+}
+
+void FIntenSelectableMultiPointScoringVisualizer::DrawVisualization(const UActorComponent* Component,
+																	const FSceneView* View,
+																	FPrimitiveDrawInterface* PDI)
+{
+	const UIntenSelectableMultiPointScoring* ComponentCasted = Cast<UIntenSelectableMultiPointScoring>(Component);
+
+	if (ComponentCasted != nullptr)
+	{
+		for (int i = 0; i < ComponentCasted->PointsToSelect.Num(); i++)
+		{
+			PDI->SetHitProxy(new FMultiPointProxy(Component, i));
+
+			FVector PointWorld =
+				ComponentCasted->GetComponentTransform().TransformPosition(ComponentCasted->PointsToSelect[i]);
+			PDI->DrawPoint(PointWorld, FColor::Green, 20.f, SDPG_Foreground);
+
+			PDI->SetHitProxy(nullptr);
+		}
+	}
+}
+
+void FIntenSelectableMultiPointScoringVisualizer::EndEditing() {}
+
+UActorComponent* FIntenSelectableMultiPointScoringVisualizer::GetEditedComponent() const
+{
+	return GetEditedScoringComponent();
+}
+
+bool FIntenSelectableMultiPointScoringVisualizer::HandleInputDelta(FEditorViewportClient* ViewportClient,
+																   FViewport* Viewport, FVector& DeltaTranslate,
+																   FRotator& DeltaRotate, FVector& DeltaScale)
+{
+	bool bHandled = false;
+
+	if (CurrentSelectionIndex != INDEX_NONE)
+	{
+		UIntenSelectableMultiPointScoring* ScoringComponent = GetEditedScoringComponent();
+		ScoringComponent->Modify();
+
+		const FVector WorldSelection = ScoringComponent->GetComponentTransform().TransformPosition(
+			GetEditedScoringComponent()->PointsToSelect[CurrentSelectionIndex]);
+		const FVector NewWorldPos =
+			ScoringComponent->GetComponentTransform().InverseTransformPosition(WorldSelection + DeltaTranslate);
+		ScoringComponent->PointsToSelect[CurrentSelectionIndex] = NewWorldPos;
+
+		// UE_LOG(LogTemp, Warning, TEXT("New Pos: %s"),
+		// *ScoringComponent->PointsToSelect[CurrentSelectionIndex].ToString());
+
+		ScoringComponent->MarkRenderStateDirty();
+		bHandled = true;
+
+		TArray<FProperty*> Properties;
+		Properties.Add(PointsProperty);
+		NotifyPropertiesModified(ScoringComponent, Properties, EPropertyChangeType::ValueSet);
+
+		GEditor->RedrawLevelEditingViewports(false);
+	}
+	else
+	{
+		// UE_LOG(LogTemp, Warning, TEXT("No Current Selection!"));
+	}
+
+	return bHandled;
+}
+
+UIntenSelectableMultiPointScoring* FIntenSelectableMultiPointScoringVisualizer::GetEditedScoringComponent() const
+{
+	return Cast<UIntenSelectableMultiPointScoring>(ScoringBehaviourPropertyPath.GetComponent());
+}
+
+bool FIntenSelectableMultiPointScoringVisualizer::GetWidgetLocation(const FEditorViewportClient* ViewportClient,
+																	FVector& OutLocation) const
+{
+	if (GetEditedScoringComponent() && CurrentSelectionIndex != INDEX_NONE)
+	{
+		OutLocation = GetCurrentVectorWorld();
+
+		return true;
+	}
+
+	return false;
+}
diff --git a/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableMultiRectangleScoringVisualizer.cpp b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableMultiRectangleScoringVisualizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8096efefa9a261de88bc6cbc0faf101b7d9bd019
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableMultiRectangleScoringVisualizer.cpp
@@ -0,0 +1,271 @@
+#include "ActorEditorUtils.h"
+#include "Interaction/IntenSelectableRectangleScoringVisualizer.h"
+#include "SceneManagement.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableRectangleScoring.h"
+
+IMPLEMENT_HIT_PROXY(FRectangleProxy, HComponentVisProxy);
+
+FIntenSelectableRectangleScoringVisualizer::FIntenSelectableRectangleScoringVisualizer()
+{
+	XLengthProperty = FindFProperty<FProperty>(UIntenSelectableRectangleScoring::StaticClass(),
+											   GET_MEMBER_NAME_CHECKED(UIntenSelectableRectangleScoring, XLength));
+	YLengthProperty = FindFProperty<FProperty>(UIntenSelectableRectangleScoring::StaticClass(),
+											   GET_MEMBER_NAME_CHECKED(UIntenSelectableRectangleScoring, YLength));
+}
+
+FIntenSelectableRectangleScoringVisualizer::~FIntenSelectableRectangleScoringVisualizer() {}
+
+bool FIntenSelectableRectangleScoringVisualizer::IsVisualizingArchetype() const
+{
+	return GetEditedScoringComponent() && GetEditedScoringComponent()->GetOwner() &&
+		FActorEditorUtils::IsAPreviewOrInactiveActor(GetEditedScoringComponent()->GetOwner());
+}
+
+FVector FIntenSelectableRectangleScoringVisualizer::GetCurrentVectorWorld() const
+{
+	if (CurrentSelectionIndex == INDEX_NONE)
+	{
+		return FVector::ZeroVector;
+	}
+
+	const FVector X = GetEditedScoringComponent()->GetRightVector() * GetEditedScoringComponent()->XLength;
+	const FVector Y = GetEditedScoringComponent()->GetUpVector() * GetEditedScoringComponent()->YLength;
+
+	const FVector CornerWorld00 =
+		GetEditedScoringComponent()->GetComponentTransform().TransformPosition(FVector::ZeroVector) - (X / 2) - (Y / 2);
+	const FVector CornerWorld10 = CornerWorld00 + X;
+	const FVector CornerWorld01 = CornerWorld00 + Y;
+	const FVector CornerWorld11 = CornerWorld00 + X + Y;
+
+
+	switch (CurrentSelectionIndex)
+	{
+	case 0:
+		// bottom
+		return CornerWorld00 + (CornerWorld10 - CornerWorld00) * 0.5;
+	case 1:
+		// left
+		return CornerWorld00 + (CornerWorld01 - CornerWorld00) * 0.5;
+	case 2:
+		// top
+		return CornerWorld01 + (CornerWorld11 - CornerWorld01) * 0.5;
+	case 3:
+		// right
+		return CornerWorld11 + (CornerWorld10 - CornerWorld11) * 0.5;
+	case 4:
+		// middle
+		return CornerWorld00 + ((CornerWorld10 - CornerWorld00) * 0.5) - ((CornerWorld10 - CornerWorld11) * 0.5);
+	default:
+		return FVector::ZeroVector;
+	}
+}
+
+bool FIntenSelectableRectangleScoringVisualizer::ShowWhenSelected() { return false; }
+
+bool FIntenSelectableRectangleScoringVisualizer::ShouldShowForSelectedSubcomponents(const UActorComponent* Component)
+{
+	return false;
+}
+
+bool FIntenSelectableRectangleScoringVisualizer::VisProxyHandleClick(FEditorViewportClient* InViewportClient,
+																	 HComponentVisProxy* VisProxy,
+																	 const FViewportClick& Click)
+{
+	bool bEditing = false;
+
+	if (VisProxy && VisProxy->Component.IsValid())
+	{
+		bEditing = true;
+
+		if (VisProxy->IsA(FRectangleProxy::StaticGetType()))
+		{
+			const UIntenSelectableRectangleScoring* T =
+				Cast<const UIntenSelectableRectangleScoring>(VisProxy->Component.Get());
+			ScoringBehaviourPropertyPath = FComponentPropertyPath(T);
+
+			FRectangleProxy* Proxy = (FRectangleProxy*)VisProxy;
+			CurrentSelectionIndex = Proxy->TargetIndex;
+		}
+		else
+		{
+			CurrentSelectionIndex = INDEX_NONE;
+		}
+	}
+	else
+	{
+		CurrentSelectionIndex = INDEX_NONE;
+	}
+
+	return bEditing;
+}
+
+void FIntenSelectableRectangleScoringVisualizer::DrawVisualization(const UActorComponent* Component,
+																   const FSceneView* View, FPrimitiveDrawInterface* PDI)
+{
+	const UIntenSelectableRectangleScoring* ComponentCasted = Cast<UIntenSelectableRectangleScoring>(Component);
+
+	if (ComponentCasted != nullptr)
+	{
+		const FVector X = ComponentCasted->GetRightVector() * ComponentCasted->XLength;
+		const FVector Y = ComponentCasted->GetUpVector() * ComponentCasted->YLength;
+
+		const FVector CornerWorld00 =
+			ComponentCasted->GetComponentTransform().TransformPosition(FVector::ZeroVector) - (X / 2) - (Y / 2);
+		const FVector CornerWorld10 = CornerWorld00 + X;
+		const FVector CornerWorld01 = CornerWorld00 + Y;
+		const FVector CornerWorld11 = CornerWorld00 + X + Y;
+
+		// bottom 0
+		PDI->SetHitProxy(new FRectangleProxy(Component, 0));
+		PDI->DrawLine(CornerWorld00, CornerWorld10, FColor::Green, SDPG_Foreground, 3);
+		PDI->SetHitProxy(nullptr);
+
+		// left 1
+		PDI->SetHitProxy(new FRectangleProxy(Component, 1));
+		PDI->DrawLine(CornerWorld00, CornerWorld01, FColor::Green, SDPG_Foreground, 3);
+		PDI->SetHitProxy(nullptr);
+
+		// up 2
+		PDI->SetHitProxy(new FRectangleProxy(Component, 2));
+		PDI->DrawLine(CornerWorld01, CornerWorld11, FColor::Green, SDPG_Foreground, 3);
+		PDI->SetHitProxy(nullptr);
+
+
+		// right 3
+		PDI->SetHitProxy(new FRectangleProxy(Component, 3));
+		PDI->DrawLine(CornerWorld11, CornerWorld10, FColor::Green, SDPG_Foreground, 3);
+		PDI->SetHitProxy(nullptr);
+
+		// middle
+		PDI->SetHitProxy(new FRectangleProxy(Component, 4));
+		const FVector Middle =
+			CornerWorld00 + ((CornerWorld10 - CornerWorld00) * 0.5) - ((CornerWorld10 - CornerWorld11) * 0.5);
+		PDI->DrawPoint(Middle, FColor::Green, 20, SDPG_Foreground);
+		PDI->SetHitProxy(nullptr);
+	}
+}
+
+void FIntenSelectableRectangleScoringVisualizer::EndEditing() { GEditor->RedrawLevelEditingViewports(true); }
+
+UActorComponent* FIntenSelectableRectangleScoringVisualizer::GetEditedComponent() const
+{
+	return GetEditedScoringComponent();
+}
+
+UIntenSelectableRectangleScoring* FIntenSelectableRectangleScoringVisualizer::GetEditedScoringComponent() const
+{
+	return Cast<UIntenSelectableRectangleScoring>(ScoringBehaviourPropertyPath.GetComponent());
+}
+
+bool FIntenSelectableRectangleScoringVisualizer::HandleInputDelta(FEditorViewportClient* ViewportClient,
+																  FViewport* Viewport, FVector& DeltaTranslate,
+																  FRotator& DeltaRotate, FVector& DeltaScale)
+{
+	bool bHandled = false;
+
+	if (CurrentSelectionIndex != INDEX_NONE)
+	{
+		UIntenSelectableRectangleScoring* ScoringComponent = GetEditedScoringComponent();
+		ScoringComponent->Modify();
+
+		switch (CurrentSelectionIndex)
+		{
+		case 0:
+			// bottom
+			ScoringComponent->YLength -= DeltaTranslate.Z;
+			if (ScoringComponent->YLength < 0.1)
+			{
+				ScoringComponent->YLength = 0.1;
+			}
+			else
+			{
+				ScoringComponent->AddLocalOffset(FVector::UpVector * DeltaTranslate.Z / 2);
+			}
+			bHandled = true;
+			break;
+		case 1:
+			// left
+			ScoringComponent->XLength -= DeltaTranslate.Y;
+			if (ScoringComponent->XLength < 0.1)
+			{
+				ScoringComponent->XLength = 0.1;
+			}
+			else
+			{
+				ScoringComponent->AddLocalOffset(FVector::RightVector * DeltaTranslate.Y / 2);
+			}
+			bHandled = true;
+			break;
+		case 2:
+			// top
+			ScoringComponent->YLength += DeltaTranslate.Z;
+			if (ScoringComponent->YLength < 0.1)
+			{
+				ScoringComponent->YLength = 0.1;
+			}
+			else
+			{
+				ScoringComponent->AddLocalOffset(FVector::UpVector * DeltaTranslate.Z / 2);
+			}
+			bHandled = true;
+			break;
+		case 3:
+			// right
+			ScoringComponent->XLength += DeltaTranslate.Y;
+			if (ScoringComponent->XLength < 0.1)
+			{
+				ScoringComponent->XLength = 0.1;
+			}
+			else
+			{
+				ScoringComponent->AddLocalOffset(FVector::RightVector * DeltaTranslate.Y / 2);
+			}
+			bHandled = true;
+			break;
+		case 4:
+			{
+				// middle
+				const FVector WorldCenter = ScoringComponent->GetComponentLocation();
+				const FVector NewWorldCenter = WorldCenter + DeltaTranslate;
+				ScoringComponent->SetWorldLocation(NewWorldCenter);
+				ScoringComponent->AddWorldRotation(DeltaRotate);
+
+				const FVector LocalScaleDelta =
+					ScoringComponent->GetComponentTransform().InverseTransformVector(DeltaScale);
+				ScoringComponent->XLength += LocalScaleDelta.Y * 4;
+				ScoringComponent->YLength += LocalScaleDelta.Z * 4;
+				bHandled = true;
+				break;
+			}
+		default:
+			bHandled = false;
+			break;
+		}
+
+		TArray<FProperty*> Properties;
+		Properties.Add(XLengthProperty);
+		Properties.Add(YLengthProperty);
+		NotifyPropertiesModified(ScoringComponent, Properties, EPropertyChangeType::ValueSet);
+
+		return bHandled;
+	}
+	else
+	{
+		// UE_LOG(LogTemp, Warning, TEXT("No Current Selection!"));
+	}
+
+	return false;
+}
+
+bool FIntenSelectableRectangleScoringVisualizer::GetWidgetLocation(const FEditorViewportClient* ViewportClient,
+																   FVector& OutLocation) const
+{
+	if (CurrentSelectionIndex != INDEX_NONE)
+	{
+		OutLocation = GetCurrentVectorWorld();
+
+		return true;
+	}
+
+	return false;
+}
diff --git a/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableSphereScoringVisualizer.cpp b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableSphereScoringVisualizer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..34657800ad77a3ee67fffb8124fcbae5dea14a7d
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Private/Interaction/IntenSelectableSphereScoringVisualizer.cpp
@@ -0,0 +1,167 @@
+#include "Interaction/IntenSelectableSphereScoringVisualizer.h"
+
+#include "ActorEditorUtils.h"
+#include "SceneManagement.h"
+#include "MaterialShared.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableSphereScoring.h"
+#include "Kismet/KismetMathLibrary.h"
+#include "Materials/MaterialInstance.h"
+
+IMPLEMENT_HIT_PROXY(FSphereProxy, HComponentVisProxy);
+
+FIntenSelectableSphereScoringVisualizer::FIntenSelectableSphereScoringVisualizer() :
+	DebugMaterial(FColoredMaterialRenderProxy(GEngine->ConstraintLimitMaterial->GetRenderProxy(), FColor::Green))
+{
+	PointsProperty = FindFProperty<FProperty>(UIntenSelectableSphereScoring::StaticClass(),
+											  GET_MEMBER_NAME_CHECKED(UIntenSelectableSphereScoring, Radius));
+}
+
+FIntenSelectableSphereScoringVisualizer::~FIntenSelectableSphereScoringVisualizer() {}
+
+bool FIntenSelectableSphereScoringVisualizer::IsVisualizingArchetype() const
+{
+	return GetEditedScoringComponent() && GetEditedScoringComponent()->GetOwner() &&
+		FActorEditorUtils::IsAPreviewOrInactiveActor(GetEditedScoringComponent()->GetOwner());
+}
+
+FVector FIntenSelectableSphereScoringVisualizer::GetCurrentVectorWorld() const
+{
+	return GetEditedScoringComponent()->GetComponentLocation();
+}
+
+bool FIntenSelectableSphereScoringVisualizer::ShowWhenSelected() { return false; }
+
+bool FIntenSelectableSphereScoringVisualizer::ShouldShowForSelectedSubcomponents(const UActorComponent* Component)
+{
+	return false;
+}
+
+bool FIntenSelectableSphereScoringVisualizer::VisProxyHandleClick(FEditorViewportClient* InViewportClient,
+																  HComponentVisProxy* VisProxy,
+																  const FViewportClick& Click)
+{
+	bool bEditing = false;
+
+	// UE_LOG(LogTemp, Warning, TEXT("Handling Click"));
+
+	if (VisProxy && VisProxy->Component.IsValid())
+	{
+		bEditing = true;
+
+		if (VisProxy->IsA(FSphereProxy::StaticGetType()))
+		{
+			const UIntenSelectableSphereScoring* T =
+				Cast<const UIntenSelectableSphereScoring>(VisProxy->Component.Get());
+			ScoringBehaviourPropertyPath = FComponentPropertyPath(T);
+
+			FSphereProxy* Proxy = (FSphereProxy*)VisProxy;
+			CurrentSelectionIndex = Proxy->TargetIndex;
+		}
+		else
+		{
+			CurrentSelectionIndex = INDEX_NONE;
+		}
+	}
+	else
+	{
+		CurrentSelectionIndex = INDEX_NONE;
+	}
+
+	return bEditing;
+}
+
+void FIntenSelectableSphereScoringVisualizer::DrawVisualization(const UActorComponent* Component,
+																const FSceneView* View, FPrimitiveDrawInterface* PDI)
+{
+	const UIntenSelectableSphereScoring* ComponentCasted = Cast<UIntenSelectableSphereScoring>(Component);
+
+	if (ComponentCasted != nullptr)
+	{
+		PDI->SetHitProxy(new FSphereProxy(Component, 0));
+
+		DrawSphere(PDI, ComponentCasted->GetComponentLocation(), FRotator::ZeroRotator,
+				   FVector::OneVector * ComponentCasted->Radius, 50, 50, &DebugMaterial, 0, false);
+
+		PDI->SetHitProxy(nullptr);
+	}
+}
+
+void FIntenSelectableSphereScoringVisualizer::EndEditing() {}
+
+UActorComponent* FIntenSelectableSphereScoringVisualizer::GetEditedComponent() const
+{
+	return GetEditedScoringComponent();
+}
+
+UIntenSelectableSphereScoring* FIntenSelectableSphereScoringVisualizer::GetEditedScoringComponent() const
+{
+	return Cast<UIntenSelectableSphereScoring>(ScoringBehaviourPropertyPath.GetComponent());
+}
+
+bool FIntenSelectableSphereScoringVisualizer::HandleInputDelta(FEditorViewportClient* ViewportClient,
+															   FViewport* Viewport, FVector& DeltaTranslate,
+															   FRotator& DeltaRotate, FVector& DeltaScale)
+{
+	bool bHandled = false;
+
+	if (true || CurrentSelectionIndex != INDEX_NONE)
+	{
+		// UE_LOG(LogTemp, Warning, TEXT("Current Selection! %s"), *DeltaTranslate.ToString());
+
+		if ((true || CurrentSelectionIndex == 0) && GetEditedComponent())
+		{
+			UIntenSelectableSphereScoring* ScoringComponent = GetEditedScoringComponent();
+			ScoringComponent->Modify();
+
+			const FVector LocalCenter = ScoringComponent->GetComponentLocation();
+			const FVector NewCenter = LocalCenter + DeltaTranslate;
+
+			ScoringComponent->SetWorldLocation(NewCenter);
+			ScoringComponent->AddWorldRotation(DeltaRotate);
+
+			const float AverageScaleFactor = (DeltaScale.X + DeltaScale.Y + DeltaScale.Z) / 3.0f;
+
+			// Apply the average scale factor to the original radius
+			float NewRadius;
+			if (AverageScaleFactor > 0)
+			{
+				// Scale up: Increase the radius
+				NewRadius = ScoringComponent->Radius * (1.0f + FMath::Abs(AverageScaleFactor));
+			}
+			else
+			{
+				// Scale down: Decrease the radius, ensuring not to reduce it below a minimum threshold (e.g., not
+				// making it negative)
+				NewRadius = ScoringComponent->Radius * FMath::Max(0.1f, 1.0f + AverageScaleFactor);
+			}
+			ScoringComponent->Radius = NewRadius;
+
+			TArray<FProperty*> Properties;
+			Properties.Add(PointsProperty);
+			NotifyPropertiesModified(ScoringComponent, Properties, EPropertyChangeType::ValueSet);
+
+			ScoringComponent->MarkRenderStateDirty();
+			GEditor->RedrawLevelEditingViewports(false);
+			bHandled = true;
+		}
+	}
+	else
+	{
+		// UE_LOG(LogTemp, Warning, TEXT("No Current Selection!"));
+	}
+
+	return bHandled;
+}
+
+bool FIntenSelectableSphereScoringVisualizer::GetWidgetLocation(const FEditorViewportClient* ViewportClient,
+																FVector& OutLocation) const
+{
+	if (CurrentSelectionIndex != INDEX_NONE)
+	{
+		OutLocation = GetCurrentVectorWorld();
+
+		return true;
+	}
+
+	return false;
+}
diff --git a/Source/RWTHVRToolkitEditor/Private/RWTHVRToolkitEditor.cpp b/Source/RWTHVRToolkitEditor/Private/RWTHVRToolkitEditor.cpp
index e53695d2b66804e9131f4dccbd5ec9a2856c6d71..a35e9354035fa20e13cf56e54d92ffe2a54d3c28 100644
--- a/Source/RWTHVRToolkitEditor/Private/RWTHVRToolkitEditor.cpp
+++ b/Source/RWTHVRToolkitEditor/Private/RWTHVRToolkitEditor.cpp
@@ -1,14 +1,115 @@
 #include "RWTHVRToolkitEditor.h"
-
 #include "UnrealEdGlobals.h"
 #include "Editor/UnrealEdEngine.h"
+#include "Interaction/IntenSelectableCylinderScoringVisualizer.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableCircleScoring.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableCubeScoring.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableCylinderScoring.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableLineScoring.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableMultiPointScoring.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableRectangleScoring.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableSphereScoring.h"
+
+#include "Interaction/IntenSelectableCircleScoringVisualizer.h"
+#include "Interaction/IntenSelectableCubeScoringVisualizer.h"
+#include "Interaction/IntenSelectableLineScoringVisualizer.h"
+#include "Interaction/IntenSelectableMultiPointScoringVisualizer.h"
+#include "Interaction/IntenSelectableRectangleScoringVisualizer.h"
+#include "Interaction/IntenSelectableSphereScoringVisualizer.h"
 
 IMPLEMENT_GAME_MODULE(FRWTHVRToolkitEditorModule, RWTHVRToolkitEditor);
 
 #define LOCTEXT_NAMESPACE "RWTHVRToolkitEditor"
 
-void FRWTHVRToolkitEditorModule::StartupModule() {}
+void FRWTHVRToolkitEditorModule::StartupModule()
+{
+	if (GUnrealEd != nullptr)
+	{
+		const TSharedPtr<FComponentVisualizer> IntenSelectableLineVisualizer =
+			MakeShareable(new FIntenSelectableLineScoringVisualizer());
+
+		if (IntenSelectableLineVisualizer.IsValid())
+		{
+			GUnrealEd->RegisterComponentVisualizer(UIntenSelectableLineScoring::StaticClass()->GetFName(),
+												   IntenSelectableLineVisualizer);
+			IntenSelectableLineVisualizer->OnRegister();
+		}
+
+
+		const TSharedPtr<FComponentVisualizer> IntenSelectableMultipointScoringVisualizer =
+			MakeShareable(new FIntenSelectableMultiPointScoringVisualizer());
+
+		if (IntenSelectableMultipointScoringVisualizer.IsValid())
+		{
+			GUnrealEd->RegisterComponentVisualizer(UIntenSelectableMultiPointScoring::StaticClass()->GetFName(),
+												   IntenSelectableMultipointScoringVisualizer);
+			IntenSelectableMultipointScoringVisualizer->OnRegister();
+		}
+
+		const TSharedPtr<FComponentVisualizer> IntenSelectableCircleScoringVisualizer =
+			MakeShareable(new FIntenSelectableCircleScoringVisualizer());
+
+		if (IntenSelectableCircleScoringVisualizer.IsValid())
+		{
+			GUnrealEd->RegisterComponentVisualizer(UIntenSelectableCircleScoring::StaticClass()->GetFName(),
+												   IntenSelectableCircleScoringVisualizer);
+			IntenSelectableCircleScoringVisualizer->OnRegister();
+		}
+
+		const TSharedPtr<FComponentVisualizer> IntenSelectableRectangleScoringVisualizer =
+			MakeShareable(new FIntenSelectableRectangleScoringVisualizer());
+
+		if (IntenSelectableRectangleScoringVisualizer.IsValid())
+		{
+			GUnrealEd->RegisterComponentVisualizer(UIntenSelectableRectangleScoring::StaticClass()->GetFName(),
+												   IntenSelectableRectangleScoringVisualizer);
+			IntenSelectableRectangleScoringVisualizer->OnRegister();
+		}
+
+		const TSharedPtr<FComponentVisualizer> IntenSelectableSphereScoringVisualizer =
+			MakeShareable(new FIntenSelectableSphereScoringVisualizer());
+
+		if (IntenSelectableSphereScoringVisualizer.IsValid())
+		{
+			GUnrealEd->RegisterComponentVisualizer(UIntenSelectableSphereScoring::StaticClass()->GetFName(),
+												   IntenSelectableSphereScoringVisualizer);
+			IntenSelectableSphereScoringVisualizer->OnRegister();
+		}
+
+		const TSharedPtr<FComponentVisualizer> IntenSelectableCubeScoringVisualizer =
+			MakeShareable(new FIntenSelectableCubeScoringVisualizer());
+
+		if (IntenSelectableCubeScoringVisualizer.IsValid())
+		{
+			GUnrealEd->RegisterComponentVisualizer(UIntenSelectableCubeScoring::StaticClass()->GetFName(),
+												   IntenSelectableCubeScoringVisualizer);
+			IntenSelectableCubeScoringVisualizer->OnRegister();
+		}
+
+		const TSharedPtr<FComponentVisualizer> IntenSelectableCylinderScoringVisualizer =
+			MakeShareable(new FIntenSelectableCylinderScoringVisualizer());
+
+		if (IntenSelectableCylinderScoringVisualizer.IsValid())
+		{
+			GUnrealEd->RegisterComponentVisualizer(UIntenSelectableCylinderScoring::StaticClass()->GetFName(),
+												   IntenSelectableCylinderScoringVisualizer);
+			IntenSelectableCylinderScoringVisualizer->OnRegister();
+		}
+	}
+}
 
-void FRWTHVRToolkitEditorModule::ShutdownModule() {}
+void FRWTHVRToolkitEditorModule::ShutdownModule()
+{
+	if (GUnrealEd != nullptr)
+	{
+		GUnrealEd->UnregisterComponentVisualizer(UIntenSelectableLineScoring::StaticClass()->GetFName());
+		GUnrealEd->UnregisterComponentVisualizer(UIntenSelectableMultiPointScoring::StaticClass()->GetFName());
+		GUnrealEd->UnregisterComponentVisualizer(UIntenSelectableCircleScoring::StaticClass()->GetFName());
+		GUnrealEd->UnregisterComponentVisualizer(UIntenSelectableRectangleScoring::StaticClass()->GetFName());
+		GUnrealEd->UnregisterComponentVisualizer(UIntenSelectableSphereScoring::StaticClass()->GetFName());
+		GUnrealEd->UnregisterComponentVisualizer(UIntenSelectableCubeScoring::StaticClass()->GetFName());
+		GUnrealEd->UnregisterComponentVisualizer(UIntenSelectableCylinderScoring::StaticClass()->GetFName());
+	}
+}
 
-#undef LOCTEXT_NAMESPACE
+#undef LOCTEXT_NAMESPACE
\ No newline at end of file
diff --git a/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableCircleScoringVisualizer.h b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableCircleScoringVisualizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..42880d84730f4166abedc015739d26369303bef2
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableCircleScoringVisualizer.h
@@ -0,0 +1,54 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "ComponentVisualizer.h"
+class UIntenSelectableCircleScoring;
+/**
+ *
+ */
+class FPrimitiveDrawInterface;
+class FSceneView;
+
+struct FCircleProxy : HComponentVisProxy
+{
+	DECLARE_HIT_PROXY();
+
+	FCircleProxy(const UActorComponent* InComponent, int32 InTargetIndex) :
+		HComponentVisProxy(InComponent), TargetIndex(InTargetIndex)
+	{
+	}
+
+	int32 TargetIndex;
+};
+
+
+class RWTHVRTOOLKITEDITOR_API FIntenSelectableCircleScoringVisualizer : public FComponentVisualizer
+{
+private:
+	int CurrentSelectionIndex;
+	FProperty* PointsProperty;
+	FComponentPropertyPath ScoringBehaviourPropertyPath;
+
+public:
+	FIntenSelectableCircleScoringVisualizer();
+	~FIntenSelectableCircleScoringVisualizer();
+
+	FVector GetCurrentVectorWorld() const;
+
+	virtual bool IsVisualizingArchetype() const override;
+	UIntenSelectableCircleScoring* GetEditedScoringComponent() const;
+
+	virtual bool ShowWhenSelected() override;
+	virtual bool ShouldShowForSelectedSubcomponents(const UActorComponent* Component) override;
+	virtual bool VisProxyHandleClick(FEditorViewportClient* InViewportClient, HComponentVisProxy* VisProxy,
+									 const FViewportClick& Click) override;
+	virtual void DrawVisualization(const UActorComponent* Component, const FSceneView* View,
+								   FPrimitiveDrawInterface* PDI) override;
+	virtual void EndEditing() override;
+	virtual UActorComponent* GetEditedComponent() const override;
+	virtual bool HandleInputDelta(FEditorViewportClient* ViewportClient, FViewport* Viewport, FVector& DeltaTranslate,
+								  FRotator& DeltaRotate, FVector& DeltaScale) override;
+	virtual bool GetWidgetLocation(const FEditorViewportClient* ViewportClient, FVector& OutLocation) const override;
+};
diff --git a/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableCubeScoringVisualizer.h b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableCubeScoringVisualizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..6ffffcfbdeaa5eed9e91261ee3ec94b9938928a1
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableCubeScoringVisualizer.h
@@ -0,0 +1,53 @@
+#pragma once
+
+#include "CoreMinimal.h"
+#include "ComponentVisualizer.h"
+#include "Materials/MaterialRenderProxy.h"
+
+class UIntenSelectableCubeScoring;
+class FPrimitiveDrawInterface;
+class FSceneView;
+
+struct FCubeProxy : HComponentVisProxy
+{
+	DECLARE_HIT_PROXY();
+
+	FCubeProxy(const UActorComponent* InComponent, int32 InTargetIndex) :
+		HComponentVisProxy(InComponent), TargetIndex(InTargetIndex)
+	{
+	}
+
+	int32 TargetIndex;
+};
+
+
+class RWTHVRTOOLKITEDITOR_API FIntenSelectableCubeScoringVisualizer : public FComponentVisualizer
+{
+private:
+	int CurrentSelectionIndex;
+
+	FColoredMaterialRenderProxy DebugMaterial;
+	FProperty* PointsProperty;
+	FComponentPropertyPath ScoringBehaviourPropertyPath;
+
+public:
+	FIntenSelectableCubeScoringVisualizer();
+	~FIntenSelectableCubeScoringVisualizer();
+
+	FVector GetCurrentVectorWorld() const;
+
+	virtual bool IsVisualizingArchetype() const override;
+	UIntenSelectableCubeScoring* GetEditedScoringComponent() const;
+
+	virtual bool ShowWhenSelected() override;
+	virtual bool ShouldShowForSelectedSubcomponents(const UActorComponent* Component) override;
+	virtual bool VisProxyHandleClick(FEditorViewportClient* InViewportClient, HComponentVisProxy* VisProxy,
+									 const FViewportClick& Click) override;
+	virtual void DrawVisualization(const UActorComponent* Component, const FSceneView* View,
+								   FPrimitiveDrawInterface* PDI) override;
+	virtual void EndEditing() override;
+	virtual UActorComponent* GetEditedComponent() const override;
+	virtual bool HandleInputDelta(FEditorViewportClient* ViewportClient, FViewport* Viewport, FVector& DeltaTranslate,
+								  FRotator& DeltaRotate, FVector& DeltaScale) override;
+	virtual bool GetWidgetLocation(const FEditorViewportClient* ViewportClient, FVector& OutLocation) const override;
+};
diff --git a/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableCylinderScoringVisualizer.h b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableCylinderScoringVisualizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e796151b1e75a07b186e71bfbb70aec56ecfa51
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableCylinderScoringVisualizer.h
@@ -0,0 +1,78 @@
+#pragma once
+
+#include "CoreMinimal.h"
+#include "ComponentVisualizer.h"
+#include "Interaction/Interactables/IntenSelect/IntenSelectableCylinderScoring.h"
+#include "Materials/MaterialRenderProxy.h"
+
+class UIntenSelectableLineScoring;
+class FPrimitiveDrawInterface;
+class FSceneView;
+
+/**Base class for clickable targeting editing proxies*/
+struct HTargetingVisProxy : public HComponentVisProxy
+{
+	DECLARE_HIT_PROXY();
+
+	HTargetingVisProxy(const UActorComponent* InComponent) : HComponentVisProxy(InComponent, HPP_Wireframe) {}
+};
+
+/**Proxy for target*/
+struct HTargetProxy : public HTargetingVisProxy
+{
+	DECLARE_HIT_PROXY();
+
+	HTargetProxy(const UActorComponent* InComponent, int32 InTargetIndex) :
+		HTargetingVisProxy(InComponent), TargetIndex(InTargetIndex)
+	{
+	}
+
+	int32 TargetIndex;
+};
+
+struct FCylinderPointProxy : HComponentVisProxy
+{
+	DECLARE_HIT_PROXY();
+
+	FCylinderPointProxy(const UActorComponent* InComponent, int32 InTargetIndex) :
+		HComponentVisProxy(InComponent), TargetIndex(InTargetIndex)
+	{
+	}
+
+	int32 TargetIndex;
+};
+
+
+class RWTHVRTOOLKITEDITOR_API FIntenSelectableCylinderScoringVisualizer : public FComponentVisualizer
+{
+private:
+	int CurrentCylinderSelectionIndex;
+	FColoredMaterialRenderProxy DebugMaterial;
+	FProperty* RadiusProperty;
+	FProperty* PointsProperty;
+	FProperty* LocationProperty;
+	FComponentPropertyPath ScoringBehaviourPropertyPath;
+
+public:
+	FIntenSelectableCylinderScoringVisualizer();
+	~FIntenSelectableCylinderScoringVisualizer();
+
+	virtual bool IsVisualizingArchetype() const override;
+	virtual bool ShowWhenSelected() override;
+	virtual bool ShouldShowForSelectedSubcomponents(const UActorComponent* Component) override;
+
+	virtual bool VisProxyHandleClick(FEditorViewportClient* InViewportClient, HComponentVisProxy* VisProxy,
+									 const FViewportClick& Click) override;
+	virtual bool HandleInputDelta(FEditorViewportClient* ViewportClient, FViewport* Viewport, FVector& DeltaTranslate,
+								  FRotator& DeltaRotate, FVector& DeltaScale) override;
+	virtual void DrawVisualization(const UActorComponent* Component, const FSceneView* View,
+								   FPrimitiveDrawInterface* PDI) override;
+
+	FVector GetCurrentVectorWorld() const;
+	virtual bool GetWidgetLocation(const FEditorViewportClient* ViewportClient, FVector& OutLocation) const override;
+
+	virtual UActorComponent* GetEditedComponent() const override;
+	UIntenSelectableCylinderScoring* GetEditedScoringComponent() const;
+
+	virtual void EndEditing() override;
+};
diff --git a/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableLineScoringVisualizer.h b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableLineScoringVisualizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..1bb024784e513db19713c1f4df74f430c56792a7
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableLineScoringVisualizer.h
@@ -0,0 +1,57 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "ComponentVisualizer.h"
+class UIntenSelectableLineScoring;
+/**
+ *
+ */
+class FPrimitiveDrawInterface;
+class FSceneView;
+
+struct FLinePointProxy : HComponentVisProxy
+{
+	DECLARE_HIT_PROXY();
+
+	FLinePointProxy(const UActorComponent* InComponent, int32 InTargetIndex) :
+		HComponentVisProxy(InComponent), TargetIndex(InTargetIndex)
+	{
+	}
+
+	int32 TargetIndex;
+};
+
+
+class RWTHVRTOOLKITEDITOR_API FIntenSelectableLineScoringVisualizer : public FComponentVisualizer
+{
+private:
+	int CurrentLineSelectionIndex;
+	FProperty* PointsProperty;
+	UIntenSelectableLineScoring* LineBehavior;
+	FComponentPropertyPath ScoringBehaviourPropertyPath;
+
+public:
+	FIntenSelectableLineScoringVisualizer();
+	~FIntenSelectableLineScoringVisualizer();
+
+	FVector GetCurrentVectorWorld() const;
+
+	virtual bool IsVisualizingArchetype() const override;
+	virtual bool ShowWhenSelected() override;
+	virtual bool ShouldShowForSelectedSubcomponents(const UActorComponent* Component) override;
+	virtual void DrawVisualization(const UActorComponent* Component, const FSceneView* View,
+								   FPrimitiveDrawInterface* PDI) override;
+
+	virtual bool VisProxyHandleClick(FEditorViewportClient* InViewportClient, HComponentVisProxy* VisProxy,
+									 const FViewportClick& Click) override;
+	virtual bool HandleInputDelta(FEditorViewportClient* ViewportClient, FViewport* Viewport, FVector& DeltaTranslate,
+								  FRotator& DeltaRotate, FVector& DeltaScale) override;
+
+	virtual bool GetWidgetLocation(const FEditorViewportClient* ViewportClient, FVector& OutLocation) const override;
+	virtual UActorComponent* GetEditedComponent() const override;
+	UIntenSelectableLineScoring* GetEditedScoringComponent() const;
+
+	virtual void EndEditing() override;
+};
diff --git a/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableMultiPointScoringVisualizer.h b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableMultiPointScoringVisualizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..c46253283484cdcffee3bc49c15dda61a4a1190a
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableMultiPointScoringVisualizer.h
@@ -0,0 +1,52 @@
+#pragma once
+
+#include "CoreMinimal.h"
+#include "ComponentVisualizer.h"
+
+class UIntenSelectableMultiPointScoring;
+class FPrimitiveDrawInterface;
+class FSceneView;
+
+struct FMultiPointProxy : HComponentVisProxy
+{
+	DECLARE_HIT_PROXY();
+
+	FMultiPointProxy(const UActorComponent* InComponent, int32 InTargetIndex) :
+		HComponentVisProxy(InComponent), TargetIndex(InTargetIndex)
+	{
+	}
+
+	int32 TargetIndex;
+};
+
+
+class RWTHVRTOOLKITEDITOR_API FIntenSelectableMultiPointScoringVisualizer : public FComponentVisualizer
+{
+private:
+	int CurrentSelectionIndex;
+	FProperty* PointsProperty;
+	FComponentPropertyPath ScoringBehaviourPropertyPath;
+
+public:
+	FIntenSelectableMultiPointScoringVisualizer();
+	~FIntenSelectableMultiPointScoringVisualizer();
+
+	virtual bool IsVisualizingArchetype() const override;
+	virtual bool ShowWhenSelected() override;
+	virtual bool ShouldShowForSelectedSubcomponents(const UActorComponent* Component) override;
+
+	virtual bool VisProxyHandleClick(FEditorViewportClient* InViewportClient, HComponentVisProxy* VisProxy,
+									 const FViewportClick& Click) override;
+	virtual void DrawVisualization(const UActorComponent* Component, const FSceneView* View,
+								   FPrimitiveDrawInterface* PDI) override;
+	virtual bool HandleInputDelta(FEditorViewportClient* ViewportClient, FViewport* Viewport, FVector& DeltaTranslate,
+								  FRotator& DeltaRotate, FVector& DeltaScale) override;
+
+	FVector GetCurrentVectorWorld() const;
+	virtual bool GetWidgetLocation(const FEditorViewportClient* ViewportClient, FVector& OutLocation) const override;
+
+	virtual UActorComponent* GetEditedComponent() const override;
+	UIntenSelectableMultiPointScoring* GetEditedScoringComponent() const;
+
+	virtual void EndEditing() override;
+};
diff --git a/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableRectangleScoringVisualizer.h b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableRectangleScoringVisualizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..983c87788e609d99950e365a457bee455d97cdd6
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableRectangleScoringVisualizer.h
@@ -0,0 +1,57 @@
+// Fill out your copyright notice in the Description page of Project Settings.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "ComponentVisualizer.h"
+class UIntenSelectableRectangleScoring;
+/**
+ *
+ */
+class FPrimitiveDrawInterface;
+class FSceneView;
+
+struct FRectangleProxy : HComponentVisProxy
+{
+	DECLARE_HIT_PROXY();
+
+	FRectangleProxy(const UActorComponent* InComponent, int32 InTargetIndex) :
+		HComponentVisProxy(InComponent), TargetIndex(InTargetIndex)
+	{
+	}
+
+	int32 TargetIndex;
+};
+
+
+class RWTHVRTOOLKITEDITOR_API FIntenSelectableRectangleScoringVisualizer : public FComponentVisualizer
+{
+private:
+	int CurrentSelectionIndex;
+	FProperty* XLengthProperty;
+	FProperty* YLengthProperty;
+	FComponentPropertyPath ScoringBehaviourPropertyPath;
+
+public:
+	FIntenSelectableRectangleScoringVisualizer();
+	~FIntenSelectableRectangleScoringVisualizer();
+
+	virtual bool IsVisualizingArchetype() const override;
+	virtual bool ShowWhenSelected() override;
+	virtual bool ShouldShowForSelectedSubcomponents(const UActorComponent* Component) override;
+
+	virtual bool VisProxyHandleClick(FEditorViewportClient* InViewportClient, HComponentVisProxy* VisProxy,
+									 const FViewportClick& Click) override;
+	virtual void DrawVisualization(const UActorComponent* Component, const FSceneView* View,
+								   FPrimitiveDrawInterface* PDI) override;
+	virtual bool HandleInputDelta(FEditorViewportClient* ViewportClient, FViewport* Viewport, FVector& DeltaTranslate,
+								  FRotator& DeltaRotate, FVector& DeltaScale) override;
+
+	FVector GetCurrentVectorWorld() const;
+	virtual bool GetWidgetLocation(const FEditorViewportClient* ViewportClient, FVector& OutLocation) const override;
+
+	virtual UActorComponent* GetEditedComponent() const override;
+	UIntenSelectableRectangleScoring* GetEditedScoringComponent() const;
+
+	virtual void EndEditing() override;
+};
diff --git a/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableSphereScoringVisualizer.h b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableSphereScoringVisualizer.h
new file mode 100644
index 0000000000000000000000000000000000000000..40e41d1707d63ac812e5e47b6665f43190a4a030
--- /dev/null
+++ b/Source/RWTHVRToolkitEditor/Public/Interaction/IntenSelectableSphereScoringVisualizer.h
@@ -0,0 +1,55 @@
+#pragma once
+
+#include "CoreMinimal.h"
+#include "ComponentVisualizer.h"
+#include "Materials/MaterialRenderProxy.h"
+
+class UIntenSelectableSphereScoring;
+class FPrimitiveDrawInterface;
+class FSceneView;
+
+struct FSphereProxy : HComponentVisProxy
+{
+	DECLARE_HIT_PROXY();
+
+	FSphereProxy(const UActorComponent* InComponent, int32 InTargetIndex) :
+		HComponentVisProxy(InComponent), TargetIndex(InTargetIndex)
+	{
+	}
+
+	int32 TargetIndex;
+};
+
+
+class RWTHVRTOOLKITEDITOR_API FIntenSelectableSphereScoringVisualizer : public FComponentVisualizer
+{
+private:
+	int CurrentSelectionIndex;
+	FColoredMaterialRenderProxy DebugMaterial;
+	FProperty* PointsProperty;
+	FComponentPropertyPath ScoringBehaviourPropertyPath;
+
+public:
+	FIntenSelectableSphereScoringVisualizer();
+	~FIntenSelectableSphereScoringVisualizer();
+
+
+	virtual bool IsVisualizingArchetype() const override;
+	virtual bool ShowWhenSelected() override;
+	virtual bool ShouldShowForSelectedSubcomponents(const UActorComponent* Component) override;
+
+	virtual bool VisProxyHandleClick(FEditorViewportClient* InViewportClient, HComponentVisProxy* VisProxy,
+									 const FViewportClick& Click) override;
+	virtual void DrawVisualization(const UActorComponent* Component, const FSceneView* View,
+								   FPrimitiveDrawInterface* PDI) override;
+	virtual bool HandleInputDelta(FEditorViewportClient* ViewportClient, FViewport* Viewport, FVector& DeltaTranslate,
+								  FRotator& DeltaRotate, FVector& DeltaScale) override;
+
+	virtual UActorComponent* GetEditedComponent() const override;
+	UIntenSelectableSphereScoring* GetEditedScoringComponent() const;
+
+	FVector GetCurrentVectorWorld() const;
+	virtual bool GetWidgetLocation(const FEditorViewportClient* ViewportClient, FVector& OutLocation) const override;
+
+	virtual void EndEditing() override;
+};