diff --git a/Config/DefaultEditor.ini b/Config/DefaultEditor.ini
new file mode 100644
index 0000000..58552fa
--- /dev/null
+++ b/Config/DefaultEditor.ini
@@ -0,0 +1,8 @@
+[UnrealEd.SimpleMap]
+SimpleMapName=/Game/FirstPerson/Maps/FirstPersonExampleMap
+
+[EditoronlyBP]
+bAllowClassAndBlueprintPinMatching=true
+bReplaceBlueprintWithClass= true
+bDontLoadBlueprintOutsideEditor= true
+bBlueprintIsNotBlueprintType= true
\ No newline at end of file
diff --git a/Config/DefaultEditorPerProjectUserSettings.ini b/Config/DefaultEditorPerProjectUserSettings.ini
new file mode 100644
index 0000000..220a551
--- /dev/null
+++ b/Config/DefaultEditorPerProjectUserSettings.ini
@@ -0,0 +1,2 @@
+[ContentBrowser]
+ContentBrowserTab1.SelectedPaths=/Game/FirstPerson
\ No newline at end of file
diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini
new file mode 100644
index 0000000..366dd3e
--- /dev/null
+++ b/Config/DefaultEngine.ini
@@ -0,0 +1,39 @@
+[/Script/Engine.CollisionProfile]
++Profiles=(Name="Projectile",CollisionEnabled=QueryOnly,ObjectTypeName="Projectile",CustomResponses=,HelpMessage="Preset for projectiles",bCanModify=True)
++DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,Name="Projectile",DefaultResponse=ECR_Block,bTraceType=False,bStaticObject=False)
++EditProfiles=(Name="Trigger",CustomResponses=((Channel=Projectile, Response=ECR_Ignore)))
+
+[/Script/EngineSettings.GameMapsSettings]
+EditorStartupMap=/Game/FirstPersonCPP/Maps/FirstPersonExampleMap.FirstPersonExampleMap
+LocalMapOptions=
+TransitionMap=
+bUseSplitscreen=True
+TwoPlayerSplitscreenLayout=Horizontal
+ThreePlayerSplitscreenLayout=FavorTop
+GameInstanceClass=/Script/Engine.GameInstance
+GameDefaultMap=/Game/ProjetPANNER/Levels/L_EnviroTest_Eden.L_EnviroTest_Eden
+ServerDefaultMap=/Engine/Maps/Entry
+GlobalDefaultGameMode=/Game/ProjetPANNER/GameMode/GM_Panner.GM_Panner_C
+GlobalDefaultServerGameMode=None
+
+[/Script/IOSRuntimeSettings.IOSRuntimeSettings]
+MinimumiOSVersion=IOS_12
+
+
+[/Script/HardwareTargeting.HardwareTargetingSettings]
+TargetedHardwareClass=Desktop
+AppliedTargetedHardwareClass=Desktop
+DefaultGraphicsPerformance=Maximum
+AppliedDefaultGraphicsPerformance=Maximum
+
+[/Script/Engine.Engine]
++ActiveGameNameRedirects=(OldGameName="TP_FirstPerson",NewGameName="/Script/Panner")
++ActiveGameNameRedirects=(OldGameName="/Script/TP_FirstPerson",NewGameName="/Script/Panner")
++ActiveClassRedirects=(OldClassName="TP_FirstPersonProjectile",NewClassName="PannerProjectile")
++ActiveClassRedirects=(OldClassName="TP_FirstPersonHUD",NewClassName="PannerHUD")
++ActiveClassRedirects=(OldClassName="TP_FirstPersonGameMode",NewClassName="PannerGameMode")
++ActiveClassRedirects=(OldClassName="TP_FirstPersonCharacter",NewClassName="PannerCharacter")
+
+[/Script/Engine.RendererSettings]
+r.DefaultFeature.AutoExposure=False
+
diff --git a/Config/DefaultGame.ini b/Config/DefaultGame.ini
new file mode 100644
index 0000000..c56501e
--- /dev/null
+++ b/Config/DefaultGame.ini
@@ -0,0 +1,10 @@
+[ProjectSettings]
+ProjectID=(A=1823396784,B=1298598689,C=1743498150,D=-2048051708)
+ProjectName=First Person Template
+
+[/Script/EngineSettings.GeneralProjectSettings]
+ProjectID=7E0A3B7C4BB9CE08B2B3CD96D57E905E
+
+[StartupActions]
+bAddPacks=True
+InsertPack=(PackSource="StarterContent.upack",PackName="StarterContent")
diff --git a/Config/DefaultInput.ini b/Config/DefaultInput.ini
new file mode 100644
index 0000000..127a3cc
--- /dev/null
+++ b/Config/DefaultInput.ini
@@ -0,0 +1,207 @@
+
+
+[/Script/Engine.InputSettings]
+-AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f))
+-AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f))
+-AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f))
+-AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f))
+-AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f))
+-AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f))
+-AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f))
++AxisConfig=(AxisKeyName="MagicLeap_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MagicLeap_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MagicLeap_Right_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MagicLeap_Right_Touch1_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MagicLeap_Right_Touch1_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MagicLeap_Right_Touch1_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MotionController_Left_Thumbstick_Z",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MotionController_Right_Thumbstick_Z",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MouseWheelAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Gamepad_LeftTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Gamepad_RightTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MotionController_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MotionController_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MotionController_Left_TriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MotionController_Left_Grip1Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MotionController_Left_Grip2Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MotionController_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MotionController_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MotionController_Right_TriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MotionController_Right_Grip1Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MotionController_Right_Grip2Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Gamepad_Special_Left_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Gamepad_Special_Left_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Left_FaceButton1",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Left_Trigger",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Left_FaceButton2",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Left_IndexPointing",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Left_ThumbUp",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Right_FaceButton1",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Right_Trigger",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Right_FaceButton2",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Right_IndexPointing",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Right_ThumbUp",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouchpad_Touchpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouchpad_Touchpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="SteamVR_Knuckles_Left_HandGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="SteamVR_Knuckles_Left_IndexGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="SteamVR_Knuckles_Left_MiddleGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="SteamVR_Knuckles_Left_RingGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="SteamVR_Knuckles_Left_PinkyGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="SteamVR_Knuckles_Right_HandGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="SteamVR_Knuckles_Right_IndexGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="SteamVR_Knuckles_Right_MiddleGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="SteamVR_Knuckles_Right_RingGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="SteamVR_Knuckles_Right_PinkyGrip",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Daydream_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Daydream_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Daydream_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Daydream_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Vive_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Vive_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Vive_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Vive_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Vive_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="Vive_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MixedReality_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MixedReality_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusGo_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusGo_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusGo_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusGo_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Touch",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MagicLeap_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MagicLeap_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MagicLeap_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MagicLeap_Left_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MagicLeap_Left_Touch1_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MagicLeap_Left_Touch1_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MagicLeap_Left_Touch1_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="MagicLeap_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusHand_Left_ThumbPinchStrength",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusHand_Left_IndexPinchStrength",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusHand_Left_MiddlePinchStrength",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusHand_Left_RingPinchStrength",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusHand_Left_PinkPinchStrength",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusHand_Right_ThumbPinchStrength",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusHand_Right_IndexPinchStrength",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusHand_Right_MiddlePinchStrength",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusHand_Right_RingPinchStrength",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
++AxisConfig=(AxisKeyName="OculusHand_Right_PinkPinchStrength",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+bAltEnterTogglesFullscreen=True
+bF11TogglesFullscreen=True
+bUseMouseForTouch=False
+bEnableMouseSmoothing=True
+bEnableFOVScaling=True
+bCaptureMouseOnLaunch=True
+bAlwaysShowTouchInterface=False
+bShowConsoleOnFourFingerTap=True
+bEnableGestureRecognizer=False
+bUseAutocorrect=False
+DefaultViewportMouseCaptureMode=CapturePermanently_IncludingInitialMouseDown
+DefaultViewportMouseLockMode=LockOnCapture
+FOVScale=0.011110
+DoubleClickTime=0.200000
++ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=SpaceBar)
++ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Gamepad_FaceButton_Bottom)
++ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Daydream_Left_Select_Click)
++ActionMappings=(ActionName="Fire",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=LeftMouseButton)
++ActionMappings=(ActionName="Fire",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Gamepad_RightTrigger)
++ActionMappings=(ActionName="Fire",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Daydream_Left_Trackpad_Click)
++ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=R)
++ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Left_Grip_Click)
++ActionMappings=(ActionName="Fire",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Right_Trigger_Click)
++ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Vive_Left_Trigger_Click)
++ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Left_Trigger_Click)
++ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Left_Trigger_Click)
++ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Left_Trigger_Click)
++ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MagicLeap_Left_Trigger)
++ActionMappings=(ActionName="Fire",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Right_Trigger_Click)
++ActionMappings=(ActionName="Fire",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Right_Trigger_Click)
++ActionMappings=(ActionName="Fire",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Right_Trigger_Click)
++ActionMappings=(ActionName="Fire",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MagicLeap_Left_Trackpad_Touch)
++ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MixedReality_Left_Thumbstick_Click)
++ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=OculusTouch_Left_Thumbstick_Click)
++ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=ValveIndex_Left_Thumbstick_Click)
++ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MagicLeap_Left_Bumper)
++ActionMappings=(ActionName="Jump",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MagicLeap_Right_Trigger)
++ActionMappings=(ActionName="Fire",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MagicLeap_Right_Trackpad_Touch)
++ActionMappings=(ActionName="ResetVR",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=MagicLeap_Right_Bumper)
++ActionMappings=(ActionName="Pick Up",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=E)
++AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=Z)
++AxisMappings=(AxisName="MoveForward",Scale=-1.000000,Key=S)
++AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=Up)
++AxisMappings=(AxisName="MoveForward",Scale=-1.000000,Key=Down)
++AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=Gamepad_LeftY)
++AxisMappings=(AxisName="MoveRight",Scale=-1.000000,Key=Q)
++AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=D)
++AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=Gamepad_LeftX)
++AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=Daydream_Left_Trackpad_X)
++AxisMappings=(AxisName="TurnRate",Scale=1.000000,Key=Gamepad_RightX)
++AxisMappings=(AxisName="TurnRate",Scale=-1.000000,Key=Left)
++AxisMappings=(AxisName="TurnRate",Scale=1.000000,Key=Right)
++AxisMappings=(AxisName="Turn",Scale=1.000000,Key=MouseX)
++AxisMappings=(AxisName="LookUpRate",Scale=1.000000,Key=Gamepad_RightY)
++AxisMappings=(AxisName="LookUp",Scale=-1.000000,Key=MouseY)
++AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=Daydream_Left_Trackpad_Y)
++AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=Vive_Left_Trackpad_Y)
++AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=MixedReality_Left_Thumbstick_Y)
++AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=OculusGo_Left_Trackpad_Y)
++AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=OculusTouch_Left_Thumbstick_Y)
++AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=ValveIndex_Left_Thumbstick_Y)
++AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=Vive_Left_Trackpad_X)
++AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=MixedReality_Left_Thumbstick_X)
++AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=OculusGo_Left_Trackpad_X)
++AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=OculusTouch_Left_Thumbstick_Y)
++AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=ValveIndex_Left_Thumbstick_Y)
++AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=MagicLeap_Left_Trackpad_X)
++AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=MagicLeap_Left_Trackpad_Y)
++AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=MagicLeap_Right_Trackpad_Y)
++AxisMappings=(AxisName="MoveRight",Scale=1.000000,Key=MagicLeap_Right_Trackpad_X)
+DefaultPlayerInputClass=/Script/Engine.PlayerInput
+DefaultInputComponentClass=/Script/Engine.InputComponent
+DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks
+-ConsoleKeys=Tilde
++ConsoleKeys=Tilde
+
diff --git a/Doc/Cahier des charges.pdf b/Doc/Cahier des charges.pdf
new file mode 100644
index 0000000..1bb2e65
Binary files /dev/null and b/Doc/Cahier des charges.pdf differ
diff --git a/Doc/PANNER_PRESENTATION_GP.pdf b/Doc/PANNER_PRESENTATION_GP.pdf
new file mode 100644
index 0000000..c288924
Binary files /dev/null and b/Doc/PANNER_PRESENTATION_GP.pdf differ
diff --git a/Doc/Panner_DEMO.mp4 b/Doc/Panner_DEMO.mp4
new file mode 100644
index 0000000..3268b9c
Binary files /dev/null and b/Doc/Panner_DEMO.mp4 differ
diff --git a/Doc/Pitch.pdf b/Doc/Pitch.pdf
new file mode 100644
index 0000000..9b1eceb
Binary files /dev/null and b/Doc/Pitch.pdf differ
diff --git a/Panner.uproject b/Panner.uproject
new file mode 100644
index 0000000..621da83
--- /dev/null
+++ b/Panner.uproject
@@ -0,0 +1,13 @@
+{
+ "FileVersion": 3,
+ "EngineAssociation": "4.27",
+ "Category": "",
+ "Description": "",
+ "Modules": [
+ {
+ "Name": "Panner",
+ "Type": "Runtime",
+ "LoadingPhase": "Default"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6d0e254
--- /dev/null
+++ b/README.md
@@ -0,0 +1,42 @@
+# Fake FLESH System
+Project to recreate the FLESH system that can be found on Dead Islands 2 during a techart apprenticeship project at ISART
+
+![gif](./Screenshot/low_damage.gif)
+
+![gif](./Screenshot/big_damage.gif)
+
+## Table of content
+ - [TechArt](#techart)
+ - [Build](#build)
+ - [Technology](#technology)
+ - [Credit](#credit)
+
+## TechArt
+see the documentations in the forlder doc
+
+## Build
+### .exe
+Dowload the zip folder in the release part
+
+### Unreal project
+To prevent the repo from becoming too large, the ```Content``` folder has been zipped. To launch the project, simply unzip the folder
+
+## Technology
+ - **Engine**: Unreal Engine 4.27
+ - **Versionning**: Perforce (P4V)
+
+ ## Credit
+ ### Game Artiste
+ - AGÉNOR Roman
+ - BELTAI Mailys
+ - IFERGANE Eden
+ - LEBTAHI Nedjma
+
+### Game Programming
+ - DEVINE Vincent
+ - MAZURIE Florestan
+ - OSMANOGLU Umut
+
+
+Start project: 01/17/2024
+End project: 02/17/2024
\ No newline at end of file
diff --git a/Screenshot/big_damage.gif b/Screenshot/big_damage.gif
new file mode 100644
index 0000000..b8c6bed
Binary files /dev/null and b/Screenshot/big_damage.gif differ
diff --git a/Screenshot/low_damage.gif b/Screenshot/low_damage.gif
new file mode 100644
index 0000000..a3f6768
Binary files /dev/null and b/Screenshot/low_damage.gif differ
diff --git a/Source/Panner.Target.cs b/Source/Panner.Target.cs
new file mode 100644
index 0000000..eb5cbec
--- /dev/null
+++ b/Source/Panner.Target.cs
@@ -0,0 +1,14 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+using UnrealBuildTool;
+using System.Collections.Generic;
+
+public class PannerTarget : TargetRules
+{
+ public PannerTarget(TargetInfo Target) : base(Target)
+ {
+ Type = TargetType.Game;
+ DefaultBuildSettings = BuildSettingsVersion.V2;
+ ExtraModuleNames.Add("Panner");
+ }
+}
diff --git a/Source/Panner/Panner.Build.cs b/Source/Panner/Panner.Build.cs
new file mode 100644
index 0000000..9bc455e
--- /dev/null
+++ b/Source/Panner/Panner.Build.cs
@@ -0,0 +1,13 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+using UnrealBuildTool;
+
+public class Panner : ModuleRules
+{
+ public Panner(ReadOnlyTargetRules Target) : base(Target)
+ {
+ PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
+
+ PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay" });
+ }
+}
diff --git a/Source/Panner/Panner.cpp b/Source/Panner/Panner.cpp
new file mode 100644
index 0000000..20b077c
--- /dev/null
+++ b/Source/Panner/Panner.cpp
@@ -0,0 +1,7 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "Panner.h"
+#include "Modules/ModuleManager.h"
+
+IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Panner, "Panner" );
+
\ No newline at end of file
diff --git a/Source/Panner/Panner.h b/Source/Panner/Panner.h
new file mode 100644
index 0000000..ddbf2e2
--- /dev/null
+++ b/Source/Panner/Panner.h
@@ -0,0 +1,5 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include "CoreMinimal.h"
diff --git a/Source/Panner/PannerCharacter.cpp b/Source/Panner/PannerCharacter.cpp
new file mode 100644
index 0000000..842c64f
--- /dev/null
+++ b/Source/Panner/PannerCharacter.cpp
@@ -0,0 +1,300 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "PannerCharacter.h"
+#include "PannerProjectile.h"
+#include "Animation/AnimInstance.h"
+#include "Camera/CameraComponent.h"
+#include "Components/CapsuleComponent.h"
+#include "Components/InputComponent.h"
+#include "GameFramework/InputSettings.h"
+#include "HeadMountedDisplayFunctionLibrary.h"
+#include "Kismet/GameplayStatics.h"
+#include "MotionControllerComponent.h"
+#include "XRMotionControllerBase.h" // for FXRMotionControllerBase::RightHandSourceId
+
+DEFINE_LOG_CATEGORY_STATIC(LogFPChar, Warning, All);
+
+//////////////////////////////////////////////////////////////////////////
+// APannerCharacter
+
+APannerCharacter::APannerCharacter()
+{
+ // Set size for collision capsule
+ GetCapsuleComponent()->InitCapsuleSize(55.f, 96.0f);
+
+ // set our turn rates for input
+ BaseTurnRate = 45.f;
+ BaseLookUpRate = 45.f;
+
+ // Create a CameraComponent
+ FirstPersonCameraComponent = CreateDefaultSubobject(TEXT("FirstPersonCamera"));
+ FirstPersonCameraComponent->SetupAttachment(GetCapsuleComponent());
+ FirstPersonCameraComponent->SetRelativeLocation(FVector(-39.56f, 1.75f, 64.f)); // Position the camera
+ FirstPersonCameraComponent->bUsePawnControlRotation = true;
+
+ // Create a mesh component that will be used when being viewed from a '1st person' view (when controlling this pawn)
+ Mesh1P = CreateDefaultSubobject(TEXT("CharacterMesh1P"));
+ Mesh1P->SetOnlyOwnerSee(true);
+ Mesh1P->SetupAttachment(FirstPersonCameraComponent);
+ Mesh1P->bCastDynamicShadow = false;
+ Mesh1P->CastShadow = false;
+ Mesh1P->SetRelativeRotation(FRotator(1.9f, -19.19f, 5.2f));
+ Mesh1P->SetRelativeLocation(FVector(-0.5f, -4.4f, -155.7f));
+
+ // Create a gun mesh component
+ FP_Gun = CreateDefaultSubobject(TEXT("FP_Gun"));
+ FP_Gun->SetOnlyOwnerSee(false); // otherwise won't be visible in the multiplayer
+ FP_Gun->bCastDynamicShadow = false;
+ FP_Gun->CastShadow = false;
+ // FP_Gun->SetupAttachment(Mesh1P, TEXT("GripPoint"));
+ FP_Gun->SetupAttachment(RootComponent);
+
+ FP_MuzzleLocation = CreateDefaultSubobject(TEXT("MuzzleLocation"));
+ FP_MuzzleLocation->SetupAttachment(FP_Gun);
+ FP_MuzzleLocation->SetRelativeLocation(FVector(0.2f, 48.4f, -10.6f));
+
+ // Default offset from the character location for projectiles to spawn
+ GunOffset = FVector(100.0f, 0.0f, 10.0f);
+
+ // Note: The ProjectileClass and the skeletal mesh/anim blueprints for Mesh1P, FP_Gun, and VR_Gun
+ // are set in the derived blueprint asset named MyCharacter to avoid direct content references in C++.
+
+ // Create VR Controllers.
+ R_MotionController = CreateDefaultSubobject(TEXT("R_MotionController"));
+ R_MotionController->MotionSource = FXRMotionControllerBase::RightHandSourceId;
+ R_MotionController->SetupAttachment(RootComponent);
+ L_MotionController = CreateDefaultSubobject(TEXT("L_MotionController"));
+ L_MotionController->SetupAttachment(RootComponent);
+
+ // Create a gun and attach it to the right-hand VR controller.
+ // Create a gun mesh component
+ VR_Gun = CreateDefaultSubobject(TEXT("VR_Gun"));
+ VR_Gun->SetOnlyOwnerSee(false); // otherwise won't be visible in the multiplayer
+ VR_Gun->bCastDynamicShadow = false;
+ VR_Gun->CastShadow = false;
+ VR_Gun->SetupAttachment(R_MotionController);
+ VR_Gun->SetRelativeRotation(FRotator(0.0f, -90.0f, 0.0f));
+
+ VR_MuzzleLocation = CreateDefaultSubobject(TEXT("VR_MuzzleLocation"));
+ VR_MuzzleLocation->SetupAttachment(VR_Gun);
+ VR_MuzzleLocation->SetRelativeLocation(FVector(0.000004, 53.999992, 10.000000));
+ VR_MuzzleLocation->SetRelativeRotation(FRotator(0.0f, 90.0f, 0.0f)); // Counteract the rotation of the VR gun model.
+
+ // Uncomment the following line to turn motion controllers on by default:
+ //bUsingMotionControllers = true;
+}
+
+void APannerCharacter::BeginPlay()
+{
+ // Call the base class
+ Super::BeginPlay();
+
+ //Attach gun mesh component to Skeleton, doing it here because the skeleton is not yet created in the constructor
+ FP_Gun->AttachToComponent(Mesh1P, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true), TEXT("GripPoint"));
+
+ // Show or hide the two versions of the gun based on whether or not we're using motion controllers.
+ if (bUsingMotionControllers)
+ {
+ VR_Gun->SetHiddenInGame(false, true);
+ Mesh1P->SetHiddenInGame(true, true);
+ }
+ else
+ {
+ VR_Gun->SetHiddenInGame(true, true);
+ Mesh1P->SetHiddenInGame(false, true);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Input
+
+void APannerCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
+{
+ // set up gameplay key bindings
+ check(PlayerInputComponent);
+
+ // Bind jump events
+ PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
+ PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
+
+ // Bind fire event
+ PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &APannerCharacter::OnFire);
+
+ // Enable touchscreen input
+ EnableTouchscreenMovement(PlayerInputComponent);
+
+ PlayerInputComponent->BindAction("ResetVR", IE_Pressed, this, &APannerCharacter::OnResetVR);
+
+ // Bind movement events
+ PlayerInputComponent->BindAxis("MoveForward", this, &APannerCharacter::MoveForward);
+ PlayerInputComponent->BindAxis("MoveRight", this, &APannerCharacter::MoveRight);
+
+ // We have 2 versions of the rotation bindings to handle different kinds of devices differently
+ // "turn" handles devices that provide an absolute delta, such as a mouse.
+ // "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystick
+ PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
+ PlayerInputComponent->BindAxis("TurnRate", this, &APannerCharacter::TurnAtRate);
+ PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
+ PlayerInputComponent->BindAxis("LookUpRate", this, &APannerCharacter::LookUpAtRate);
+}
+
+void APannerCharacter::OnFire()
+{
+ // try and fire a projectile
+ if (ProjectileClass != nullptr)
+ {
+ UWorld* const World = GetWorld();
+ if (World != nullptr)
+ {
+ if (bUsingMotionControllers)
+ {
+ const FRotator SpawnRotation = VR_MuzzleLocation->GetComponentRotation();
+ const FVector SpawnLocation = VR_MuzzleLocation->GetComponentLocation();
+ World->SpawnActor(ProjectileClass, SpawnLocation, SpawnRotation);
+ }
+ else
+ {
+ const FRotator SpawnRotation = GetControlRotation();
+ // MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
+ const FVector SpawnLocation = ((FP_MuzzleLocation != nullptr) ? FP_MuzzleLocation->GetComponentLocation() : GetActorLocation()) + SpawnRotation.RotateVector(GunOffset);
+
+ //Set Spawn Collision Handling Override
+ FActorSpawnParameters ActorSpawnParams;
+ ActorSpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButDontSpawnIfColliding;
+
+ // spawn the projectile at the muzzle
+ World->SpawnActor(ProjectileClass, SpawnLocation, SpawnRotation, ActorSpawnParams);
+ }
+ }
+ }
+
+ // try and play the sound if specified
+ if (FireSound != nullptr)
+ {
+ UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
+ }
+
+ // try and play a firing animation if specified
+ if (FireAnimation != nullptr)
+ {
+ // Get the animation object for the arms mesh
+ UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
+ if (AnimInstance != nullptr)
+ {
+ AnimInstance->Montage_Play(FireAnimation, 1.f);
+ }
+ }
+}
+
+void APannerCharacter::OnResetVR()
+{
+ UHeadMountedDisplayFunctionLibrary::ResetOrientationAndPosition();
+}
+
+void APannerCharacter::BeginTouch(const ETouchIndex::Type FingerIndex, const FVector Location)
+{
+ if (TouchItem.bIsPressed == true)
+ {
+ return;
+ }
+ if ((FingerIndex == TouchItem.FingerIndex) && (TouchItem.bMoved == false))
+ {
+ OnFire();
+ }
+ TouchItem.bIsPressed = true;
+ TouchItem.FingerIndex = FingerIndex;
+ TouchItem.Location = Location;
+ TouchItem.bMoved = false;
+}
+
+void APannerCharacter::EndTouch(const ETouchIndex::Type FingerIndex, const FVector Location)
+{
+ if (TouchItem.bIsPressed == false)
+ {
+ return;
+ }
+ TouchItem.bIsPressed = false;
+}
+
+//Commenting this section out to be consistent with FPS BP template.
+//This allows the user to turn without using the right virtual joystick
+
+//void APannerCharacter::TouchUpdate(const ETouchIndex::Type FingerIndex, const FVector Location)
+//{
+// if ((TouchItem.bIsPressed == true) && (TouchItem.FingerIndex == FingerIndex))
+// {
+// if (TouchItem.bIsPressed)
+// {
+// if (GetWorld() != nullptr)
+// {
+// UGameViewportClient* ViewportClient = GetWorld()->GetGameViewport();
+// if (ViewportClient != nullptr)
+// {
+// FVector MoveDelta = Location - TouchItem.Location;
+// FVector2D ScreenSize;
+// ViewportClient->GetViewportSize(ScreenSize);
+// FVector2D ScaledDelta = FVector2D(MoveDelta.X, MoveDelta.Y) / ScreenSize;
+// if (FMath::Abs(ScaledDelta.X) >= 4.0 / ScreenSize.X)
+// {
+// TouchItem.bMoved = true;
+// float Value = ScaledDelta.X * BaseTurnRate;
+// AddControllerYawInput(Value);
+// }
+// if (FMath::Abs(ScaledDelta.Y) >= 4.0 / ScreenSize.Y)
+// {
+// TouchItem.bMoved = true;
+// float Value = ScaledDelta.Y * BaseTurnRate;
+// AddControllerPitchInput(Value);
+// }
+// TouchItem.Location = Location;
+// }
+// TouchItem.Location = Location;
+// }
+// }
+// }
+//}
+
+void APannerCharacter::MoveForward(float Value)
+{
+ if (Value != 0.0f)
+ {
+ // add movement in that direction
+ AddMovementInput(GetActorForwardVector(), Value);
+ }
+}
+
+void APannerCharacter::MoveRight(float Value)
+{
+ if (Value != 0.0f)
+ {
+ // add movement in that direction
+ AddMovementInput(GetActorRightVector(), Value);
+ }
+}
+
+void APannerCharacter::TurnAtRate(float Rate)
+{
+ // calculate delta for this frame from the rate information
+ AddControllerYawInput(Rate * BaseTurnRate * GetWorld()->GetDeltaSeconds());
+}
+
+void APannerCharacter::LookUpAtRate(float Rate)
+{
+ // calculate delta for this frame from the rate information
+ AddControllerPitchInput(Rate * BaseLookUpRate * GetWorld()->GetDeltaSeconds());
+}
+
+bool APannerCharacter::EnableTouchscreenMovement(class UInputComponent* PlayerInputComponent)
+{
+ if (FPlatformMisc::SupportsTouchInput() || GetDefault()->bUseMouseForTouch)
+ {
+ PlayerInputComponent->BindTouch(EInputEvent::IE_Pressed, this, &APannerCharacter::BeginTouch);
+ PlayerInputComponent->BindTouch(EInputEvent::IE_Released, this, &APannerCharacter::EndTouch);
+
+ //Commenting this out to be more consistent with FPS BP template.
+ //PlayerInputComponent->BindTouch(EInputEvent::IE_Repeat, this, &APannerCharacter::TouchUpdate);
+ return true;
+ }
+
+ return false;
+}
diff --git a/Source/Panner/PannerCharacter.h b/Source/Panner/PannerCharacter.h
new file mode 100644
index 0000000..d1f9c74
--- /dev/null
+++ b/Source/Panner/PannerCharacter.h
@@ -0,0 +1,148 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "GameFramework/Character.h"
+#include "PannerCharacter.generated.h"
+
+class UInputComponent;
+class USkeletalMeshComponent;
+class USceneComponent;
+class UCameraComponent;
+class UMotionControllerComponent;
+class UAnimMontage;
+class USoundBase;
+
+UCLASS(config=Game)
+class APannerCharacter : public ACharacter
+{
+ GENERATED_BODY()
+
+ /** Pawn mesh: 1st person view (arms; seen only by self) */
+ UPROPERTY(VisibleDefaultsOnly, Category=Mesh)
+ USkeletalMeshComponent* Mesh1P;
+
+ /** Gun mesh: 1st person view (seen only by self) */
+ UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
+ USkeletalMeshComponent* FP_Gun;
+
+ /** Location on gun mesh where projectiles should spawn. */
+ UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
+ USceneComponent* FP_MuzzleLocation;
+
+ /** Gun mesh: VR view (attached to the VR controller directly, no arm, just the actual gun) */
+ UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
+ USkeletalMeshComponent* VR_Gun;
+
+ /** Location on VR gun mesh where projectiles should spawn. */
+ UPROPERTY(VisibleDefaultsOnly, Category = Mesh)
+ USceneComponent* VR_MuzzleLocation;
+
+ /** First person camera */
+ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
+ UCameraComponent* FirstPersonCameraComponent;
+
+ /** Motion controller (right hand) */
+ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
+ UMotionControllerComponent* R_MotionController;
+
+ /** Motion controller (left hand) */
+ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
+ UMotionControllerComponent* L_MotionController;
+
+public:
+ APannerCharacter();
+
+protected:
+ virtual void BeginPlay();
+
+public:
+ /** Base turn rate, in deg/sec. Other scaling may affect final turn rate. */
+ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
+ float BaseTurnRate;
+
+ /** Base look up/down rate, in deg/sec. Other scaling may affect final rate. */
+ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
+ float BaseLookUpRate;
+
+ /** Gun muzzle's offset from the characters location */
+ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Gameplay)
+ FVector GunOffset;
+
+ /** Projectile class to spawn */
+ UPROPERTY(EditDefaultsOnly, Category=Projectile)
+ TSubclassOf ProjectileClass;
+
+ /** Sound to play each time we fire */
+ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Gameplay)
+ USoundBase* FireSound;
+
+ /** AnimMontage to play each time we fire */
+ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay)
+ UAnimMontage* FireAnimation;
+
+ /** Whether to use motion controller location for aiming. */
+ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay)
+ uint8 bUsingMotionControllers : 1;
+
+protected:
+
+ /** Fires a projectile. */
+ void OnFire();
+
+ /** Resets HMD orientation and position in VR. */
+ void OnResetVR();
+
+ /** Handles moving forward/backward */
+ void MoveForward(float Val);
+
+ /** Handles stafing movement, left and right */
+ void MoveRight(float Val);
+
+ /**
+ * Called via input to turn at a given rate.
+ * @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
+ */
+ void TurnAtRate(float Rate);
+
+ /**
+ * Called via input to turn look up/down at a given rate.
+ * @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
+ */
+ void LookUpAtRate(float Rate);
+
+ struct TouchData
+ {
+ TouchData() { bIsPressed = false;Location=FVector::ZeroVector;}
+ bool bIsPressed;
+ ETouchIndex::Type FingerIndex;
+ FVector Location;
+ bool bMoved;
+ };
+ void BeginTouch(const ETouchIndex::Type FingerIndex, const FVector Location);
+ void EndTouch(const ETouchIndex::Type FingerIndex, const FVector Location);
+ void TouchUpdate(const ETouchIndex::Type FingerIndex, const FVector Location);
+ TouchData TouchItem;
+
+protected:
+ // APawn interface
+ virtual void SetupPlayerInputComponent(UInputComponent* InputComponent) override;
+ // End of APawn interface
+
+ /*
+ * Configures input for touchscreen devices if there is a valid touch interface for doing so
+ *
+ * @param InputComponent The input component pointer to bind controls to
+ * @returns true if touch controls were enabled.
+ */
+ bool EnableTouchscreenMovement(UInputComponent* InputComponent);
+
+public:
+ /** Returns Mesh1P subobject **/
+ USkeletalMeshComponent* GetMesh1P() const { return Mesh1P; }
+ /** Returns FirstPersonCameraComponent subobject **/
+ UCameraComponent* GetFirstPersonCameraComponent() const { return FirstPersonCameraComponent; }
+
+};
+
diff --git a/Source/Panner/PannerGameMode.cpp b/Source/Panner/PannerGameMode.cpp
new file mode 100644
index 0000000..b382db7
--- /dev/null
+++ b/Source/Panner/PannerGameMode.cpp
@@ -0,0 +1,17 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "PannerGameMode.h"
+#include "PannerHUD.h"
+#include "PannerCharacter.h"
+#include "UObject/ConstructorHelpers.h"
+
+APannerGameMode::APannerGameMode()
+ : Super()
+{
+ // set default pawn class to our Blueprinted character
+ static ConstructorHelpers::FClassFinder PlayerPawnClassFinder(TEXT("/Game/FirstPersonCPP/Blueprints/FirstPersonCharacter"));
+ DefaultPawnClass = PlayerPawnClassFinder.Class;
+
+ // use our custom HUD class
+ HUDClass = APannerHUD::StaticClass();
+}
diff --git a/Source/Panner/PannerGameMode.h b/Source/Panner/PannerGameMode.h
new file mode 100644
index 0000000..723c689
--- /dev/null
+++ b/Source/Panner/PannerGameMode.h
@@ -0,0 +1,19 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "GameFramework/GameModeBase.h"
+#include "PannerGameMode.generated.h"
+
+UCLASS(minimalapi)
+class APannerGameMode : public AGameModeBase
+{
+ GENERATED_BODY()
+
+public:
+ APannerGameMode();
+};
+
+
+
diff --git a/Source/Panner/PannerHUD.cpp b/Source/Panner/PannerHUD.cpp
new file mode 100644
index 0000000..9b82902
--- /dev/null
+++ b/Source/Panner/PannerHUD.cpp
@@ -0,0 +1,35 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "PannerHUD.h"
+#include "Engine/Canvas.h"
+#include "Engine/Texture2D.h"
+#include "TextureResource.h"
+#include "CanvasItem.h"
+#include "UObject/ConstructorHelpers.h"
+
+APannerHUD::APannerHUD()
+{
+ // Set the crosshair texture
+ static ConstructorHelpers::FObjectFinder CrosshairTexObj(TEXT("/Game/FirstPerson/Textures/FirstPersonCrosshair"));
+ CrosshairTex = CrosshairTexObj.Object;
+}
+
+
+void APannerHUD::DrawHUD()
+{
+ Super::DrawHUD();
+
+ // Draw very simple crosshair
+
+ // find center of the Canvas
+ const FVector2D Center(Canvas->ClipX * 0.5f, Canvas->ClipY * 0.5f);
+
+ // offset by half the texture's dimensions so that the center of the texture aligns with the center of the Canvas
+ const FVector2D CrosshairDrawPosition( (Center.X),
+ (Center.Y + 20.0f));
+
+ // draw the crosshair
+ FCanvasTileItem TileItem( CrosshairDrawPosition, CrosshairTex->Resource, FLinearColor::White);
+ TileItem.BlendMode = SE_BLEND_Translucent;
+ Canvas->DrawItem( TileItem );
+}
diff --git a/Source/Panner/PannerHUD.h b/Source/Panner/PannerHUD.h
new file mode 100644
index 0000000..fdf33e8
--- /dev/null
+++ b/Source/Panner/PannerHUD.h
@@ -0,0 +1,25 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "GameFramework/HUD.h"
+#include "PannerHUD.generated.h"
+
+UCLASS()
+class APannerHUD : public AHUD
+{
+ GENERATED_BODY()
+
+public:
+ APannerHUD();
+
+ /** Primary draw call for the HUD */
+ virtual void DrawHUD() override;
+
+private:
+ /** Crosshair asset pointer */
+ class UTexture2D* CrosshairTex;
+
+};
+
diff --git a/Source/Panner/PannerProjectile.cpp b/Source/Panner/PannerProjectile.cpp
new file mode 100644
index 0000000..be18f56
--- /dev/null
+++ b/Source/Panner/PannerProjectile.cpp
@@ -0,0 +1,43 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "PannerProjectile.h"
+#include "GameFramework/ProjectileMovementComponent.h"
+#include "Components/SphereComponent.h"
+
+APannerProjectile::APannerProjectile()
+{
+ // Use a sphere as a simple collision representation
+ CollisionComp = CreateDefaultSubobject(TEXT("SphereComp"));
+ CollisionComp->InitSphereRadius(5.0f);
+ CollisionComp->BodyInstance.SetCollisionProfileName("Projectile");
+ CollisionComp->OnComponentHit.AddDynamic(this, &APannerProjectile::OnHit); // set up a notification for when this component hits something blocking
+
+ // Players can't walk on it
+ CollisionComp->SetWalkableSlopeOverride(FWalkableSlopeOverride(WalkableSlope_Unwalkable, 0.f));
+ CollisionComp->CanCharacterStepUpOn = ECB_No;
+
+ // Set as root component
+ RootComponent = CollisionComp;
+
+ // Use a ProjectileMovementComponent to govern this projectile's movement
+ ProjectileMovement = CreateDefaultSubobject(TEXT("ProjectileComp"));
+ ProjectileMovement->UpdatedComponent = CollisionComp;
+ ProjectileMovement->InitialSpeed = 3000.f;
+ ProjectileMovement->MaxSpeed = 3000.f;
+ ProjectileMovement->bRotationFollowsVelocity = true;
+ ProjectileMovement->bShouldBounce = true;
+
+ // Die after 3 seconds by default
+ InitialLifeSpan = 3.0f;
+}
+
+void APannerProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
+{
+ // Only add impulse and destroy projectile if we hit a physics
+ if ((OtherActor != nullptr) && (OtherActor != this) && (OtherComp != nullptr) && OtherComp->IsSimulatingPhysics())
+ {
+ OtherComp->AddImpulseAtLocation(GetVelocity() * 100.0f, GetActorLocation());
+
+ Destroy();
+ }
+}
\ No newline at end of file
diff --git a/Source/Panner/PannerProjectile.h b/Source/Panner/PannerProjectile.h
new file mode 100644
index 0000000..e2bbe7d
--- /dev/null
+++ b/Source/Panner/PannerProjectile.h
@@ -0,0 +1,37 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include "CoreMinimal.h"
+#include "GameFramework/Actor.h"
+#include "PannerProjectile.generated.h"
+
+class USphereComponent;
+class UProjectileMovementComponent;
+
+UCLASS(config=Game)
+class APannerProjectile : public AActor
+{
+ GENERATED_BODY()
+
+ /** Sphere collision component */
+ UPROPERTY(VisibleDefaultsOnly, Category=Projectile)
+ USphereComponent* CollisionComp;
+
+ /** Projectile movement component */
+ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Movement, meta = (AllowPrivateAccess = "true"))
+ UProjectileMovementComponent* ProjectileMovement;
+
+public:
+ APannerProjectile();
+
+ /** called when projectile hits something */
+ UFUNCTION()
+ void OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
+
+ /** Returns CollisionComp subobject **/
+ USphereComponent* GetCollisionComp() const { return CollisionComp; }
+ /** Returns ProjectileMovement subobject **/
+ UProjectileMovementComponent* GetProjectileMovement() const { return ProjectileMovement; }
+};
+
diff --git a/Source/PannerEditor.Target.cs b/Source/PannerEditor.Target.cs
new file mode 100644
index 0000000..ae35db2
--- /dev/null
+++ b/Source/PannerEditor.Target.cs
@@ -0,0 +1,14 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+using UnrealBuildTool;
+using System.Collections.Generic;
+
+public class PannerEditorTarget : TargetRules
+{
+ public PannerEditorTarget(TargetInfo Target) : base(Target)
+ {
+ Type = TargetType.Editor;
+ DefaultBuildSettings = BuildSettingsVersion.V2;
+ ExtraModuleNames.Add("Panner");
+ }
+}
diff --git a/p4ignore b/p4ignore
new file mode 100644
index 0000000..e6d0b7c
--- /dev/null
+++ b/p4ignore
@@ -0,0 +1,573 @@
+# Created by https://www.toptal.com/developers/gitignore/api/rider,visualstudio,unrealengine
+# Edit at https://www.toptal.com/developers/gitignore?templates=rider,visualstudio,unrealengine
+
+### Rider ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# AWS User-specific
+.idea/**/aws.xml
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# SonarLint plugin
+.idea/sonarlint/
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### UnrealEngine ###
+# Visual Studio 2015 user specific files
+.vs/
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+*.ipa
+
+# These project files can be generated by the engine
+*.xcodeproj
+*.xcworkspace
+*.sln
+*.suo
+*.opensdf
+*.sdf
+*.VC.db
+*.VC.opendb
+
+# Precompiled Assets
+SourceArt/**/*.png
+SourceArt/**/*.tga
+
+# Binary Files
+Binaries/*
+Plugins/*/Binaries/*
+
+# Builds
+Build/*
+
+# Whitelist PakBlacklist-.txt files
+!Build/*/
+Build/*/**
+!Build/*/PakBlacklist*.txt
+
+# Don't ignore icon files in Build
+!Build/**/*.ico
+
+# Built data for maps
+*_BuiltData.uasset
+
+# Configuration files generated by the Editor
+Saved/*
+
+# Compiled source files for the engine to use
+Intermediate/*
+Plugins/*/Intermediate/*
+
+# Cache files for the editor to use
+DerivedDataCache/*
+
+### UnrealEngine Patch ###
+# Don't ignore icon and splash images for mobile app
+!Build/IOS/Resources/
+Build/IOS/Resources/*
+!Build/IOS/Resources/Graphics/
+Build/IOS/Resources/Graphics/*
+!Build/IOS/Resources/Graphics/*.png
+!Build/Android/res/
+Build/Android/res/*
+!Build/Android/res/*/
+Build/Android/res/*/*
+!Build/Android/res/*/*.png
+# Ignore plugins binaries on deep subfolders
+Plugins/**/Binaries/*
+Plugins/**/Intermediate/*
+
+### VisualStudio ###
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
+
+# User-specific files
+*.rsuser
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Mono auto generated files
+mono_crash.*
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+[Ww][Ii][Nn]32/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+[Ll]ogs/
+
+# Visual Studio 2015/2017 cache/options directory
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUnit
+*.VisualState.xml
+TestResult.xml
+nunit-*.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# ASP.NET Scaffolding
+ScaffoldingReadMe.txt
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_h.h
+*.ilk
+*.meta
+*.iobj
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*_wpftmp.csproj
+*.log
+*.tlog
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.cachefile
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*.json
+coverage*.xml
+coverage*.info
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# NuGet Symbol Packages
+*.snupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+*.appxbundle
+*.appxupload
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+*- [Bb]ackup.rdl
+*- [Bb]ackup ([0-9]).rdl
+*- [Bb]ackup ([0-9][0-9]).rdl
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio 6 auto-generated project file (contains which files were open etc.)
+*.vbp
+
+# Visual Studio 6 workspace and project file (working project files containing files to include in project)
+*.dsw
+*.dsp
+
+# Visual Studio 6 technical files
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# CodeRush personal settings
+.cr/personal
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+
+# Local History for Visual Studio
+.localhistory/
+
+# Visual Studio History (VSHistory) files
+.vshistory/
+
+# BeatPulse healthcheck temp database
+healthchecksdb
+
+# Backup folder for Package Reference Convert tool in Visual Studio 2017
+MigrationBackup/
+
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# Fody - auto-generated XML schema
+FodyWeavers.xsd
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+# Local History for Visual Studio Code
+.history/
+
+# Windows Installer files from build outputs
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# JetBrains Rider
+*.sln.iml
+
+# Perforce config
+*.p4config
+*.p4settings
+
+### VisualStudio Patch ###
+# Additional files built by Visual Studio
+
+# End of https://www.toptal.com/developers/gitignore/api/rider,visualstudio,unrealengine
\ No newline at end of file