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"

Office Holiday

Epic Games' offices will be on holiday from June 22nd to July 7th. During this period support will be limited. Our offices will reopen on Monday, July 8th. 

[Closed] How can I resolve ChoosePlayerStart(AController* Player) Player is NULL?

Hi! When I try to override ChoosePlayerStart(AController* Player) in my custom game mode, the Player pointer passed has value NULL. I would need to know which player it is in order to choose the correct PlayerStart. Why is this happening and how can I solve it?

Product Version: Not Selected
Tags:
more ▼

asked Apr 21 '14 at 04:57 PM in C++ Programming

avatar image

undercover
843 123 111 138

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

The question has been closed Jun 17 '14 at 04:47 PM by undercover for the following reason:

The question is answered, right answer was accepted


2 answers: sort voted first

Look on source code suggest it is possible that this function might get null pointer

https://github.com/EpicGames/UnrealEngine/blob/7fdf681ee21b111524848ade9e952de3ad3fa1ac/Engine/Source/Runtime/Engine/Private/GameMode.cpp#L334

And give this warning if both playercontroller and return from ChoosePlayerStart will be null "Warning - PATHS NOT DEFINED or NO PLAYERSTART with positive rating"

Maybe try to "if" it out if that happens and return null, i didnt analize possibilities deply but maybe you might got another call with controller. You would need to debug call stack to check what really sends then null and to debug that you need engine call symbols (pdb files) which you can get by compiling the engine.

more ▼

answered Apr 21 '14 at 05:58 PM

avatar image

Shadowriver
36.6k 930 169 1111

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

I am also interested in an answer to this question, it seems to be the case at least when the player is first started in the GameMode, not sure if the NewPlayer is null in the match flow when it calls RestartPlayer(AController* NewPlayer) yet.

either way, i found a workaround.

its hackish, but it has gotten me the functionality i wanted and if you haven't found a solution yet, it should work for you as well. you seemz to got the skillz to do this just by description, but in case any n00bs find this post later, i will be explicit for posterity.

put this in your GameMode header:

             /** spawns default pawn for player*/
                 virtual APawn* SpawnDefaultPawnFor(AController* NewPlayer, class AActor* StartSpot) OVERRIDE;
         
     /** hack to select teamspawn, due to null controller passed to ChoosePlayerStart by engine*/
         AActor* GetTeamStart(AYourPlayerController* Player);
 

then when you override it in your GameMode CPP, check it:

  APawn* AYourGameMode::SpawnDefaultPawnFor(AController* NewPlayer, class AActor* StartSpot)
     {
     //choose the player start location based on player start's PlayerStartTag
     FRotator StartRotation(ForceInit);
     FVector StartLocation;
     AActor* TeamStart;
     
     FActorSpawnParameters SpawnInfo;
     SpawnInfo.Instigator = Instigator;
     APawn* ResultPawn;
     
     //newplayer is not null here.
     AYourPlayerController* PCOwner = Cast<AYourPlayerController>(NewPlayer);
     // team information stored in playerstate.
     AYourPlayerState* PSOwner = CastChecked<AYourPlayerState>(NewPlayer->PlayerState);
     
     TeamStart = GetTeamStart(PCOwner);
     
     if(TeamStart == NULL) // if assignment failed, use default.
     {
     TeamStart = StartSpot;
     }
     
     StartRotation.Yaw = TeamStart->GetActorRotation.Yaw;
     StartLocation = TeamStart->GetActorLocation();
     
     ResultPawn = GetWorld()->SpawnActor<APawn>(GetDefaultPawnClassForController(NewPlayer), StartLocation, StartRotation, SpawnInfo);
             return ResultPawn;
     }



and lastly, the GetTeamStart function, which populates the arrays with teamstarts based on their player start tag, which can be edited in the Unreal Editor by clicking on the player start in the viewport and changing the object in the "details" section that says "Player Start Tag"

    AActor* AYourGameMode::GetTeamStart(AYourPlayerController* Player)
     {
 //Arrays to hold the starts for each team
 TArray<APlayerStart*> Team1Starts;
 TArray<APlayerStart*> Team2Starts;
 
         FString Team1STag = "Team1Start";
         FString Team2STag = "Team2Start";
         
         FName Team1Tag = FName(*Team1STag);
         FName Team2Tag = FName(*Team2STag);
         
         
         for (int i = 0; i < PlayerStarts.Num(); i++)
         {
             if (PlayerStarts[i]->PlayerStartTag == Team1Tag)
             {
                 Team1Starts.Add(PlayerStarts[i]);
             }
             else if (PlayerStarts[i]->PlayerStartTag == Team2Tag)
             {
                 Team2Starts.Add(PlayerStarts[i]);
             }
         }
     
         AActor* TeamStart = NULL;
         if (Player)
         {
             AYourPlayerState* PState = CastChecked<AYourPlayerState>(Player->PlayerState);
             if (PState)
             {
                 if (PState->GetTeamNum() == 1)
                 {
                     TeamStart = Team1Starts[FMath::RandHelper(Team1Starts.Num())];
                 }
                 else if (PState->GetTeamNum() == 2)
                 {
                     TeamStart = Team2Starts[FMath::RandHelper(Team2Starts.Num())];
                 }
             }
         }
     
         return TeamStart;
     }

 

of course, this assumes that you have already assigned your teams in your PlayerStates, and have added a "GetTeamNum()" function to them, hope this helps SOMEONE out at some point.i would love a more elegant solution to this.

more ▼

answered Jun 15 '14 at 11:08 AM

avatar image

CUTIEPIE
61 7 7 9

avatar image certifiedDoc Oct 20 '15 at 08:58 PM

This compiled for you? Which engine version was this built with? Currently (UE 4.9), SpawnDefaultPawnFor() is not a virtual function and cannot be overridden in this manner.

avatar image Shadowriver Oct 20 '15 at 09:04 PM

Is not virtual to prevent override of generated code needed to use it in blueprint since version 4.8, as lot of GameMode functions was given BlueprintNativeEvent specifier and all functions with actual code of it need to be placed in function with *_Implementation surrfix, so in this case SpawnDefaultPawnFor_Implementation() and you do override here too

avatar image TheGreatCabbage Jun 30 '17 at 02:35 PM

Thank you, using this works perfectly: virtual AActor* ChoosePlayerStart_Implementation(AController* Player) override;

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

Follow this question

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

Answers to this question