x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How to spawn a custom blueprint pawn from c++

Hello every one,

I have started some weeks ago a game project with unreal engine, learning how to use this engine and how achieve my objectives with it.

today I start to hit some trouble that I don't arrive to solve by my self.

before to speak about my trouble some background arround the project.

this project is based on twin stick template, I have handle to get it playable in multiplayer, after 1 week with the small base pawn of this template I have by a back of 7 low poly ship for this game, and created 7 blueprint ship for these one with a parent class in c++

i'm now handling the player spawn when he enter the arena I have success to made it with a temporary blueprint replacing my game mode, and a blueprint for the playerController, but i'm actually in progress to get these one in c++, and try to only use blueprint for my baseActor customisation with only some minimal logic in it.

now the trouble, on the Game mode blueprint I use handle starting player event to spawn a pawn for my player, based on the OptionString (color customisation, modele selection, weapon selection ...).

here the blueprint: https://blueprintue.com/blueprint/x9y8gd8d/

the collapsed node are just a spawn actor with some base property change (like hide the new player to other one until his first move) before to return the BasePawn

and there the cpp file of the gameMode to replace this one:

 #include "FreeForAllArenaGameMode.h"
 #include "ArenaPlayerController.h"
 #include "PawnShipBase.h"
 
 #include "Engine/World.h"
 #include "Kismet/GameplayStatics.h"
 
 void AFreeForAllArenaGameMode::HandleStartingNewPlayer_Implementation(APlayerController* NewPlayer)
 {
     UE_LOG(LogTemp, Warning, TEXT("processing New player"));
     // store player controler?
     AArenaPlayerController *ArenaPC = (AArenaPlayerController *) NewPlayer;
     ArenaPC->ShipType = StringToEnum(EShipType, UGameplayStatics::ParseOption(OptionsString, "Shiptype"));
     UWorld *World = GetWorld();
     APawnShipBase *ShipToSpawn = nullptr;
     UClass *ShipClass = nullptr;
     //TODO: switch is fine cause we have not a large list of ship do factory here? else create a private function to store it
     switch (ArenaPC->ShipType)
     {
     case EShipType::Harbinger:
         ShipToSpawn = FindObject<APawnShipBase>(ANY_PACKAGE, TEXT("/Game/Blueprints/ProjectName/Ship/BP_Harbinger.BP_Harbinger"));
         ShipClass = ShipToSpawn->StaticClass();
         break;
     case EShipType::Interceptor:
         ShipToSpawn = FindObject<APawnShipBase>(ANY_PACKAGE, TEXT("/Game/Blueprints/ProjectName/Ship/BP_Interceptor.BP_Interceptor"));
         ShipClass = ShipToSpawn->StaticClass();
         break;
     case EShipType::Icarus:
         ShipToSpawn = FindObject<APawnShipBase>(ANY_PACKAGE, TEXT("/Game/Blueprints/ProjectName/Ship/BP_Icarus.BP_Icarus"));
         ShipClass = ShipToSpawn->StaticClass();
         break;
     case EShipType::Avadora:
         ShipToSpawn = FindObject<APawnShipBase>(ANY_PACKAGE, TEXT("/Game/Blueprints/ProjectName/Ship/BP_Avadora.BP_Avadora"));
         ShipClass = ShipToSpawn->StaticClass();
         break;
     case EShipType::ThunderStorm:
         ShipToSpawn = FindObject<APawnShipBase>(ANY_PACKAGE, TEXT("/Game/Blueprints/ProjectName/Ship/BP_ThunderStorm.BP_ThunderStorm"));
         ShipClass = ShipToSpawn->StaticClass();
         break;
     case EShipType::Praetor:
         ShipToSpawn = FindObject<APawnShipBase>(ANY_PACKAGE, TEXT("/Game/Blueprints/ProjectName/Ship/BP_Praetor.BP_Praetor"));
         ShipClass = ShipToSpawn->StaticClass();
         break;
     case EShipType::Vanquisher:
     default:
         ShipToSpawn = FindObject<APawnShipBase>(ANY_PACKAGE, TEXT("/Game/Blueprints/ProjectName/Ship/BP_Vanquisher.BP_Vanquisher"));
         ShipClass = ShipToSpawn->StaticClass();
         break;
     }
     AActor *SpawnPoint = FindPlayerStart(ArenaPC);
     //APawnShipBase* pShip = GetWorld()->SpawnActorDeferred<APawnShipBase>(ShipClass, FTransform(FRotator(0, 0, 0), SpawnPoint->GetActorLocation()));
     APawnShipBase* pShip = Cast<APawnShipBase>(UGameplayStatics::BeginDeferredActorSpawnFromClass(ArenaPC, ShipClass, FTransform(FRotator(0, 0, 0), SpawnPoint->GetActorLocation())));
     if (pShip != nullptr) {
         //set color from option here
         pShip->BaseColor.InitFromString(UGameplayStatics::ParseOption(OptionsString, "PrimaryColor"));
         pShip->AdditionalColor.InitFromString(UGameplayStatics::ParseOption(OptionsString, "AdditionalColor"));
         pShip->WindshieldColor.InitFromString(UGameplayStatics::ParseOption(OptionsString, "WindshieldColor"));
         pShip->EnginesColor.InitFromString(UGameplayStatics::ParseOption(OptionsString, "EnginesColor"));
         pShip->WeaponsColor.InitFromString(UGameplayStatics::ParseOption(OptionsString, "WeaponsColor"));
         pShip->JetGlowColor.InitFromString(UGameplayStatics::ParseOption(OptionsString, "JetGlowColor"));
         UGameplayStatics::FinishSpawningActor(pShip, FTransform(FRotator(0, 0, 0), SpawnPoint->GetActorLocation()));
         ArenaPC->Possess(pShip);
     }
 }
 
 // TODO: event begin play must be call here and init AI (cf GM_FreeForAllArena BP)

