How can I spawn Actors by setting their class values from one level to another?

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

This topic has been moved from International to Programming & Scripting.

When posting, please review the categories to ensure your topic is posted in the most relevant space. Hopefully, this new category will get you an answer.

In the meantime, good luck and happy developing! :slight_smile:

Solved , I’ve been digging for a whole week in the internet and I read that you cannot pass Class values through game instances , in this post Game instance lose object on "Open level" - #6 by kristian0049 . So I used strings to compare with the string values , from a for loop ,where I loop through an array of classes which contains the strings and assigned the matching class ,with that matching string , to spawn from that .