当前位置:网站首页>UE small knowledge point controller possess pawn process
UE small knowledge point controller possess pawn process
2022-07-01 09:25:00 【[ascetic monk]】
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);
const 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);
}
}
void APlayerController::OnPossess(APawn* PawnToPossess)
{
if ( PawnToPossess != NULL &&
(PlayerState == NULL || !PlayerState->IsOnlyASpectator()) )
{
const bool bNewPawn = (GetPawn() != PawnToPossess);
if (GetPawn() && bNewPawn)
{
UnPossess();
}
if (PawnToPossess->Controller != NULL)
{
PawnToPossess->Controller->UnPossess();
}
PawnToPossess->PossessedBy(this);
// update rotation to match possessed pawn's rotation
SetControlRotation( PawnToPossess->GetActorRotation() );
SetPawn(PawnToPossess);
check(GetPawn() != NULL);
if (GetPawn() && GetPawn()->PrimaryActorTick.bStartWithTickEnabled)
{
GetPawn()->SetActorTickEnabled(true);
}
INetworkPredictionInterface* NetworkPredictionInterface = GetPawn() ? Cast<INetworkPredictionInterface>(GetPawn()->GetMovementComponent()) : NULL;
if (NetworkPredictionInterface)
{
NetworkPredictionInterface->ResetPredictionData_Server();
}
AcknowledgedPawn = NULL;
// Local PCs will have the Restart() triggered right away in ClientRestart (via PawnClientRestart()), but the server should call Restart() locally for remote PCs.
// We're really just trying to avoid calling Restart() multiple times.
if (!IsLocalPlayerController())
{
GetPawn()->DispatchRestart(false);
}
ClientRestart(GetPawn());
ChangeState( NAME_Playing );
if (bAutoManageActiveCameraTarget)
{
AutoManageActiveCameraTarget(GetPawn());
ResetCameraMode();
}
}
}
void AController::UnPossess()
{
APawn* CurrentPawn = GetPawn();
// No need to notify if we don't have a pawn
if (CurrentPawn == nullptr)
{
return;
}
OnUnPossess();
// Notify only when pawn has been successfully unpossessed by the native class.
APawn* NewPawn = GetPawn();
if (NewPawn != CurrentPawn)
{
ReceiveUnPossess(CurrentPawn);
OnNewPawn.Broadcast(NewPawn);
}
}
void APlayerController::OnUnPossess()
{
if (GetPawn() != NULL)
{
if (GetLocalRole() == ROLE_Authority)
{
GetPawn()->SetReplicates(true);
}
GetPawn()->UnPossessed();
if (GetViewTarget() == GetPawn())
{
SetViewTarget(this);
}
}
SetPawn(NULL);
}
void APawn::UnPossessed()
{
AController* const OldController = Controller;
ForceNetUpdate();
SetPlayerState(nullptr);
SetOwner(nullptr);
Controller = nullptr;
// Unregister input component if we created one
DestroyPlayerInputComponent();
// dispatch Blueprint event if necessary
if (OldController)
{
ReceiveUnpossessed(OldController);
}
NotifyControllerChanged();
ConsumeMovementInputVector();
}
void ACharacter::UnPossessed()
{
Super::UnPossessed();
if (CharacterMovement)
{
CharacterMovement->ResetPredictionData_Client();
CharacterMovement->ResetPredictionData_Server();
}
// We're no longer controlled remotely, resume regular ticking of animations.
if (Mesh)
{
Mesh->bOnlyAllowAutonomousTickPose = false;
}
}
void APawn::PossessedBy(AController* NewController)
{
SetOwner(NewController);
AController* const OldController = Controller;
Controller = NewController;
ForceNetUpdate();
if (Controller->PlayerState != nullptr)
{
SetPlayerState(Controller->PlayerState);
}
if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
{
if (GetNetMode() != NM_Standalone)
{
SetReplicates(true);
SetAutonomousProxy(true);
}
}
else
{
CopyRemoteRoleFrom(GetDefault<APawn>());
}
// dispatch Blueprint event if necessary
if (OldController != NewController)
{
ReceivePossessed(Controller);
NotifyControllerChanged();
}
}
void APlayerController::ClientRestart_Implementation(APawn* NewPawn)
{
UE_LOG(LogPlayerController, Verbose, TEXT("ClientRestart_Implementation %s"), *GetNameSafe(NewPawn));
ResetIgnoreInputFlags();
AcknowledgedPawn = NULL;
SetPawn(NewPawn);
if ( (GetPawn() != NULL) && GetPawn()->GetTearOff() )
{
UnPossess();
SetPawn(NULL);
AcknowledgePossession(GetPawn());
return;
}
if ( GetPawn() == NULL )
{
// We failed to possess, ask server to verify and potentially resend the pawn
ServerCheckClientPossessionReliable();
return;
}
// Only acknowledge non-null Pawns here. ClientRestart is only ever called by the Server for valid pawns,
// but we may receive the function call before Pawn is replicated over, so it will resolve to NULL.
AcknowledgePossession(GetPawn());
GetPawn()->Controller = this;
GetPawn()->DispatchRestart(true);
if (GetLocalRole() < ROLE_Authority)
{
ChangeState( NAME_Playing );
if (bAutoManageActiveCameraTarget)
{
AutoManageActiveCameraTarget(GetPawn());
ResetCameraMode();
}
}
}
void APlayerController::AcknowledgePossession(APawn* P)
{
if (Cast<ULocalPlayer>(Player) != NULL)
{
AcknowledgedPawn = P;
if (P != NULL)
{
P->RecalculateBaseEyeHeight();
}
ServerAcknowledgePossession(P);
}
}
边栏推荐
- dsPIC30F6014a LCD 方块显示
- I use flask to write the website "one"
- Network counting 01 physical layer
- SDN_简单总结
- Bird recognition app
- In the middle of the year, where should fixed asset management go?
- Can diffusion models be regarded as an autoencoder?
- SQL学习笔记(04)——数据更新、查询操作
- Phishing identification app
- Which method is good for the management of fixed assets of small and medium-sized enterprises?
猜你喜欢
Jetson nano installs tensorflow GPU and problem solving
[video game training] real topic of 2013 video game of infrared optical communication device
nacos簡易實現負載均衡
MySQL optimization
Error org apache. catalina. core. StandardContext. FilterStart start filter exception
NoSQL数据库的安装和使用
JS scope chain and closure
Reproduced Xray - cve-2017-7921 (unauthorized access by Hikvision)
MapReduce programming basics
【电赛训练】红外光通信装置 2013年电赛真题
随机推荐
Exception handling of classes in C #
SDN_简单总结
Can diffusion models be regarded as an autoencoder?
How to realize the usage of connecting multiple databases in idel
Key points of NFT supervision and overseas policies
Using closures to implement private variables
js valueOf 与 toString 区别
樹結構---二叉樹2非遞歸遍曆
2.2 【pytorch】torchvision.transforms
2.3 [pytorch] data preprocessing torchvision datasets. ImageFolder
Nacos service configuration and persistence configuration
[pytorch learning] torch device
Understanding and implementation of AVL tree
Rich text interpolation
计网01-物理层
Problems caused by delete and delete[]
How to effectively align team cognition
Weidongshan board compilation kernel problem solving
【ESP 保姆级教程】疯狂毕设篇 —— 案例:基于阿里云、小程序、Arduino的WS2812灯控系统
I use flask to write the website "one"