diff --git a/GravityStomp/Config/DefaultEngine.ini b/GravityStomp/Config/DefaultEngine.ini index 5d490b1..b2f98f2 100644 --- a/GravityStomp/Config/DefaultEngine.ini +++ b/GravityStomp/Config/DefaultEngine.ini @@ -54,6 +54,7 @@ AppliedDefaultGraphicsPerformance=Maximum +ActiveGameNameRedirects=(OldGameName="/Script/TP_ThirdPerson",NewGameName="/Script/GravityStomp") +ActiveClassRedirects=(OldClassName="TP_ThirdPersonGameMode",NewClassName="GravityStompGameMode") +ActiveClassRedirects=(OldClassName="TP_ThirdPersonCharacter",NewClassName="GravityStompCharacter") +WorldSettingsClassName=/Script/GravityStompGame.GSWorldSettings [/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings] bEnablePlugin=True diff --git a/GravityStomp/Content/Core/BP_GSCameraActor.uasset b/GravityStomp/Content/Core/BP_GSCameraActor.uasset index 8d3e2dc..0594405 100644 --- a/GravityStomp/Content/Core/BP_GSCameraActor.uasset +++ b/GravityStomp/Content/Core/BP_GSCameraActor.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ee09d0478d0c774f799b97144a577b94d50856b51c9259e4aeb477530ddbba85 -size 550026 +oid sha256:acb51c7c588eca9b2402bc03e99e4f5a572ee95c2b9cf9e8073720d24e1cc916 +size 769671 diff --git a/GravityStomp/Content/Debug/Camera/BP_CameraDebugGameMode.uasset b/GravityStomp/Content/Debug/Camera/BP_CameraDebugGameMode.uasset new file mode 100644 index 0000000..a1aab19 --- /dev/null +++ b/GravityStomp/Content/Debug/Camera/BP_CameraDebugGameMode.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b1f69f0fae5197a056ad9e8cc5895a3f65993b3b2374660aff86b470605cf00 +size 19313 diff --git a/GravityStomp/Content/Debug/Camera/BP_GSDebugCameraActor.uasset b/GravityStomp/Content/Debug/Camera/BP_GSDebugCameraActor.uasset new file mode 100644 index 0000000..34f19b2 --- /dev/null +++ b/GravityStomp/Content/Debug/Camera/BP_GSDebugCameraActor.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dbe8c10b3ca8c82a69f852a206c5adbe3e7ce84b4ce7403a9a58ea3459a9ec83 +size 201475 diff --git a/GravityStomp/Content/Debug/Camera/TestCamera.umap b/GravityStomp/Content/Debug/Camera/TestCamera.umap new file mode 100644 index 0000000..173f853 --- /dev/null +++ b/GravityStomp/Content/Debug/Camera/TestCamera.umap @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58012414f80549405aff7e9e70751c98fef38532e6b1275f3e412db28726d3b5 +size 43400 diff --git a/GravityStomp/Content/Maps/Debug/Test.umap b/GravityStomp/Content/Maps/Debug/Test.umap index 7c5e707..a7f7ffd 100644 --- a/GravityStomp/Content/Maps/Debug/Test.umap +++ b/GravityStomp/Content/Maps/Debug/Test.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8e16bddb7c0c882d49fb0395470566b907b03a486f06a6009960e5fa6b13fdb1 +oid sha256:18e0a97b5772a4053933e58c1c1d3548182f97d77ca26886970de7153c7dd803 size 52403 diff --git a/GravityStomp/Source/GravityStompGame/Camera/GSCameraActor.cpp b/GravityStomp/Source/GravityStompGame/Camera/GSCameraActor.cpp new file mode 100644 index 0000000..ff600b4 --- /dev/null +++ b/GravityStomp/Source/GravityStompGame/Camera/GSCameraActor.cpp @@ -0,0 +1,115 @@ +// Gravity Stomp Copyright Kevin Poretti + +#include "Camera/GSCameraActor.h" + +// UE includes +#include "Kismet/KismetMathLibrary.h" +#include "World/GSWorldSettings.h" + +AGSCameraActor::AGSCameraActor() +{ + PanSpeed = 100.0f; + ZoomSpeed = 100.0f; +} + + +void AGSCameraActor::Tick(float DeltaSeconds) +{ + Super::Tick(DeltaSeconds); + + FBox2D ScreenBoundingBox = GetBoundingBoxFromViewportPercentage(0); + + // bounding box of what is considered the "edge" of the screen + // when characters are outside of this box the camera should pan or zoom out + FBox2D EdgeBoundingBox = GetBoundingBoxFromViewportPercentage(0.15); + + // bounding box of what is considered the "center" of the screen + // when all characters are inside of this box the camera should zoom in + FBox2D CenterBoundingBox = GetBoundingBoxFromViewportPercentage(0.15); + + // debug + FVector2D ScreenBoxCenter = GetBoxCenter(ScreenBoundingBox); + float ScreenHeight, ScreenWidth; + GetBoxDimensions(ScreenBoundingBox, ScreenHeight, ScreenWidth); + DrawDebugBox(GetWorld(), FVector(0.0f, ScreenBoxCenter.X, ScreenBoxCenter.Y), FVector(0.0f, ScreenWidth/2, ScreenHeight/2), + FColor::Magenta, false, -1, 0, 2.0f); + + FVector CurrLocation = GetActorLocation(); + float ZoomMove = ZoomDirection * ZoomSpeed * DeltaSeconds; + FVector2D PanMove = PanDirection * PanSpeed * DeltaSeconds; + FVector2D NewPan = FVector2D(CurrLocation.Y + PanMove.X, CurrLocation.Z + PanMove.Y); + NewPan = ClampCameraLocationToStageBounds(NewPan, ScreenBoundingBox); + + FVector NewLocation = FVector(CurrLocation.X + ZoomMove, NewPan.X, NewPan.Y); + SetActorLocation(NewLocation); +} + + +FBox2D AGSCameraActor::GetBoundingBoxFromViewportPercentage(float ScreenPercentage) const +{ + APlayerController* PC = GetWorld()->GetFirstPlayerController(); + int32 SizeX, SizeY; + PC->GetViewportSize(SizeX, SizeY); + float MinX = ((float)SizeX) * ScreenPercentage; + float MinY = ((float)SizeY) * ScreenPercentage; + float MaxX = ((float)SizeX) * (1 - ScreenPercentage); + float MaxY = ((float)SizeY) * (1 - ScreenPercentage); + FVector TopRight = GetWorldLocationFromScreenCoords(MaxX, MinY); + FVector BottomLeft = GetWorldLocationFromScreenCoords(MinX, MaxY); + + FBox2D Result; + Result.Min = FVector2D(BottomLeft.Y, BottomLeft.Z); + Result.Max = FVector2D(TopRight.Y, TopRight.Z); + return Result; +} + + +FVector2D AGSCameraActor::GetBoxCenter(FBox2D Box) const +{ + return FVector2D((Box.Min.X + Box.Max.X) / 2.0f, (Box.Min.Y + Box.Max.Y) / 2.0f); +} + + +void AGSCameraActor::GetBoxDimensions(FBox2D Box, float& BoxHeight, float& BoxWidth) const +{ + BoxWidth = FMath::Abs(Box.Max.X - Box.Min.X); + BoxHeight = FMath::Abs(Box.Max.Y - Box.Min.Y); +} + + +FVector AGSCameraActor::GetWorldLocationFromScreenCoords(float InX, float InY) const +{ + APlayerController* PC = GetWorld()->GetFirstPlayerController(); + FVector WorldLocation; + FVector WorldDirection; + PC->DeprojectScreenPositionToWorld(InX, InY, WorldLocation, WorldDirection); + + FPlane XPlane = UKismetMathLibrary::MakePlaneFromPointAndNormal(FVector::ZeroVector, FVector::ForwardVector); + // NOTE: 10000 is a big enough number to make sure the intersection goes through the X = 0 plane + // there is probably a more elegant way to do this + float T; + FVector Result = FVector::ZeroVector; + UKismetMathLibrary::LinePlaneIntersection(WorldLocation, WorldLocation + (WorldDirection * 10000), XPlane, T, Result); + return Result; +} + + +FVector2D AGSCameraActor::ClampCameraLocationToStageBounds(FVector2D CameraLocation, FBox2D ScreenBox) const +{ + AGSWorldSettings* WS = Cast(GetWorld()->GetWorldSettings()); + FBox2D StageBounds = WS->StageBounds; + + float ScreenHeight, ScreenWidth; + GetBoxDimensions(ScreenBox, ScreenHeight, ScreenWidth); + float HalfHeight = ScreenHeight / 2; + float HalfWidth = ScreenWidth / 2; + + float MinStageX = StageBounds.Min.X + HalfWidth; + float MinStageY = StageBounds.Min.Y + HalfHeight; + float MaxStageX = StageBounds.Max.X - HalfWidth; + float MaxStageY = StageBounds.Max.Y - HalfHeight; + + float FinalX = FMath::Clamp(CameraLocation.X, MinStageX, MaxStageX); + float FinalY = FMath::Clamp(CameraLocation.Y, MinStageY, MaxStageY); + return FVector2D(FinalX, FinalY); +} diff --git a/GravityStomp/Source/GravityStompGame/Camera/GSCameraActor.h b/GravityStomp/Source/GravityStompGame/Camera/GSCameraActor.h new file mode 100644 index 0000000..6d40f00 --- /dev/null +++ b/GravityStomp/Source/GravityStompGame/Camera/GSCameraActor.h @@ -0,0 +1,45 @@ +// Gravity Stomp Copyright Kevin Poretti + +#pragma once + +#include "CoreMinimal.h" +#include "Camera/CameraActor.h" +#include "GSCameraActor.generated.h" + +/** + * + */ +UCLASS(showcategories=(Input)) +class GRAVITYSTOMPGAME_API AGSCameraActor : public ACameraActor +{ + GENERATED_BODY() + +public: + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Camera Settings") + float PanSpeed; + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Camera Settings") + float ZoomSpeed; + + UPROPERTY(BlueprintReadWrite) + FVector2D PanDirection; + + UPROPERTY(BlueprintReadWrite) + float ZoomDirection; + + AGSCameraActor(); + +protected: + virtual void Tick(float DeltaSeconds) override; + +private: + FBox2D GetBoundingBoxFromViewportPercentage(float ScreenPercentage) const; + + FVector2D GetBoxCenter(FBox2D Box) const; + + void GetBoxDimensions(FBox2D Box, float& BoxHeight, float& BoxWidth) const; + + FVector GetWorldLocationFromScreenCoords(float InX, float InY) const; + + FVector2D ClampCameraLocationToStageBounds(FVector2D CameraLocation, FBox2D ScreenBox) const; +}; diff --git a/GravityStomp/Source/GravityStompGame/GravityStompGame.Build.cs b/GravityStomp/Source/GravityStompGame/GravityStompGame.Build.cs index 8a59bfc..2152723 100644 --- a/GravityStomp/Source/GravityStompGame/GravityStompGame.Build.cs +++ b/GravityStomp/Source/GravityStompGame/GravityStompGame.Build.cs @@ -22,7 +22,7 @@ public class GravityStompGame : ModuleRules "CoreUObject", "Engine", "InputCore", - "EnhancedInput" + "EnhancedInput", } ); } diff --git a/GravityStomp/Source/GravityStompGame/World/GSWorldSettings.cpp b/GravityStomp/Source/GravityStompGame/World/GSWorldSettings.cpp new file mode 100644 index 0000000..d94f639 --- /dev/null +++ b/GravityStomp/Source/GravityStompGame/World/GSWorldSettings.cpp @@ -0,0 +1,10 @@ +// Gravity Stomp Copyright Kevin Poretti + + +#include "World/GSWorldSettings.h" + +AGSWorldSettings::AGSWorldSettings() +{ + StageBounds.Min = FVector2D(-2000.0f, 0.0f); + StageBounds.Max = FVector2D(2000.0f, 2250.0f); +} diff --git a/GravityStomp/Source/GravityStompGame/World/GSWorldSettings.h b/GravityStomp/Source/GravityStompGame/World/GSWorldSettings.h new file mode 100644 index 0000000..a4436aa --- /dev/null +++ b/GravityStomp/Source/GravityStompGame/World/GSWorldSettings.h @@ -0,0 +1,22 @@ +// Gravity Stomp Copyright Kevin Poretti + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/WorldSettings.h" +#include "GSWorldSettings.generated.h" + +/** + * + */ +UCLASS() +class GRAVITYSTOMPGAME_API AGSWorldSettings : public AWorldSettings +{ + GENERATED_BODY() + +public: + AGSWorldSettings(); + + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Gravity Stomp Settings") + FBox2D StageBounds; +};