Pickup System in UE5 using C++

203 views Asked by At

So I'm having trouble with this pickup system I've been working on in UE5 with 4 different pickups that add a color material to the character's mesh and an ability (ex: blue pickup makes character blue and doubles its size). I also need to develop a spawner that can spawn each of the 4 pickups at random.

Functions for each pickup If and switch/case in the pickup collection function that references the 4 functions I made in my character cpp

I thought this would would work but when I went to Unreal to compile the code I got this error Compiler error

I've looked up the error code and I couldn't find a solution.

Code:

Pickup.cpp


#include "Pickup.h"
#include "SpawnerCharacter.h"

#include "Components/StaticMeshComponent.h"
#include "Kismet/KismetMathLibrary.h"

// Sets default values
APickup::APickup()
{
    // 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;

    BIsActive = true;

    RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));

    VisibleComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisibleComponent"));
    VisibleComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
}

// Called when the game starts or when spawned
void APickup::BeginPlay()
{
    Super::BeginPlay();
    
}

// Called every frame
void APickup::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

}

bool APickup::IsActive()
{
    return BIsActive;
}

void APickup::SetActive(bool NewPickUpState)
{
    BIsActive = NewPickUpState;
}

void APickup::WasCollected_Implementation(AActor* OtherActor)
{

    FString PickName = GetName();
    UE_LOG(LogTemp, Warning, TEXT("Name = %s"), *PickName);
    //Destroy();

    UE_LOG(LogTemp, Warning, TEXT("Trigger"));
    ASpawnerCharacter* CharRef = Cast<ASpawnerCharacter>(OtherActor);
    if (CharRef != nullptr)
    {
        switch (PickupTag)
        {
        case 1:
            CharRef->sizeDoubled();
            break;
        case 2:
            CharRef->sizeHalved();
            break;
        case 3:
            CharRef->speedDoubled();
            break;
        case 4:
            CharRef->speedHalved();
            break;
        }
    }
}

Pickup.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Pickup.generated.h"

UCLASS()
class SPAWNER_API APickup : public AActor
{
    GENERATED_BODY()
    
public: 
    // Sets default values for this actor's properties
    APickup();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public: 
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    UPROPERTY(EditAnywhere)
        class UStaticMeshComponent* VisibleComponent;

    UFUNCTION(BlueprintPure, Category = PickUp)
        bool IsActive();

    UFUNCTION(BlueprintCallable, Category = PickUp)
        void SetActive(bool NewPickUpState);

    UFUNCTION(BlueprintNativeEvent)
        void WasCollected(); // DONT CREATE

    UFUNCTION()
    virtual void WasCollected_Implementation(AActor* OtherActor);

    int32 pickType = 0;
    int Size2x = 0;
    int SizeHalf = 0;
    int Speed2x = 0;
    int SpeedHalf = 0;

    int PickupTag = 0;

protected:
    bool BIsActive;


};

SpawnerCharacter.cpp


#include "SpawnerCharacter.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/InputComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/Controller.h"
#include "GameFramework/SpringArmComponent.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"

#include "Spawner/Pickup.h"

#include "RunTime/CoreUObject/Public/UObject/ConstructorHelpers.h"
#include "Components/SkeletalMeshComponent.h"

#include "Engine/World.h"
#include "TimerManager.h"

#include "Components/SphereComponent.h"



//////////////////////////////////////////////////////////////////////////
// ASpawnerCharacter

ASpawnerCharacter::ASpawnerCharacter()
{
    // Set size for collision capsule
    GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
        
    // Don't rotate when the controller rotates. Let that just affect the camera.
    bUseControllerRotationPitch = false;
    bUseControllerRotationYaw = false;
    bUseControllerRotationRoll = false;

    // Configure character movement
    GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input...   
    GetCharacterMovement()->RotationRate = FRotator(0.0f, 500.0f, 0.0f); // ...at this rotation rate

    // Note: For faster iteration times these variables, and many more, can be tweaked in the Character Blueprint
    // instead of recompiling to adjust them
    GetCharacterMovement()->JumpZVelocity = 700.f;
    GetCharacterMovement()->AirControl = 0.35f;
    GetCharacterMovement()->MaxWalkSpeed = 500.f;
    GetCharacterMovement()->MinAnalogWalkSpeed = 20.f;
    GetCharacterMovement()->BrakingDecelerationWalking = 2000.f;

    // Create a camera boom (pulls in towards the player if there is a collision)
    CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
    CameraBoom->SetupAttachment(RootComponent);
    CameraBoom->TargetArmLength = 400.0f; // The camera follows at this distance behind the character   
    CameraBoom->bUsePawnControlRotation = true; // Rotate the arm based on the controller

    // Create a follow camera
    FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera"));
    FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation
    FollowCamera->bUsePawnControlRotation = false; // Camera does not rotate relative to arm

    // Note: The skeletal mesh and anim blueprint references on the Mesh component (inherited from Character) 
    // are set in the derived blueprint asset named ThirdPersonCharacter (to avoid direct content references in C++)

    //CREATE SPHERE COLLISION
    CollectionSphere = CreateDefaultSubobject<USphereComponent>(TEXT("CollectSphere"));
    CollectionSphere->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
    CollectionSphere->SetSphereRadius(110.f);

    //REFERENCE to material --->  press RightClick on Material -> CopyReference
    ///Script/Engine.Material'/Game/ThirdPerson/Materials/Blue.Blue'
    static ConstructorHelpers::FObjectFinder<UMaterialInterface>Blue(TEXT("/Game/ThirdPerson/Materials/Blue.Blue"));
    if (Blue.Succeeded())
    {
        Colors[0] = Blue.Object;
    }

    ///Script/Engine.Material'/Game/ThirdPerson/Materials/Red.Red'
    static ConstructorHelpers::FObjectFinder<UMaterialInterface>Red(TEXT("/Game/ThirdPerson/Materials/Red.Red"));
    if (Red.Succeeded())
    {
        Colors[1] = Red.Object;
    }

    ///Script/Engine.Material'/Game/ThirdPerson/Materials/Yellow.Yellow'
    static ConstructorHelpers::FObjectFinder<UMaterialInterface>Yellow(TEXT("/Game/ThirdPerson/Materials/Yellow.Yellow"));
    if (Yellow.Succeeded())
    {
        Colors[2] = Yellow.Object;
    }

    ///Script/Engine.Material'/Game/ThirdPerson/Materials/Green.Green'
    static ConstructorHelpers::FObjectFinder<UMaterialInterface>Green(TEXT("/Game/ThirdPerson/Materials/Green.Green"));
    if (Green.Succeeded())
    {
        Colors[3] = Green.Object;
    }
}

void ASpawnerCharacter::BeginPlay()
{
    // Call the base class  
    Super::BeginPlay();

    //Add Input Mapping Context
    if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
    {
        if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
        {
            Subsystem->AddMappingContext(DefaultMappingContext, 0);
        }
    }
}

void ASpawnerCharacter::CollectPickUp()
{

    TArray<AActor*>CollectedActors;
    CollectionSphere->GetOverlappingActors(CollectedActors);

    for (int32 iCollected = 0; iCollected < CollectedActors.Num(); ++iCollected)
    {
        
        APickup* const grabRef = Cast<APickup>(CollectedActors[iCollected]);
        if (grabRef)
        {
            grabRef->WasCollected();
            grabRef->SetActive(false);

            //change color  what, which color
            

            

            functionTimerStart();
        }
    }

}

void ASpawnerCharacter::functionTimerStart()
{
    UE_LOG(LogTemp, Warning, TEXT("TIME START"));
    //           Call Timer                TimerHandle                       FunctionToCall       TimeToCall If_Loop
    GetWorld()->GetTimerManager().SetTimer(myTimer, this, &ASpawnerCharacter::functionTimerEnd, 5, false);

}

void ASpawnerCharacter::functionTimerEnd()
{
    UE_LOG(LogTemp, Warning, TEXT("TIME END"));
}

void ASpawnerCharacter::SpeedUpFunc()
{
    //cout 
    UE_LOG(LogTemp, Warning, TEXT("Hello"));

    fNum += 1.5;
    //                 %d    %f   %s
    UE_LOG(LogTemp, Warning, TEXT("fnum = %f"), fNum);

    GetCharacterMovement()->MaxWalkSpeed = 700;

}

void ASpawnerCharacter::sizeDoubled()
{
    //GetMesh()->SetRelativeScale3D();
    GetMesh()->SetMaterial(0, Colors[0]);
}

void ASpawnerCharacter::sizeHalved()
{
    GetMesh()->SetMaterial(1, Colors[1]);
}

void ASpawnerCharacter::speedDoubled()
{
    speed = speed * 2;
    UE_LOG(LogTemp, Warning, TEXT("Speed = %d"), mySpeed);
    GetMesh()->SetMaterial(2, Colors[2]);
}

void ASpawnerCharacter::speedHalved()
{
    speed = speed / 2;
    UE_LOG(LogTemp, Warning, TEXT("Speed = %d"), mySpeed);
    GetMesh()->SetMaterial(3, Colors[3]);
}

//////////////////////////////////////////////////////////////////////////
// Input

void ASpawnerCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
    // Set up action bindings
    if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent)) {
        
        //Jumping
        EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ACharacter::Jump);
        EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping);

        //Moving
        EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &ASpawnerCharacter::Move);

        //Looking
        EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &ASpawnerCharacter::Look);

        //Speed
        EnhancedInputComponent->BindAction(SpeedAction, ETriggerEvent::Triggered, this, &ASpawnerCharacter::SpeedUpFunc);

        //COLLECT
        EnhancedInputComponent->BindAction(Collect, ETriggerEvent::Started, this, &ASpawnerCharacter::CollectPickUp);

    }

}

void ASpawnerCharacter::Move(const FInputActionValue& Value)
{
    // input is a Vector2D
    FVector2D MovementVector = Value.Get<FVector2D>();

    if (Controller != nullptr)
    {
        // find out which way is forward
        const FRotator Rotation = Controller->GetControlRotation();
        const FRotator YawRotation(0, Rotation.Yaw, 0);

        // get forward vector
        const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
    
        // get right vector 
        const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);

        // add movement 
        AddMovementInput(ForwardDirection, MovementVector.Y);
        AddMovementInput(RightDirection, MovementVector.X);
    }
}

void ASpawnerCharacter::Look(const FInputActionValue& Value)
{
    // input is a Vector2D
    FVector2D LookAxisVector = Value.Get<FVector2D>();

    if (Controller != nullptr)
    {
        // add yaw and pitch input to controller
        AddControllerYawInput(LookAxisVector.X);
        AddControllerPitchInput(LookAxisVector.Y);
    }
}

SpawnerCharacter.h

  #pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "InputActionValue.h"
#include "SpawnerCharacter.generated.h"


UCLASS(config=Game)
class ASpawnerCharacter : public ACharacter
{
    GENERATED_BODY()

    /** Camera boom positioning the camera behind the character */
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
    class USpringArmComponent* CameraBoom;

    /** Follow camera */
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
    class UCameraComponent* FollowCamera;
    
    /** MappingContext */
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
    class UInputMappingContext* DefaultMappingContext;

    /** Jump Input Action */
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
    class UInputAction* JumpAction;

    /** Move Input Action */
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
    class UInputAction* MoveAction;

    /** Look Input Action */
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
    class UInputAction* LookAction;

    /** Speed Up Action */
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
    class UInputAction* SpeedAction;

    /*Collect*/
    UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
        class UInputAction* Collect;

    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = PickUp, meta = (AllowPrivateAccess = "true"))
        class USphereComponent* CollectionSphere;


public:
    ASpawnerCharacter();
    

protected:

    /** Called for movement input */
    void Move(const FInputActionValue& Value);

    /** Called for looking input */
    void Look(const FInputActionValue& Value);
            

protected:
    // APawn interface
    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
    
    // To add mapping context
    virtual void BeginPlay();

    //collecting

public:
    /** Returns CameraBoom subobject **/
    FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
    /** Returns FollowCamera subobject **/
    FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; }


    UFUNCTION(BlueprintCallable, Category = PickUp)
        void CollectPickUp();

    UMaterialInterface* Colors[4]; //01

    FTimerHandle myTimer;

    void functionTimerStart();
    void functionTimerEnd();

    //not needed 
    void SpeedUpFunc();

    UPROPERTY(EditAnywhere)
        float fNum = 1.1;

    UPROPERTY(EditAnywhere,BlueprintReadWrite, Category = Material)
    int PickupTag = 0;

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
        int32 speed = 500;

    UPROPERTY(EditAnywhere, BlueprintReadWrite)
        int32 mySpeed = 0;

    void sizeDoubled();
    void sizeHalved();
    void speedDoubled();
    void speedHalved();
};

0

There are 0 answers