Start of dynamic camera in C++
This commit is contained in:
parent
b4e7468204
commit
d07a08793b
@ -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
|
||||
|
BIN
GravityStomp/Content/Core/BP_GSCameraActor.uasset
(Stored with Git LFS)
BIN
GravityStomp/Content/Core/BP_GSCameraActor.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
GravityStomp/Content/Debug/Camera/BP_CameraDebugGameMode.uasset
(Stored with Git LFS)
Normal file
BIN
GravityStomp/Content/Debug/Camera/BP_CameraDebugGameMode.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
GravityStomp/Content/Debug/Camera/BP_GSDebugCameraActor.uasset
(Stored with Git LFS)
Normal file
BIN
GravityStomp/Content/Debug/Camera/BP_GSDebugCameraActor.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
GravityStomp/Content/Debug/Camera/TestCamera.umap
(Stored with Git LFS)
Normal file
BIN
GravityStomp/Content/Debug/Camera/TestCamera.umap
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
GravityStomp/Content/Maps/Debug/Test.umap
(Stored with Git LFS)
BIN
GravityStomp/Content/Maps/Debug/Test.umap
(Stored with Git LFS)
Binary file not shown.
115
GravityStomp/Source/GravityStompGame/Camera/GSCameraActor.cpp
Normal file
115
GravityStomp/Source/GravityStompGame/Camera/GSCameraActor.cpp
Normal file
@ -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<AGSWorldSettings>(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);
|
||||
}
|
45
GravityStomp/Source/GravityStompGame/Camera/GSCameraActor.h
Normal file
45
GravityStomp/Source/GravityStompGame/Camera/GSCameraActor.h
Normal file
@ -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;
|
||||
};
|
@ -22,7 +22,7 @@ public class GravityStompGame : ModuleRules
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"InputCore",
|
||||
"EnhancedInput"
|
||||
"EnhancedInput",
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
22
GravityStomp/Source/GravityStompGame/World/GSWorldSettings.h
Normal file
22
GravityStomp/Source/GravityStompGame/World/GSWorldSettings.h
Normal file
@ -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;
|
||||
};
|
Loading…
Reference in New Issue
Block a user