Skip to content
Snippets Groups Projects
Commit c24fe986 authored by Kris Tabea Helwig's avatar Kris Tabea Helwig
Browse files

Implemented PointOfInterest as position markers, PointOfInterestManager as...

Implemented PointOfInterest as position markers, PointOfInterestManager as Manager, splines that connect POIs, and camera rides;
parent 2cc785ce
No related branches found
No related tags found
1 merge request!1Implements `PointOfInterest`s
File added
File added
#include "PointOfInterest.h"
#include "Logging/StructuredLog.h"
#include "Components/BillboardComponent.h"
DEFINE_LOG_CATEGORY(POILog)
APointOfInterest::APointOfInterest()
{
UE_LOGFMT(POILog, Verbose, "POI instantiated");
SetRootComponent(CreateDefaultSubobject<USceneComponent>("SceneComponent"));
auto Billboard = CreateDefaultSubobject<UBillboardComponent>("BillboardComponent");
static ConstructorHelpers::FObjectFinder<UTexture2D> LocationMarker(TEXT("/Script/Engine.Texture2D'/RWTHVRQuickStart/location_marker.location_marker'"));
if(LocationMarker.Succeeded())
{
Billboard->SetSprite(LocationMarker.Object);
}
else
{
UE_LOGFMT(POILog, Verbose, "POILog: Could not find location marker Texture. The Asset might have moved.");
}
Billboard->AttachToComponent(RootComponent, FAttachmentTransformRules::SnapToTargetIncludingScale);
Billboard->SetHiddenInGame(true);
Billboard->SetWorldScale3D(FVector(0.1f, 0.1f, 0.1f));
}
#include "PointOfInterestManager.h"
#include "PointOfInterest.h"
#include "Kismet/GameplayStatics.h"
#include "Logging/StructuredLog.h"
DEFINE_LOG_CATEGORY(POIManagerLog);
APointOfInterestManager::APointOfInterestManager()
{
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bStartWithTickEnabled = true;
PrimaryActorTick.SetTickFunctionEnable(true);
POIs = TArray<APointOfInterest*>();
SplineComponent = CreateDefaultSubobject<USplineComponent>("SplineComponent");
SplineComponent->SetupAttachment(RootComponent.Get());
}
void APointOfInterestManager::TickActor(float DeltaTime, enum ELevelTick TickType, FActorTickFunction& ThisTickFunction)
{
SplineComponent->Duration = SplineComponent->GetSplineLength() / CameraSpeed;
if (IsRidingCamera)
{
ProgressCameraRide();
}
}
void APointOfInterestManager::AddPointOfInterest()
{
APointOfInterest* POI = static_cast<APointOfInterest*>(GetWorld()->SpawnActor(APointOfInterest::StaticClass()));
TScriptDelegate Del = TScriptDelegate();
Del.BindUFunction(this, "UpdateSpline");
POI->GetRootComponent()->TransformUpdated.AddLambda([this](USceneComponent*, EUpdateTransformFlags, ETeleportType)
{
UpdateSpline();
});
POIs.Add(POI);
UpdateSpline();
}
void APointOfInterestManager::VisitNextPointOfInterest()
{
if (CurrentPOIIndex >= GetPointOfInterestCount() - 1)
{
CurrentPOIIndex = 0;
}
else
{
++CurrentPOIIndex;
}
VisitPointOfInterest(POIs[CurrentPOIIndex]);
}
void APointOfInterestManager::VisitPreviousPointOfInterest()
{
if (CurrentPOIIndex <= 0)
{
CurrentPOIIndex = GetPointOfInterestCount() - 1;
}
else
{
--CurrentPOIIndex;
}
VisitPointOfInterest(POIs[CurrentPOIIndex]);
}
void APointOfInterestManager::VisitPointOfInterestByIndex(int index)
{
VisitPointOfInterest(POIs[index]);
}
void APointOfInterestManager::VisitPointOfInterest(APointOfInterest* POI) const
{
APawn* Pawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
if (!Pawn)
{
UE_LOGFMT(POIManagerLog, Warning, "Attempted to move player pawn but no pawn found to move.");
return;
}
FVector Location = POI->GetActorLocation();
FRotator Rotation = POI->GetActorRotation();
Rotation.Pitch = 0;
Rotation.Roll = 0;
Pawn->Controller->SetControlRotation(Rotation);
Pawn->SetActorLocationAndRotation(Location, Rotation);
}
int APointOfInterestManager::GetPointOfInterestCount()
{
return POIs.Num();
}
void APointOfInterestManager::StartCameraRide()
{
CameraRideStart = UGameplayStatics::GetTimeSeconds(this);
CameraRideEnd = CameraRideStart + SplineComponent->Duration;
IsRidingCamera = true;
}
void APointOfInterestManager::StopCameraRide()
{
CameraRideEnded();
}
void APointOfInterestManager::UpdateSpline()
{
for (int i = 0; i < GetPointOfInterestCount(); ++i)
{
if (POIs[i] == nullptr)
{
POIs.RemoveAt(i);
SplineComponent->RemoveSplinePoint(i);
--i;
}
else if (!POIs[i]->GetRootComponent()->TransformUpdated.IsBound())
{
POIs[i]->GetRootComponent()->TransformUpdated.AddLambda(
[this](USceneComponent*, EUpdateTransformFlags, ETeleportType)
{
UpdateSpline();
});
}
}
int POIsNum = GetPointOfInterestCount();
int SplinePointsNum = SplineComponent->GetNumberOfSplinePoints();
if (POIsNum > SplinePointsNum)
{
for (int i = SplinePointsNum; i < POIsNum; ++i)
{
SplineComponent->AddSplinePointAtIndex(FVector::Zero(), i, ESplineCoordinateSpace::World);
}
}
else if (POIsNum < SplinePointsNum)
{
for (int i = SplinePointsNum - 1; i >= POIsNum; --i)
{
SplineComponent->RemoveSplinePoint(i);
}
}
for (int i = 0; i < GetPointOfInterestCount(); ++i)
{
APointOfInterest* POI = POIs[i];
FVector POIPosition = POI->GetActorLocation();
FRotator POIRotation = POI->GetActorRotation();
SplineComponent->SetLocationAtSplinePoint(i, POIPosition, ESplineCoordinateSpace::World);
SplineComponent->SetRotationAtSplinePoint(i, POIRotation, ESplineCoordinateSpace::World);
}
}
void APointOfInterestManager::ProgressCameraRide()
{
double Current = UGameplayStatics::GetTimeSeconds(this);
float SecondsSinceStart = Current - CameraRideStart;
UE_LOGFMT(POIManagerLog, VeryVerbose, "");
APawn* Pawn = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
if (!Pawn)
{
UE_LOGFMT(POIManagerLog, Warning, "Attempted to move player pawn but no pawn found to move.");
return;
}
if (Current < CameraRideEnd)
{
FVector Location = SplineComponent->GetLocationAtTime(SecondsSinceStart, ESplineCoordinateSpace::World);
FRotator Rotation = SplineComponent->GetRotationAtTime(SecondsSinceStart, ESplineCoordinateSpace::World);
Rotation.Pitch = 0;
Rotation.Roll = 0;
Pawn->Controller->SetControlRotation(Rotation);
Pawn->SetActorLocationAndRotation(Location, Rotation);
}
else
{
CameraRideEnded();
}
}
void APointOfInterestManager::CameraRideEnded()
{
IsRidingCamera = false;
VisitPointOfInterestByIndex(GetPointOfInterestCount() - 1);
}
#pragma once
#include "CoreMinimal.h"
#include "PointOfInterest.generated.h"
DECLARE_LOG_CATEGORY_EXTERN(POILog, All, All)
UCLASS()
class APointOfInterest : public AActor
{
GENERATED_BODY()
public:
APointOfInterest();
};
#pragma once
#include "CoreMinimal.h"
#include "Components/SplineComponent.h"
#include "PointOfInterestManager.generated.h"
DECLARE_LOG_CATEGORY_EXTERN(POIManagerLog, All, All);
class APointOfInterest;
class FCameraRide;
UCLASS(Blueprintable)
class APointOfInterestManager : public AActor
{
GENERATED_BODY()
public:
APointOfInterestManager();
virtual void TickActor(float DeltaTime, enum ELevelTick TickType, FActorTickFunction& ThisTickFunction) override;
UFUNCTION(CallInEditor, Category="Point Of Interest Manager")
void AddPointOfInterest();
UFUNCTION(CallInEditor, Category="Point Of Interest Manager")
void VisitNextPointOfInterest();
UFUNCTION(CallInEditor, Category="Point Of Interest Manager")
void VisitPreviousPointOfInterest();
void VisitPointOfInterestByIndex(int index);
void VisitPointOfInterest(APointOfInterest* POI) const;
UFUNCTION(CallInEditor, Category="Point Of Interest Manager")
void StartCameraRide();
UFUNCTION(CallInEditor, Category="Point Of Interest Manager")
void StopCameraRide();
int GetPointOfInterestCount();
protected:
UPROPERTY(EditAnywhere)
TArray<APointOfInterest*> POIs;
int CurrentPOIIndex = 0;
private:
UFUNCTION(CallInEditor, Category="Point Of Interest Manager")
void UpdateSpline();
void ProgressCameraRide();
void CameraRideEnded();
USplineComponent* SplineComponent;
UPROPERTY(EditAnywhere, meta=(UIMin = 0.0, UIMax = 500))
float CameraSpeed = 100;
bool IsRidingCamera;
float CameraRideStart, CameraRideEnd;
};
...@@ -25,7 +25,7 @@ public class RWTHVRQuickStart : ModuleRules ...@@ -25,7 +25,7 @@ public class RWTHVRQuickStart : ModuleRules
PublicDependencyModuleNames.AddRange( PublicDependencyModuleNames.AddRange(
new string[] new string[]
{ {
"Core", "Core", "Engine", "Engine",
// ... add other public dependencies that you statically link with here ... // ... add other public dependencies that you statically link with here ...
} }
); );
...@@ -37,7 +37,7 @@ public class RWTHVRQuickStart : ModuleRules ...@@ -37,7 +37,7 @@ public class RWTHVRQuickStart : ModuleRules
"CoreUObject", "CoreUObject",
"Engine", "Engine",
"Slate", "Slate",
"SlateCore", "SlateCore", "RWTHVRToolkit", "RWTHVRToolkit",
// ... add private dependencies that you statically link with here ... // ... add private dependencies that you statically link with here ...
} }
); );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment