Hello , I have a Character Selection Level and I am trying to spawn the characters in my Combat Level after I make my selection and switch to the other Level using my own custom Player Controller to pass values through levels. However when I press the button to go to the other Level , nothing spawns . I tried the Game Instance , instead I get an exception error
this is my Player_Controller header :
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "Player_Controller.generated.h"
/**
*
*/
UCLASS()
class MOBILEGAME_API APlayer_Controller : public APlayerController
{
GENERATED_BODY()
protected:
//References to class for each character
TSubclassOf<APlayerCharacters> CharacterToSpawnOne;
TSubclassOf<APlayerCharacters> CharacterToSpawnTwo;
TSubclassOf<APlayerCharacters> CharacterToSpawnThree;
public:
APlayer_Controller();
//Get Player Characters
UFUNCTION(BlueprintCallable)
TSubclassOf<APlayerCharacters> GetCharacterOne()const { return CharacterToSpawnOne; };
UFUNCTION(BlueprintCallable)
TSubclassOf<APlayerCharacters> GetCharacterTwo()const { return CharacterToSpawnTwo; };
UFUNCTION(BlueprintCallable)
TSubclassOf<APlayerCharacters> GetCharacterThree()const { return CharacterToSpawnThree; };
//Set Player Characters
UFUNCTION(BlueprintCallable)
void SetCharacterOne(TSubclassOf<APlayerCharacters> _CharacterOne);
UFUNCTION(BlueprintCallable)
void SetCharacterTwo(TSubclassOf<APlayerCharacters> _CharacterTwo);
UFUNCTION(BlueprintCallable)
void SetCharacterThree(TSubclassOf<APlayerCharacters> _CharacterThree);
};
Game_Controller cpp :
#include "Player_Controller.h"
APlayer_Controller::APlayer_Controller()
{
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.bStartWithTickEnabled = true;
}
void APlayer_Controller::SetCharacterOne(TSubclassOf<APlayerCharacters> _CharacterOne)
{
CharacterToSpawnOne = _CharacterOne;
}
void APlayer_Controller::SetCharacterTwo(TSubclassOf<APlayerCharacters> _CharacterTwo)
{
CharacterToSpawnTwo = _CharacterTwo;
}
void APlayer_Controller::SetCharacterThree(TSubclassOf<APlayerCharacters> _CharacterThree)
{
CharacterToSpawnThree = _CharacterThree;
}
I use a Blueprint UI to set the values for the
This is a picture for setting up the reference on Event Construct
When I press one of the 3 buttons I set the value for the variables in the Player Controller.
I Used Print string to print the Class values from the Game Instance and they all seemed correct
The Compare Picked Character function:
After I switch the level my Characters don’t spawn I have added 3 spawn objects in the world:
The header for CharacterSpawner :
#include "GameFramework/Actor.h"
#include "CharacterSpawn.generated.h"
class APlayerCharacters;
class UArrowComponent;
class APlayerPawn;
UCLASS()
class MOBILEGAME_API ACharacterSpawn : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ACharacterSpawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
UArrowComponent* ArrowPointingForward;
UPROPERTY(EditAnywhere,BlueprintReadWrite)
TSubclassOf<APlayerCharacters> CharacterToSpawn;
UPROPERTY(BlueprintReadWrite)
APlayerCharacters* CharacterForThisSpawn;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
APlayerPawn* ParentOwner;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
/*UFUNCTION(BlueprintCallable)
void SpawnCharacter(TSubclassOf<APlayerCharacters> _CharacterToSpawn);*/
UFUNCTION(BlueprintCallable)
APlayerCharacters* SpawnCharacter(TSubclassOf<APlayerCharacters> _CharacterToSpawn);
APlayerCharacters* GetCharacterForThisSpawn()const { return CharacterForThisSpawn; };
};
The cpp of Character Spawner :
#include "CharacterSpawn.h"
#include "Components/ArrowComponent.h"
#include "PlayerCharacters.h"
#include "PlayerPawn.h"
#include "Kismet/GameplayStatics.h"
#include "Mobile_GameInstance.h"
// Sets default values
ACharacterSpawn::ACharacterSpawn()
{
// 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;
ArrowPointingForward = CreateDefaultSubobject<UArrowComponent>(TEXT("Arrow that shows forward direction"));
ArrowPointingForward->ArrowColor = FColor::White;
}
// Called when the game starts or when spawned
void ACharacterSpawn::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ACharacterSpawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
APlayerCharacters* ACharacterSpawn::SpawnCharacter(TSubclassOf<APlayerCharacters> _CharacterToSpawn)
{
FActorSpawnParameters Params;
Params.Owner = ParentOwner;
Params.bNoFail = true;
Params.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
if (_CharacterToSpawn != nullptr)
{
APlayerCharacters* ReturnCharacter = GetWorld()->SpawnActor<APlayerCharacters>(_CharacterToSpawn, GetActorLocation(), GetActorRotation(),Params );
return ReturnCharacter;
}
else {
GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("_CharacterToSpawn is null"));
return nullptr;
}
}```
I call the Spawn Characters Function from my Pawn Class
Pawn header :
#include “CoreMinimal.h”
#include “GameFramework/Pawn.h”
#include “PlayerPawn.generated.h”
class APlayerCharacters;
class ACharacterSpawn;
UCLASS()
class MOBILEGAME_API APlayerPawn : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn’s properties
APlayerPawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
//An array of Characters that the Player currently uses while in combat
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray<APlayerCharacters*>CombatPickedCharacters;
//Current pickedCharacter
UPROPERTY(EditAnywhere, BlueprintReadWrite)
APlayerCharacters* CurrentPickedCharacter;
//Pointers to Character Spawns
UPROPERTY(EditAnywhere, BlueprintReadWrite)
ACharacterSpawn* SpawnOne;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
ACharacterSpawn* SpawnTwo;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
ACharacterSpawn* SpawnThree;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
And the Pawn cpp:
#include “PlayerPawn.h”
#include “PlayerCharacters.h”
#include “Camera/CameraComponent.h”
#include “Blueprint/UserWidget.h”
#include “CharacterSpawn.h”
#include “Player_Controller.h”
#include “Kismet/GameplayStatics.h”
// Sets default values
APlayerPawn::APlayerPawn()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don’t need it.
PrimaryActorTick.bCanEverTick = true;
AutoPossessPlayer = EAutoReceiveInput::Player0;
Camera = CreateDefaultSubobject(“Camera”);
PlayerHUD = nullptr;
PlayerHUDClass = nullptr;
//Set Character Pointer to Spawned Characters
//Add UI to change spawn Character.
}
// Called when the game starts or when spawned
void APlayerPawn::BeginPlay()
{
Super::BeginPlay();
APlayer_Controller* PC = Cast<APlayer_Controller>(GetController());
if (GetLevel()->GetName() == "Combat_Level")
{
if (PC)
{
CombatPickedCharacters.Add(SpawnOne->SpawnCharacter(PC->GetCharacterOne()));
CombatPickedCharacters.Add(SpawnTwo->SpawnCharacter(PC->GetCharacterTwo()));
CombatPickedCharacters.Add(SpawnThree->SpawnCharacter(PC->GetCharacterThree()));
CurrentPickedCharacter = CombatPickedCharacters[0];
}
}
if (IsLocallyControlled() && PlayerHUDClass)
{
APlayerController* PCon = GetController<APlayerController>();
check(PCon);
PlayerHUD = CreateWidget<UUserWidget>(PCon, PlayerHUDClass);
check(PlayerHUD);
PlayerHUD->AddToPlayerScreen();
}
}
I've been banging my head around this from Monday to Saturday and still am :D