Implemented Vision Link Gadget Tutorial

This commit is contained in:
Rafal Swierczek 2023-11-02 02:27:04 +00:00
parent 8694b8746b
commit 7ee592f1f0
20 changed files with 211 additions and 33 deletions

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4dfc52ea68790fe41a2183cebf9f3f1760c3cd066efe8459f7f116673f524040
size 212777

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:27d39fdab60fb9511fcfe760ba9180190bdbe16c5f1f62357f88de13800d47b7 oid sha256:f33dd03b39415d19a4fe13c124542d77eb6517c16ad6bc19177c5acb82fd82a2
size 108912 size 109451

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:5865096b570bd55d2eb3055389ccd4c7f9db407bb3f830746a5736a47d34253a oid sha256:eccb9b1edb192ea701130918efac376eee57496ac65768f76a09f95c956d84e6
size 607074 size 607443

Binary file not shown.

View File

@ -19,10 +19,10 @@ class ENDLESSVENDETTA_API AWaypointActor : public AActor
float ScalingY_Intercept; float ScalingY_Intercept;
UPROPERTY(EditDefaultsOnly, Category = "Waypoint Scaling") UPROPERTY(EditDefaultsOnly, Category = "Waypoint Scaling")
float MaxDist = 8000.f; float MaxDist = 16000.f;
UPROPERTY(EditDefaultsOnly, Category = "Waypoint Scaling") UPROPERTY(EditDefaultsOnly, Category = "Waypoint Scaling")
float ScaleAtMaxDist = 8.f; float ScaleAtMaxDist = 4.f;
UPROPERTY(EditDefaultsOnly, Category = "Waypoint Scaling") UPROPERTY(EditDefaultsOnly, Category = "Waypoint Scaling")
float MinDist = 900.f; float MinDist = 900.f;

View File

@ -423,8 +423,8 @@ bool AEndlessVendettaCharacter::GetHasRifle()
bool AEndlessVendettaCharacter::UpdateGadgetType(TSubclassOf<AGadgetBase> NewGadgetClass) bool AEndlessVendettaCharacter::UpdateGadgetType(TSubclassOf<AGadgetBase> NewGadgetClass)
{ {
if (NewGadgetClass.GetDefaultObject()->IsA(AReconGadget::StaticClass()) && GadgetManager->CantReplaceReconGadget()) return false; if (NewGadgetClass.GetDefaultObject()->IsA(AReconGadget::StaticClass()) && GadgetManager->ReconCantBeSwitchedOut()) return false;
if (NewGadgetClass.GetDefaultObject()->IsA(ACombatGadget::StaticClass()) && GadgetManager->CantReplaceCombatGadget()) return false; if (NewGadgetClass.GetDefaultObject()->IsA(ACombatGadget::StaticClass()) && GadgetManager->CombatCantBeSwitchedOut()) return false;
for (UActorComponent* PlayersCamera : GetComponentsByTag(UCameraComponent::StaticClass(), FName("PlayersCamera"))) for (UActorComponent* PlayersCamera : GetComponentsByTag(UCameraComponent::StaticClass(), FName("PlayersCamera")))
{ {

View File

@ -87,10 +87,11 @@ protected:
UPROPERTY(EditDefaultsOnly, Category = "Gadget") UPROPERTY(EditDefaultsOnly, Category = "Gadget")
TSubclassOf<AGadgetManager> GadgetManagerClass; TSubclassOf<AGadgetManager> GadgetManagerClass;
AGadgetManager* GadgetManager;
public: public:
int Money = 2000; int Money = 2000;
AGadgetManager* GadgetManager;
bool bIsReloading = false; bool bIsReloading = false;
/** Look Input Action */ /** Look Input Action */

View File

@ -78,16 +78,24 @@ public:
return false; return false;
} }
bool CantReplaceReconGadget() bool ReconInUse()
{ {
// Cant be replaced if it exists, and is either in use whilst being unequippable in use, or equipped and cant be unequipped return IsValidReconGadget() && ReconGadget->IsInUse();
return IsValidReconGadget() && (ReconGadget->IsInUse() && ReconGadget->IsUnequippableInUse() || IsReconEquipped() && !TryToUnequipRecon());
} }
bool CantReplaceCombatGadget() bool CombatInUse()
{ {
// Cant be replaced if it exists, and is either in use whilst being unequippable in use, or equipped and cant be unequipped return IsValidCombatGadget() && CombatGadget->IsInUse();
return IsValidCombatGadget() && (CombatGadget->IsInUse() && CombatGadget->IsUnequippableInUse() || IsCombatEquipped() && !TryToUnequipCombat()); }
bool ReconCantBeSwitchedOut()
{
return IsValidReconGadget() && (ReconGadget->IsInUse() || (ReconGadget->Equipped && !TryToUnequipRecon()));
}
bool CombatCantBeSwitchedOut()
{
return IsValidCombatGadget() && (CombatGadget->IsInUse() || (CombatGadget->Equipped && !TryToUnequipCombat()));
} }
}; };

View File

@ -8,6 +8,7 @@ ABaseGadgetTutorial::ABaseGadgetTutorial()
{ {
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true; PrimaryActorTick.bCanEverTick = true;
bAllowTickBeforeBeginPlay = false;
} }
@ -25,8 +26,18 @@ void ABaseGadgetTutorial::Tick(float DeltaTime)
} }
void ABaseGadgetTutorial::SpawnNewWaypoint(FVector Loc, FString Desc)
{
if (IsValid(WaypointActor)) WaypointActor->Destroy();
FActorSpawnParameters SpawnParams;
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
WaypointActor = Cast<AWaypointActor>(GetWorld()->SpawnActor<AActor>(WaypointClass, Loc, GetActorRotation(), SpawnParams));
WaypointActor->SetupWaypoint(WaypointIcon, Desc);
}
void ABaseGadgetTutorial::DestroyTutorial() void ABaseGadgetTutorial::DestroyTutorial()
{ {
UE_LOG(LogTemp, Warning, TEXT("Destroyed Tutorial"));
Destroy(); Destroy();
} }

View File

@ -3,18 +3,29 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "EndlessVendetta/BountySystem/WaypointActor.h"
#include "GameFramework/Actor.h" #include "GameFramework/Actor.h"
#include "BaseGadgetTutorial.generated.h" #include "BaseGadgetTutorial.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FCompletedGadgetTutorial)
UCLASS() UCLASS()
class ENDLESSVENDETTA_API ABaseGadgetTutorial : public AActor class ENDLESSVENDETTA_API ABaseGadgetTutorial : public AActor
{ {
GENERATED_BODY() GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = "Gadget Tutorial")
FTransform SpawnTransform;
protected: protected:
UPROPERTY(EditDefaultsOnly, Category = "Gadget Tutorial")
TSubclassOf<AWaypointActor> WaypointClass;
AWaypointActor* WaypointActor;
UPROPERTY(EditDefaultsOnly, Category = "Gadget Tutorial")
UTexture2D* WaypointIcon;
void SpawnNewWaypoint(FVector Loc, FString Desc);
// Called when the game starts or when spawned // Called when the game starts or when spawned
virtual void BeginPlay() override; virtual void BeginPlay() override;
@ -22,14 +33,12 @@ public:
// Sets default values for this actor's properties // Sets default values for this actor's properties
ABaseGadgetTutorial(); ABaseGadgetTutorial();
FCompletedGadgetTutorial CompletedGadgetTutorial;
// Called every frame // Called every frame
virtual void Tick(float DeltaTime) override; virtual void Tick(float DeltaTime) override;
virtual void DestroyTutorial(); virtual void DestroyTutorial();
FTransform GetSpawnTransform()
{
return SpawnTransform;
}
}; };

View File

@ -94,8 +94,8 @@ void AGadgetTutorialStation::SelectGadget()
FActorSpawnParameters SpawnParams; FActorSpawnParameters SpawnParams;
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
TSubclassOf<ABaseGadgetTutorial> GadgetTutorialToSpawnInClass = GadgetsArray[GadgetIndex]->GetDefaultObject<AGadgetBase>()->GadgetTutorialClass; TSubclassOf<ABaseGadgetTutorial> GadgetTutorialToSpawnInClass = GadgetsArray[GadgetIndex]->GetDefaultObject<AGadgetBase>()->GadgetTutorialClass;
FTransform SpawnTransform = GadgetTutorialToSpawnInClass->GetDefaultObject<ABaseGadgetTutorial>()->GetSpawnTransform(); if (!IsValid(GadgetTutorialToSpawnInClass)) return;
AActor* GadgetTutorialActor = GetWorld()->SpawnActor<AActor>(GadgetTutorialToSpawnInClass, SpawnTransform.GetLocation(), SpawnTransform.GetRotation().Rotator(), SpawnParams); AActor* GadgetTutorialActor = GetWorld()->SpawnActor<AActor>(GadgetTutorialToSpawnInClass, GadgetTutorialSpawnTransform.GetLocation(), GadgetTutorialSpawnTransform.GetRotation().Rotator(), SpawnParams);
CurrentGadgetTutorial = Cast<ABaseGadgetTutorial>(GadgetTutorialActor); CurrentGadgetTutorial = Cast<ABaseGadgetTutorial>(GadgetTutorialActor);
} }

View File

@ -24,6 +24,9 @@ class ENDLESSVENDETTA_API AGadgetTutorialStation : public AActor, public IIntera
UPROPERTY(EditDefaultsOnly, Category = "Gadgets") UPROPERTY(EditDefaultsOnly, Category = "Gadgets")
TSubclassOf<UGadgetMenu> PickGadgetWidgetClass; TSubclassOf<UGadgetMenu> PickGadgetWidgetClass;
UPROPERTY(EditDefaultsOnly, Category = "Gadgets")
FTransform GadgetTutorialSpawnTransform;
int GadgetIndex = 0; int GadgetIndex = 0;
UUserWidget* PickGadgetWidget; UUserWidget* PickGadgetWidget;

View File

@ -0,0 +1,71 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "VisionLinkTutorial.h"
#include "EndlessVendetta/EndlessVendettaCharacter.h"
#include "EndlessVendetta/GadgetSystem/GadgetManager.h"
#include "Kismet/KismetMathLibrary.h"
void AVisionLinkTutorial::BeginPlay()
{
Super::BeginPlay();
SpawnEnemiesAndSetupDefaults();
SpawnNewWaypoint(GoToAreaWaypointLoc, GoToAreaWaypointDesc);
SetActorTickInterval(0.2);
}
void AVisionLinkTutorial::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
if (!PlayerInTutorialZone)
{
if (PlayerWasInTutZone) SpawnNewWaypoint(GoToAreaWaypointLoc, GoToAreaWaypointDesc);
PlayerWasInTutZone = false;
return;
}
if (!PlayerWasInTutZone) SpawnNewWaypoint(LookAtTargetWaypointLoc, LookAtTargetWaypointDesc);
PlayerWasInTutZone = true;
// Check if players recon gadget (vision link) is in active
APawn* PlayerPawn = GetWorld()->GetFirstPlayerController()->GetPawn();
AEndlessVendettaCharacter* EndlessVendettaCharacter = Cast<AEndlessVendettaCharacter>(PlayerPawn);
AGadgetManager* GadgetManager = EndlessVendettaCharacter->GadgetManager;
if (!GadgetManager->ReconInUse()) return;
// Check if the player is roughly looking at their target
FRotator LookAtRot = UKismetMathLibrary::FindLookAtRotation(PlayerPawn->GetActorLocation(), TargetLoc);
FRotator PlayersRotator = PlayerPawn->GetActorRotation();
// Keep all yaw values between -180 and 180 to simplify the comparison
float DesiredtYaw = LookAtRot.Yaw - (LookAtRot.Yaw > 180 ? 360 : 0);
float PlayersYaw = PlayersRotator.Yaw - (PlayersRotator.Yaw > 180 ? 360 : 0);
// Do nothing if players yaw is off by more than 45 degrees
if (FMath::Abs(DesiredtYaw - PlayersYaw) > 45) return;
SpawnNewWaypoint(ResultWaypointLoc, ResultWaypointDesc);
FTimerHandle TimerHandle;
GetWorld()->GetTimerManager().SetTimer(TimerHandle, this, &AVisionLinkTutorial::FinishedTutorial, 7.5);
SetActorTickEnabled(false);
}
void AVisionLinkTutorial::DestroyTutorial()
{
if (IsValid(WaypointActor)) WaypointActor->Destroy();
DespawnEnemies();
Super::DestroyTutorial();
}
void AVisionLinkTutorial::FinishedTutorial()
{
if (IsValid(WaypointActor)) WaypointActor->Destroy();
CompletedGadgetTutorial.Broadcast();
}

View File

@ -0,0 +1,60 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "BaseGadgetTutorial.h"
#include "VisionLinkTutorial.generated.h"
UCLASS()
class ENDLESSVENDETTA_API AVisionLinkTutorial : public ABaseGadgetTutorial
{
GENERATED_BODY()
bool PlayerInTutorialZone = false;
bool PlayerWasInTutZone = false;
void BeginPlay() override;
void Tick(float DeltaSeconds) override;
void DestroyTutorial() override;
protected:
UPROPERTY(EditDefaultsOnly)
FString GoToAreaWaypointDesc;
UPROPERTY(EditDefaultsOnly)
FString LookAtTargetWaypointDesc;
UPROPERTY(EditDefaultsOnly)
FString ResultWaypointDesc;
UPROPERTY(BlueprintReadWrite)
FVector GoToAreaWaypointLoc;
UPROPERTY(BlueprintReadWrite)
FVector LookAtTargetWaypointLoc;
UPROPERTY(BlueprintReadWrite)
FVector ResultWaypointLoc;
UPROPERTY(BlueprintReadWrite)
FVector TargetLoc;
// Spawns enemies, sets up waypoint locs, and target loc
UFUNCTION(BlueprintImplementableEvent)
void SpawnEnemiesAndSetupDefaults();
UFUNCTION(BlueprintImplementableEvent)
void DespawnEnemies();
UFUNCTION(BlueprintCallable)
void PlayerEnteredTutorialZone()
{
PlayerInTutorialZone = true;
}
UFUNCTION(BlueprintCallable)
void PlayerLeftTutorialZone()
{
PlayerInTutorialZone = false;
}
void FinishedTutorial();
};