diff --git a/.gitignore b/.gitignore index d114181..8fa8a52 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,6 @@ Project/.vsconfig *.target *.modules Project/.idea + +Project/Saved/Screenshots +*/Binaries/Win64/*.patch_*.* diff --git a/Project/Binaries/Win64/UnrealEditor-Gasa.dll b/Project/Binaries/Win64/UnrealEditor-Gasa.dll index 3efd3cd..d6e19fb 100644 Binary files a/Project/Binaries/Win64/UnrealEditor-Gasa.dll and b/Project/Binaries/Win64/UnrealEditor-Gasa.dll differ diff --git a/Project/Binaries/Win64/UnrealEditor-Gasa.pdb b/Project/Binaries/Win64/UnrealEditor-Gasa.pdb index ce64c5a..71d7084 100644 Binary files a/Project/Binaries/Win64/UnrealEditor-Gasa.pdb and b/Project/Binaries/Win64/UnrealEditor-Gasa.pdb differ diff --git a/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll b/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll index 66c2159..2654f7d 100644 Binary files a/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll and b/Project/Binaries/Win64/UnrealEditor-GasaEditor.dll differ diff --git a/Project/Binaries/Win64/UnrealEditor-GasaEditor.pdb b/Project/Binaries/Win64/UnrealEditor-GasaEditor.pdb index d463302..639b3e3 100644 Binary files a/Project/Binaries/Win64/UnrealEditor-GasaEditor.pdb and b/Project/Binaries/Win64/UnrealEditor-GasaEditor.pdb differ diff --git a/Project/Config/DefaultEngine.ini b/Project/Config/DefaultEngine.ini index 9a69e01..0feed8b 100644 --- a/Project/Config/DefaultEngine.ini +++ b/Project/Config/DefaultEngine.ini @@ -3,6 +3,7 @@ [/Script/EngineSettings.GameMapsSettings] GameDefaultMap=/Game/Levels/StartupMap.StartupMap EditorStartupMap=/Game/Levels/StartupMap.StartupMap +GlobalDefaultGameMode=/Game/Core/Game/BP_GameMode.BP_GameMode_C [/Script/WindowsTargetPlatform.WindowsTargetSettings] DefaultGraphicsRHI=DefaultGraphicsRHI_DX12 diff --git a/Project/Source/Gasa/Character/GasaCharacter.cpp b/Project/Source/Gasa/Character/GasaCharacter.cpp index 81ecec4..9990966 100644 --- a/Project/Source/Gasa/Character/GasaCharacter.cpp +++ b/Project/Source/Gasa/Character/GasaCharacter.cpp @@ -1,11 +1,41 @@ #include "GasaCharacter.h" +#include "Camera/CameraComponent.h" +#include "GameFramework/CharacterMovementComponent.h" +#include "GameFramework/SpringArmComponent.h" + AGasaCharacter::AGasaCharacter() { PrimaryActorTick.bCanEverTick = false; + UCharacterMovementComponent* + Movement = GetCharacterMovement(); + Movement->bOrientRotationToMovement = true; + Movement->bConstrainToPlane = true; + Movement->bSnapToPlaneAtStart = true; + Movement->RotationRate = FRotator(0.0, 400.f, 0.0); + + bUseControllerRotationPitch = false; + bUseControllerRotationRoll = false; + bUseControllerRotationYaw = false; + + USceneComponent* root_component = GetRootComponent(); + USkeletalMeshComponent* mesh = GetMesh(); + + CamSpringArm = CreateDefaultSubobject("Camera Spring Arm"); + CamSpringArm->SetupAttachment(root_component); + CamSpringArm->SetRelativeRotation( FQuat::MakeFromEuler(FVector(0.0, -35.0, 0.0))); + CamSpringArm->TargetArmLength = 400.0f; + + CamSpringArm->bInheritPitch = false; + CamSpringArm->bInheritYaw = false; + CamSpringArm->bInheritRoll = false; + + Camera = CreateDefaultSubobject("Camera"); + Camera->SetupAttachment(CamSpringArm); + Weapon = CreateDefaultSubobject("Weapon"); - Weapon->SetupAttachment(GetMesh(), FName("WeaponAttach")); + Weapon->SetupAttachment(mesh, FName("WeaponAttach")); Weapon->SetCollisionEnabled(ECollisionEnabled::NoCollision); } diff --git a/Project/Source/Gasa/Character/GasaCharacter.h b/Project/Source/Gasa/Character/GasaCharacter.h index a310dd9..1d76696 100644 --- a/Project/Source/Gasa/Character/GasaCharacter.h +++ b/Project/Source/Gasa/Character/GasaCharacter.h @@ -1,5 +1,6 @@ #pragma once +#include "GasaCommon.h" #include "GameFramework/Character.h" #include "GasaCharacter.generated.h" @@ -9,6 +10,14 @@ class GASA_API AGasaCharacter : public ACharacter { GENERATED_BODY() public: +#pragma region Camera + UPROPERTY(EditAnywhere, Category="Camera") + UCameraComponent* Camera; + + UPROPERTY(EditAnywhere, Category="Camera") + USpringArmComponent* CamSpringArm; +#pragma endregion Camera + #pragma region Combat UPROPERTY(EditAnywhere, Category="Combat") TObjectPtr Weapon; diff --git a/Project/Source/Gasa/Gasa.Build.cs b/Project/Source/Gasa/Gasa.Build.cs index c277120..8745e41 100644 --- a/Project/Source/Gasa/Gasa.Build.cs +++ b/Project/Source/Gasa/Gasa.Build.cs @@ -55,6 +55,6 @@ public class Gasa : ModuleRules } #endregion Plugins - PublicIncludePathModuleNames.Add("Gasa"); + PublicIncludePaths.Add("Gasa"); } } diff --git a/Project/Source/Gasa/GasaCommon.h b/Project/Source/Gasa/GasaCommon.h index b27a535..53c28d4 100644 --- a/Project/Source/Gasa/GasaCommon.h +++ b/Project/Source/Gasa/GasaCommon.h @@ -2,6 +2,8 @@ #include "CoreMinimal.h" // #define private protected +class UCameraComponent; class UInputAction; struct FInputActionValue; class UInputMappingContext; +class USpringArmComponent; diff --git a/Project/Source/Gasa/GasaGameMode.cpp b/Project/Source/Gasa/GasaGameMode.cpp new file mode 100644 index 0000000..67304d3 --- /dev/null +++ b/Project/Source/Gasa/GasaGameMode.cpp @@ -0,0 +1,2 @@ +#include "GasaGameMode.h" + diff --git a/Project/Source/Gasa/GasaGameMode.h b/Project/Source/Gasa/GasaGameMode.h new file mode 100644 index 0000000..7fa00d4 --- /dev/null +++ b/Project/Source/Gasa/GasaGameMode.h @@ -0,0 +1,11 @@ +#pragma once +#include "GameFramework/GameMode.h" + +#include "GasaGameMode.generated.h" + +UCLASS(Blueprintable) +class GASA_API AGasaGameMode : public AGameMode +{ + GENERATED_BODY() +public: +}; diff --git a/Project/Source/Gasa/GasaPlayerController.cpp b/Project/Source/Gasa/GasaPlayerController.cpp index 18b8428..ed99d83 100644 --- a/Project/Source/Gasa/GasaPlayerController.cpp +++ b/Project/Source/Gasa/GasaPlayerController.cpp @@ -11,6 +11,11 @@ AGasaPlayerController::AGasaPlayerController() void AGasaPlayerController::Move(FInputActionValue const& ActionValue) { + APawn* pawn = GetPawn(); + if (pawn == nullptr ) + return; + +// Note(Ed): I did the follow optimization for practice, they are completely unnecessary for this context. #if 0 FVector2D AxisV = ActionValue.Get(); FRotator ControlRot = GetControlRotation(); @@ -19,31 +24,31 @@ void AGasaPlayerController::Move(FInputActionValue const& ActionValue) FVector FwdDir = FRotationMatrix(YawRot).GetUnitAxis(EAxis::X); FVector RightDir = FRotationMatrix(YawRot).GetUnitAxis(EAxis::Y); - APawn* Pawn = GetPawn(); - if (Pawn) - { - Pawn->AddMovementInput(FwdDir, AxisV.Y); - Pawn->AddMovementInput(RightDir, AxisV.X); - } + PPawn->AddMovementInput(FwdDir, AxisV.Y); + PPawn->AddMovementInput(RightDir, AxisV.X); #else FVector2f AxisV = FVector2f(ActionValue.Get()); - FQuat // FQuat isomorphic to FRotor (Hypothetical Def) - ControlRotor = GetControlRotation().Quaternion(); + + FQuat4f // FQuat isomorphic to FRotor (Hypothetical Def) + ControlRotor = FQuat4f(GetControlRotation().Quaternion()); // ControlRotor.Normalize(); // The Quaternion should always be a versor with UE... - FQuat4f - YawRotor = FQuat4f(FVector3f::UpVector, ControlRotor.GetAngle()); + FVector3f HorizontalForward = ControlRotor.RotateVector(FVector3f::ForwardVector); + // HorizontalForward.Normalize(); + + // TODO(Ed): Profile which is faster just to know... (atan2 vs FindBetweenVectors) + // HorizontalForward.Z = 0; + // FQuat4f + // YawRotor = FQuat4f::FindBetweenVectors(FVector3f::ForwardVector, HorizontalForward); // YawRotor.Normalize(); // The Quaternion should always be a versor with UE... - FVector3f FwdDir = YawRotor.RotateVector(FVector3f::ForwardVector); - FVector3f RightDir = YawRotor.RotateVector(FVector3f::RightVector); + // Need only one axis of rotation so this might be a possible optimization + float YawAngle = FMath::Atan2(HorizontalForward.Y, HorizontalForward.X); + FQuat4f YawRotor = FQuat4f(FVector3f::UpVector, YawAngle); - APawn* PPawn = GetPawn(); - if (PPawn) - { - PPawn->AddMovementInput(FVector(FwdDir), AxisV.Y); - PPawn->AddMovementInput(FVector(RightDir), AxisV.X); - } + // Rotate the combined input by the yaw rotor to get the movement direction + FVector MoveDir = (FVector) YawRotor.RotateVector( FVector3f(AxisV.Y, AxisV.X, 0.f)); + pawn->AddMovementInput( MoveDir ); #endif }