当前位置:网站首页>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);
}
}边栏推荐
- Rich text interpolation
- 队列的实现和应用
- Principles of Microcomputer - Introduction
- Win7 pyinstaller reports an error DLL load failed while importing after packaging exe_ Socket: parameter error
- 樹結構---二叉樹2非遞歸遍曆
- How to realize the usage of connecting multiple databases in idel
- 韦东山板子编译内核问题解决
- 2022.02.15_ Daily question leetcode six hundred and ninety
- PR training notes
- 微信小程序 webview 禁止页面滚动,同时又不影响业务内overflow的滚动的实现方式
猜你喜欢

计网01-物理层

An overview of the design of royalties and service fees of mainstream NFT market platforms
![delete和delete[]引发的问题](/img/d9/a1c3e5ce51ef1be366a973aa42d1f0.png)
delete和delete[]引发的问题

Mise en œuvre simple de l'équilibrage de la charge par nacos

2.2 【pytorch】torchvision. transforms

Why is the Ltd independent station a Web3.0 website!

nacos简易实现负载均衡

Principles of Microcomputer - Introduction

ESP8266 FreeRTOS开发环境搭建

How to manage fixed assets well? Easy to point and move to provide intelligent solutions
随机推荐
SQL学习笔记(04)——数据更新、查询操作
NoSQL数据库的安装和使用
OSPF - virtual link details (including configuration commands)
Serialization, listening, custom annotation
delete和delete[]引发的问题
Dspic30f6014a LCD block display
Niuke monthly race 22- collect pieces of paper
Mysql8.0 learning record 17 -create table
PR training notes
Problems caused by delete and delete[]
Weidongshan board compilation kernel problem solving
Set the type of the input tag to number, and remove the up and down arrows
Solution of EPS image blur by latex insertion
The fixed assets management system enables enterprises to dynamically master assets
Record a redis timeout
js函数arguments对象
LeetCode 344. Reverse string
Redis -- lattice connects to redis cluster
Nacos service configuration and persistence configuration
JS scope chain and closure