Move generic pickup functionality to base Pickup class

This commit is contained in:
Louis Hobbs 2023-06-24 15:11:09 +01:00
parent b1eed2ff2e
commit 79d61a200e
4 changed files with 80 additions and 66 deletions

View File

@ -2,26 +2,54 @@
#include "Pickup.h" #include "Pickup.h"
#include "PlayerCharacter.h"
// Sets default values // Sets default values
APickup::APickup() APickup::APickup()
{ {
// 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;
PrimaryActorTick.SetTickFunctionEnable(true);
PrimaryActorTick.bStartWithTickEnabled = true;
SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
SphereComponent->SetSphereRadius(25.0f, true);
SphereComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndProbe);
SphereComponent->SetupAttachment(RootComponent);
PointLightComponent = CreateDefaultSubobject<UPointLightComponent>(TEXT("PointLightComponent"));
PointLightComponent->SetLightColor(FLinearColor::FromSRGBColor(LightColor));
PointLightComponent->SetupAttachment(RootComponent);
} }
// Called when the game starts or when spawned // Called when the game starts or when spawned
void APickup::BeginPlay() void APickup::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
SphereComponent->OnComponentBeginOverlap.AddDynamic(this, &APickup::OnOverlapBegin);
PointLightComponent->SetWorldLocation(this->GetActorLocation());
} }
// Called every frame // Called every frame
void APickup::Tick(float DeltaTime) void APickup::Tick(const float DeltaTime)
{ {
Super::Tick(DeltaTime); Super::Tick(DeltaTime);
PointLightComponent->MarkRenderStateDirty();
// We have to do this because Unreal doesn't like it when you create lights in c++ apparently ::pain::
const float Sin = FMath::Abs(FMath::Sin(GetWorld()->GetRealTimeSeconds() * (LightFadeSpeed / 2)));
//PointLightComponent->SetLightBrightness(sin * MaxLightBrightness);
PointLightComponent->SetLightBrightness(Sin * MaxLightBrightness);
} }
void APickup::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep,
const FHitResult& SweepResult)
{
if (Cast<APlayerCharacter>(OtherActor))
{
this->Destroy();
}
}

View File

@ -2,6 +2,8 @@
#pragma once #pragma once
#include <Components/PointLightComponent.h>
#include <Components/SphereComponent.h>
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "GameFramework/Actor.h" #include "GameFramework/Actor.h"
#include "Pickup.generated.h" #include "Pickup.generated.h"
@ -10,8 +12,25 @@ UCLASS()
class NAKATOMI_API APickup : public AActor class NAKATOMI_API APickup : public AActor
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
float LightFadeSpeed = 1.0f;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
float MaxLightBrightness = 5000.0f;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
FColor LightColor = FColor::White;
private:
UPROPERTY()
USphereComponent* SphereComponent;
UPROPERTY()
UPointLightComponent* PointLightComponent;
public:
// Sets default values for this actor's properties // Sets default values for this actor's properties
APickup(); APickup();
@ -19,8 +38,12 @@ protected:
// Called when the game starts or when spawned // Called when the game starts or when spawned
virtual void BeginPlay() override; virtual void BeginPlay() override;
public: public:
// Called every frame // Called every frame
virtual void Tick(float DeltaTime) override; virtual void Tick(float DeltaTime) override;
UFUNCTION()
virtual void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
}; };

View File

@ -1,25 +1,11 @@
// Fill out your copyright notice in the Description page of Project Settings. // Fill out your copyright notice in the Description page of Project Settings.
#include "WeaponPickup.h" #include "WeaponPickup.h"
#include "PlayerCharacter.h"
// Sets default values // Sets default values
AWeaponPickup::AWeaponPickup() AWeaponPickup::AWeaponPickup()
{ {
// 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.SetTickFunctionEnable(true);
PrimaryActorTick.bStartWithTickEnabled = true;
SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
SphereComponent->SetSphereRadius(25.0f, true);
SphereComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndProbe);
SphereComponent->SetupAttachment(RootComponent);
PointLightComponent = CreateDefaultSubobject<UPointLightComponent>(TEXT("PointLightComponent"));
PointLightComponent->SetLightColor(FLinearColor::FromSRGBColor(LightColor));
PointLightComponent->SetupAttachment(RootComponent);
} }
// Called when the game starts or when spawned // Called when the game starts or when spawned
@ -31,13 +17,10 @@ void AWeaponPickup::BeginPlay()
{ {
SpawnWeapon(); SpawnWeapon();
} }
SphereComponent->OnComponentBeginOverlap.AddDynamic(this, &AWeaponPickup::OnOverlapBegin);
PointLightComponent->SetWorldLocation(this->GetActorLocation());
} }
// Called every frame // Called every frame
void AWeaponPickup::Tick(float DeltaTime) void AWeaponPickup::Tick(const float DeltaTime)
{ {
Super::Tick(DeltaTime); Super::Tick(DeltaTime);
@ -47,15 +30,10 @@ void AWeaponPickup::Tick(float DeltaTime)
WeaponComponent->AddActorLocalRotation((SpinRotation * RotationSpeed) * DeltaTime); WeaponComponent->AddActorLocalRotation((SpinRotation * RotationSpeed) * DeltaTime);
// Bob weapon up and down // Bob weapon up and down
float Time = GetWorld()->GetRealTimeSeconds(); const float Time = GetWorld()->GetRealTimeSeconds();
float Sine = FMath::Sin(Time * MovementSpeed); const float Sine = FMath::Sin(Time * MovementSpeed);
WeaponComponent->SetActorLocation(WeaponStartingLocation + ((MovementDirection * Sine) * MovementDistance)); WeaponComponent->SetActorLocation(WeaponStartingLocation + ((MovementDirection * Sine) * MovementDistance));
} }
PointLightComponent->MarkRenderStateDirty();
// We have to do this because Unreal doesn't like it when you create lights in c++ apparently ::pain::
float sin = FMath::Abs(FMath::Sin(GetWorld()->GetRealTimeSeconds() * (MovementSpeed / 2)));
PointLightComponent->SetLightBrightness(sin * MaxLightBrightness);
} }
void AWeaponPickup::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, void AWeaponPickup::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
@ -63,21 +41,22 @@ void AWeaponPickup::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AAc
const FHitResult& SweepResult) const FHitResult& SweepResult)
{ {
// TODO: Add extra checking here // TODO: Add extra checking here
auto player = Cast<APlayerCharacter>(OtherActor);
if (player && Weapon) const auto Player = Cast<APlayerCharacter>(OtherActor);
if (Player && Weapon)
{ {
player->AddWeaponToInventory(Weapon); Player->AddWeaponToInventory(Weapon);
player->WeaponInventory.Last()->SetWeaponProperties(*WeaponComponent->GetWeaponProperties()); Player->WeaponInventory.Last()->SetWeaponProperties(*WeaponComponent->GetWeaponProperties());
this->Destroy();
WeaponComponent->Destroy(); WeaponComponent->Destroy();
} }
Super::OnOverlapBegin(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult);
} }
void AWeaponPickup::SetWeapon(TSubclassOf<class AWeapon> weapon) void AWeaponPickup::SetWeapon(const TSubclassOf<AWeapon> NewWeapon)
{ {
Weapon = weapon; Weapon = NewWeapon;
if (WeaponComponent) if (WeaponComponent)
{ {
@ -92,7 +71,7 @@ FWeaponProperties* AWeaponPickup::GetWeaponProperties()
return &WeaponProperties; return &WeaponProperties;
} }
void AWeaponPickup::SetWeaponProperties(FWeaponProperties FWeaponProperties) void AWeaponPickup::SetWeaponProperties(const FWeaponProperties& FWeaponProperties) const
{ {
WeaponComponent->SetWeaponProperties(FWeaponProperties); WeaponComponent->SetWeaponProperties(FWeaponProperties);
} }
@ -102,7 +81,7 @@ void AWeaponPickup::SpawnWeapon()
FActorSpawnParameters SpawnParameters; FActorSpawnParameters SpawnParameters;
SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
WeaponComponent = GetWorld()->SpawnActor<AWeapon>(Weapon, SpawnParameters); WeaponComponent = GetWorld()->SpawnActor<AWeapon>(Weapon, SpawnParameters);
FAttachmentTransformRules TransformRules = FAttachmentTransformRules( const FAttachmentTransformRules TransformRules = FAttachmentTransformRules(
EAttachmentRule::SnapToTarget, EAttachmentRule::SnapToTarget, EAttachmentRule::SnapToTarget, true); EAttachmentRule::SnapToTarget, EAttachmentRule::SnapToTarget, EAttachmentRule::SnapToTarget, true);
WeaponComponent->AttachToComponent(RootComponent, TransformRules); WeaponComponent->AttachToComponent(RootComponent, TransformRules);
WeaponComponent->SetActorRelativeLocation(FVector(0.0f, 0.0f, 5.0f)); WeaponComponent->SetActorRelativeLocation(FVector(0.0f, 0.0f, 5.0f));

View File

@ -2,22 +2,18 @@
#pragma once #pragma once
#include <Components/PointLightComponent.h> #include "Pickup.h"
#include "Components/SphereComponent.h"
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "PlayerCharacter.h"
#include "Weapon.h" #include "Weapon.h"
#include "WeaponPickup.generated.h" #include "WeaponPickup.generated.h"
UCLASS() UCLASS()
class NAKATOMI_API AWeaponPickup : public AActor class NAKATOMI_API AWeaponPickup : public APickup
{ {
GENERATED_BODY() GENERATED_BODY()
public: public:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
TSubclassOf<class AWeapon> Weapon; TSubclassOf<AWeapon> Weapon;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
FVector MovementDirection = FVector(0.0f, 0.0f, 1.0f); FVector MovementDirection = FVector(0.0f, 0.0f, 1.0f);
@ -34,16 +30,7 @@ public:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
float RotationSpeed = 50.0f; float RotationSpeed = 50.0f;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
float MaxLightBrightness = 5000.0f;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
FColor LightColor = FColor::White;
private: private:
UPROPERTY()
USphereComponent* SphereComponent;
UPROPERTY() UPROPERTY()
AWeapon* WeaponComponent; AWeapon* WeaponComponent;
@ -52,9 +39,6 @@ private:
FWeaponProperties WeaponProperties; FWeaponProperties WeaponProperties;
UPROPERTY()
UPointLightComponent* PointLightComponent;
public: public:
// Sets default values for this actor's properties // Sets default values for this actor's properties
AWeaponPickup(); AWeaponPickup();
@ -67,15 +51,15 @@ public:
// Called every frame // Called every frame
virtual void Tick(float DeltaTime) override; virtual void Tick(float DeltaTime) override;
UFUNCTION() virtual void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, UPrimitiveComponent* OtherComp,
int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult); int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) override;
void SetWeapon(TSubclassOf<class AWeapon> weapon); void SetWeapon(TSubclassOf<AWeapon> NewWeapon);
FWeaponProperties* GetWeaponProperties(); FWeaponProperties* GetWeaponProperties();
void SetWeaponProperties(FWeaponProperties FWeaponProperties); void SetWeaponProperties(const FWeaponProperties& FWeaponProperties) const;
private: private:
void SpawnWeapon(); void SpawnWeapon();