my trouble with this way is my BP_pawn constructor are not call, and I have to init some materials on the ship (custom colors), the material binding is not exactly the same on each ship so I can't setup it in my BaseShip, I'm in search of a way to do it (the ship selection is made from an other level dedicated to the ship customisation.

if some one got a way to achieve it I will be happy to read it.

Product Version: UE 4.21
Tags:
more ▼

asked Mar 13 '19 at 10:12 PM in C++ Programming

avatar image

Guss42
1 1 2

avatar image Guss42 Mar 15 '19 at 01:12 PM

hello again, after some time to search, I'm always blocking on this point, every try I made always result on spawn my PawnShipBase instead of the blueprints version... I really don't know how to deal with it.

(comments are locked)
10|2000 characters needed characters left

3 answers: sort voted first

Problem solved with:

 ShipClass = LoadObject<UBlueprint>(nullptr, TEXT("/Game/Blueprints/ProjectName/Ship/BP_Vanquisher.BP_Vanquisher"))->GeneratedClass;


in the switch to load asset dynamically ;)

more ▼

answered Mar 16 '19 at 12:08 PM

avatar image

Guss42
1 1 2

(comments are locked)
10|2000 characters needed characters left

Hi Guss42,

Here is how I spawn a blueprint pawn class from C++.

Inside the constructor, I load the blueprint pawn class :

 static ConstructorHelpers::FObjectFinder<UClass> PawnObject(TEXT("Class'/Game/Characters/Blueprints/BP_Pawn.BP_Pawn_C'"));
 PawnClass = PawnObject.Object; // TSubclassOf<class APAwn> PawnClass; is declared in my class' header.

Note that the reference of the resource has to end with a "_C".

Now inside the function executed server-side that spawns the pawn, I do as follows :

 FActorSpawnParameters SpawnInfo;
 APawn * pawn = GetWorld()->SpawnActor<APawn>(PawnClass, playerStart->GetActorLocation(), playerStart->GetActorRotation(), SpawnInfo);

Hope it helps!

Cheers.

more ▼

answered Mar 16 '19 at 01:30 AM

avatar image

Elou44
179 3 9 7

avatar image Guss42 Mar 16 '19 at 03:29 AM

as I will add many more ship in future I don't think load them all is a good idea but thanks, I now Use LoadObject instead of FindObject, fetching derectly the class in ship class and it's start to be good I have now to rewrite some part of my BP to instantiate my materials on eventBeginPlay instead of BP constructor (as the constructor is call just before colour customisation).

but thanks to you for your reply ;)

avatar image Elou44 Mar 16 '19 at 12:44 PM

Well, I believe that loading an asset via its path (with LoadObject or FObjectFinder) is an expensive operation. That’s why I would advice against using it in your spawning function (that I guess will be called many times when your game is played). In my case I load the asset reference only once in the constructor of the class handling the spawn (e.g. AGameMode). Cheers

avatar image Guss42 Mar 16 '19 at 12:48 PM

I don't really know when to lazy load or preload asset, but this finction is called once on player connection to the arena, so I think it's fine and if my available ship pool grow I must be able to load only one. I think it's a good case to use it

thanks for your answers, I really apreciate your try to help ;)

avatar image Elou44 Mar 16 '19 at 12:59 PM

I would add a new class member : TMap<EShipType, UClass*> ShipClasses and I would populate it inside the constructor class.

avatar image Guss42 Mar 16 '19 at 01:04 PM

I will take a look to this advice, and look to bench the difference between the 2 way :)

(comments are locked)
10|2000 characters needed characters left

Problem solved with:

 ShipClass = LoadObject<UBlueprint>(nullptr, TEXT("/Game/Blueprints/ProjectName/Ship/BP_Vanquisher.BP_Vanquisher"))->GeneratedClass;


in the switch to load asset dynamically ;)

more ▼

answered Mar 16 '19 at 12:08 PM

avatar image

Guss42
1 1 2

(comments are locked)
10|2000 characters needed characters left
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question