/**
* Handles attaching this controller to the specified pawn.
* Only runs on the network authority (where HasAuthority() returns true).
* Derived native classes can override OnPossess to filter the specified pawn.
* When possessed pawn changed, blueprint class gets notified by ReceivePossess
* and OnNewPawn delegate is broadcasted.
* @param InPawn The Pawn to be possessed.
* @see HasAuthority, OnPossess, ReceivePossess
*/
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Pawn, meta=(Keywords="set controller"))
virtual void Possess(APawn* InPawn) final; // DEPRECATED(4.22, "Possess is marked virtual final as you should now be overriding OnPossess instead")
void AController::Possess(APawn* InPawn)
{
if (!bCanPossessWithoutAuthority && !HasAuthority())
{
FMessageLog("PIE").Warning(FText::Format(
LOCTEXT("ControllerPossessAuthorityOnly", "Possess function should only be used by the network authority for {0}"),
FText::FromName(GetFName())
));
UE_LOG(LogController, Warning, TEXT("Trying to possess %s without network authority! Request will be ignored."), *GetNameSafe(InPawn));
return;
}
REDIRECT_OBJECT_TO_VLOG(InPawn, this);
APawn* CurrentPawn = GetPawn();
// A notification is required when the current assigned pawn is not possessed (i.e. pawn assigned before calling Possess)
const bool bNotificationRequired = (CurrentPawn != nullptr) && (CurrentPawn->GetController() == nullptr);
// To preserve backward compatibility we keep notifying derived classed for null pawn in case some
// overrides decided to react differently when asked to possess a null pawn.
// Default engine implementation is to unpossess the current pawn.
OnPossess(InPawn);
// Notify when pawn to possess (different than the assigned one) has been accepted by the native class or notification is explicitly required
APawn* NewPawn = GetPawn();
if ((NewPawn != CurrentPawn) || bNotificationRequired)
{
ReceivePossess(NewPawn);
OnNewPawn.Broadcast(NewPawn);
OnPossessedPawnChanged.Broadcast(bNotificationRequired ? nullptr : CurrentPawn, NewPawn);
}
TRACE_PAWN_POSSESS(this, InPawn);
}