Advertisement
Guest User

Untitled

a guest
Sep 4th, 2018
3,293
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 149.23 KB | None | 0 0
  1. // Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
  2.  
  3. #include "GameFramework/PlayerController.h"
  4. #include "Misc/PackageName.h"
  5. #include "UObject/LinkerLoad.h"
  6. #include "EngineGlobals.h"
  7. #include "TimerManager.h"
  8. #include "Widgets/DeclarativeSyntaxSupport.h"
  9. #include "CollisionQueryParams.h"
  10. #include "Engine/World.h"
  11. #include "SceneView.h"
  12. #include "Components/PrimitiveComponent.h"
  13. #include "Camera/CameraActor.h"
  14. #include "UObject/Package.h"
  15. #include "Engine/Canvas.h"
  16. #include "GameFramework/GameModeBase.h"
  17. #include "GameFramework/PlayerStart.h"
  18. #include "Components/SkeletalMeshComponent.h"
  19. #include "Components/AudioComponent.h"
  20. #include "Components/ForceFeedbackComponent.h"
  21. #include "Kismet/GameplayStatics.h"
  22. #include "LatentActions.h"
  23. #include "Engine/Engine.h"
  24. #include "Engine/LevelStreaming.h"
  25. #include "Engine/LocalPlayer.h"
  26. #include "Engine/NetConnection.h"
  27. #include "ContentStreaming.h"
  28. #include "DrawDebugHelpers.h"
  29. #include "EngineUtils.h"
  30. #include "Framework/Application/SlateApplication.h"
  31. #include "Widgets/SViewport.h"
  32. #include "Engine/Console.h"
  33. #include "Net/UnrealNetwork.h"
  34. #include "Engine/WorldComposition.h"
  35. #include "Engine/LevelScriptActor.h"
  36. #include "GameFramework/GameNetworkManager.h"
  37. #include "Interfaces/NetworkPredictionInterface.h"
  38. #include "Net/OnlineEngineInterface.h"
  39. #include "GameFramework/OnlineSession.h"
  40. #include "IHeadMountedDisplay.h"
  41. #include "IXRTrackingSystem.h"
  42. #include "IXRCamera.h"
  43. #include "IXRInput.h"
  44. #include "GameFramework/TouchInterface.h"
  45. #include "DisplayDebugHelpers.h"
  46. #include "Matinee/InterpTrackInstDirector.h"
  47. #include "Matinee/MatineeActor.h"
  48. #include "Engine/ActorChannel.h"
  49. #include "GameFramework/PawnMovementComponent.h"
  50. #include "GameFramework/SpectatorPawn.h"
  51. #include "GameFramework/HUD.h"
  52. #include "Engine/InputDelegateBinding.h"
  53. #include "Widgets/Input/SVirtualJoystick.h"
  54. #include "GameFramework/LocalMessage.h"
  55. #include "GameFramework/CheatManager.h"
  56. #include "GameFramework/PlayerInput.h"
  57. #include "GameFramework/InputSettings.h"
  58. #include "GameFramework/PlayerState.h"
  59. #include "GameFramework/GameStateBase.h"
  60. #include "Haptics/HapticFeedbackEffect_Base.h"
  61. #include "Engine/ChildConnection.h"
  62. #include "VisualLogger/VisualLogger.h"
  63. #include "Logging/MessageLog.h"
  64. #include "Slate/SceneViewport.h"
  65. #include "Engine/NetworkObjectList.h"
  66. #include "GameFramework/GameSession.h"
  67. #include "GameMapsSettings.h"
  68.  
  69. DEFINE_LOG_CATEGORY(LogPlayerController);
  70.  
  71. #define LOCTEXT_NAMESPACE "PlayerController"
  72.  
  73. DECLARE_CYCLE_STAT(TEXT("PC Tick Actor"), STAT_PC_TickActor, STATGROUP_PlayerController);
  74. DECLARE_CYCLE_STAT(TEXT(" PC Tick Input"), STAT_PC_TickInput, STATGROUP_PlayerController);
  75. DECLARE_CYCLE_STAT(TEXT(" PC Build Input Stack"), STAT_PC_BuildInputStack, STATGROUP_PlayerController);
  76. DECLARE_CYCLE_STAT(TEXT(" PC Process Input Stack"), STAT_PC_ProcessInputStack, STATGROUP_PlayerController);
  77.  
  78.  
  79. const float RetryClientRestartThrottleTime = 0.5f;
  80. const float RetryServerAcknowledgeThrottleTime = 0.25f;
  81. const float RetryServerCheckSpectatorThrottleTime = 0.25f;
  82.  
  83. // Note: This value should be sufficiently small such that it is considered to be in the past before RetryClientRestartThrottleTime and RetryServerAcknowledgeThrottleTime.
  84. const float ForceRetryClientRestartTime = -100.0f;
  85.  
  86. //////////////////////////////////////////////////////////////////////////
  87. // APlayerController
  88.  
  89. APlayerController::APlayerController(const FObjectInitializer& ObjectInitializer)
  90. : Super(ObjectInitializer)
  91. {
  92. NetPriority = 3.0f;
  93. CheatClass = UCheatManager::StaticClass();
  94. ClientCap = 0;
  95. LocalPlayerCachedLODDistanceFactor = 1.0f;
  96. bIsUsingStreamingVolumes = true;
  97. PrimaryActorTick.TickGroup = TG_PrePhysics;
  98. PrimaryActorTick.bTickEvenWhenPaused = true;
  99. bAllowTickBeforeBeginPlay = true;
  100. bShouldPerformFullTickWhenPaused = false;
  101. LastRetryPlayerTime = ForceRetryClientRestartTime;
  102. DefaultMouseCursor = EMouseCursor::Default;
  103. DefaultClickTraceChannel = ECollisionChannel::ECC_Visibility;
  104. HitResultTraceDistance = 100000.f;
  105.  
  106. bCinemaDisableInputMove = false;
  107. bCinemaDisableInputLook = false;
  108.  
  109. bInputEnabled = true;
  110. bEnableTouchEvents = true;
  111. bForceFeedbackEnabled = true;
  112. ForceFeedbackScale = 1.f;
  113.  
  114. bAutoManageActiveCameraTarget = true;
  115. bRenderPrimitiveComponents = true;
  116. SmoothTargetViewRotationSpeed = 20.f;
  117. bHidePawnInCinematicMode = false;
  118.  
  119. bIsPlayerController = true;
  120. bIsLocalPlayerController = false;
  121. bDisableHaptics = false;
  122.  
  123. ClickEventKeys.Add(EKeys::LeftMouseButton);
  124.  
  125. if (RootComponent)
  126. {
  127. // We want to drive rotation with ControlRotation regardless of attachment state.
  128. RootComponent->bAbsoluteRotation = true;
  129. }
  130. }
  131.  
  132. float APlayerController::GetNetPriority(const FVector& ViewPos, const FVector& ViewDir, AActor* Viewer, AActor* ViewTarget, UActorChannel* InChannel, float Time, bool bLowBandwidth)
  133. {
  134. if ( Viewer == this )
  135. {
  136. Time *= 4.f;
  137. }
  138. return NetPriority * Time;
  139. }
  140.  
  141. const AActor* APlayerController::GetNetOwner() const
  142. {
  143. return this;
  144. }
  145.  
  146. UPlayer* APlayerController::GetNetOwningPlayer()
  147. {
  148. return Player;
  149. }
  150.  
  151. bool APlayerController::HasNetOwner() const
  152. {
  153. // Player controllers are their own net owners
  154. return true;
  155. }
  156.  
  157. UNetConnection* APlayerController::GetNetConnection() const
  158. {
  159. // A controller without a player has no "owner"
  160. return (Player != NULL) ? NetConnection : NULL;
  161. }
  162.  
  163. bool APlayerController::DestroyNetworkActorHandled()
  164. {
  165. UNetConnection* C = Cast<UNetConnection>(Player);
  166. if (C)
  167. {
  168. if (C->Channels[0] && C->State != USOCK_Closed)
  169. {
  170. C->bPendingDestroy = true;
  171. C->Channels[0]->Close();
  172. }
  173. return true;
  174. }
  175.  
  176. return false;
  177. }
  178.  
  179. bool APlayerController::IsLocalController() const
  180. {
  181. // Never local on dedicated server. IsServerOnly() is checked at compile time and optimized out appropriately.
  182. if (FPlatformProperties::IsServerOnly())
  183. {
  184. checkSlow(!bIsLocalPlayerController);
  185. return false;
  186. }
  187.  
  188. // Fast path if we have this bool set.
  189. if (bIsLocalPlayerController)
  190. {
  191. return true;
  192. }
  193.  
  194. ENetMode NetMode = GetNetMode();
  195. if (NetMode == NM_DedicatedServer)
  196. {
  197. // This is still checked for the PIE case, which would not be caught in the IsServerOnly() check above.
  198. checkSlow(!bIsLocalPlayerController);
  199. return false;
  200. }
  201.  
  202. if (NetMode == NM_Client || NetMode == NM_Standalone)
  203. {
  204. // Clients or Standalone only receive their own PC. We are not ROLE_AutonomousProxy until after PostInitializeComponents so we can't check that.
  205. bIsLocalPlayerController = true;
  206. return true;
  207. }
  208.  
  209. return bIsLocalPlayerController;
  210. }
  211.  
  212.  
  213. void APlayerController::FailedToSpawnPawn()
  214. {
  215. Super::FailedToSpawnPawn();
  216. ChangeState(NAME_Inactive);
  217. ClientGotoState(NAME_Inactive);
  218. }
  219.  
  220. FName APlayerController::NetworkRemapPath(FName InPackageName, bool bReading)
  221. {
  222. // For PIE Networking: remap the packagename to our local PIE packagename
  223. FString PackageNameStr = InPackageName.ToString();
  224. GEngine->NetworkRemapPath(GetNetDriver(), PackageNameStr, bReading);
  225. return FName(*PackageNameStr);
  226. }
  227.  
  228. /// @cond DOXYGEN_WARNINGS
  229.  
  230. void APlayerController::ClientUpdateLevelStreamingStatus_Implementation(FName PackageName, bool bNewShouldBeLoaded, bool bNewShouldBeVisible, bool bNewShouldBlockOnLoad, int32 LODIndex )
  231. {
  232. PackageName = NetworkRemapPath(PackageName, true);
  233.  
  234. UWorld* World = GetWorld();
  235.  
  236. // Distance dependent streaming levels should be controlled by client only
  237. if (World && World->WorldComposition)
  238. {
  239. if (World->WorldComposition->IsDistanceDependentLevel(PackageName))
  240. {
  241. return;
  242. }
  243. }
  244.  
  245. // if we're about to commit a map change, we assume that the streaming update is based on the to be loaded map and so defer it until that is complete
  246. if (GEngine->ShouldCommitPendingMapChange(World))
  247. {
  248. GEngine->AddNewPendingStreamingLevel(World, PackageName, bNewShouldBeLoaded, bNewShouldBeVisible, LODIndex);
  249. }
  250. else
  251. {
  252. // search for the level object by name
  253. ULevelStreaming* LevelStreamingObject = nullptr;
  254. if (World && PackageName != NAME_None)
  255. {
  256. for (ULevelStreaming* CurrentLevelStreamingObject : World->GetStreamingLevels())
  257. {
  258. if (CurrentLevelStreamingObject && CurrentLevelStreamingObject->GetWorldAssetPackageFName() == PackageName)
  259. {
  260. LevelStreamingObject = CurrentLevelStreamingObject;
  261. if (LevelStreamingObject)
  262. {
  263. // If we're unloading any levels, we need to request a one frame delay of garbage collection to make sure it happens after the level is actually unloaded
  264. if (LevelStreamingObject->ShouldBeLoaded() && !bNewShouldBeLoaded)
  265. {
  266. GEngine->DelayGarbageCollection();
  267. }
  268.  
  269. LevelStreamingObject->SetShouldBeLoaded(bNewShouldBeLoaded);
  270. LevelStreamingObject->SetShouldBeVisible(bNewShouldBeVisible);
  271. LevelStreamingObject->bShouldBlockOnLoad = bNewShouldBlockOnLoad;
  272. LevelStreamingObject->SetLevelLODIndex(LODIndex);
  273. }
  274. else
  275. {
  276. UE_LOG(LogStreaming, Log, TEXT("Unable to handle streaming object %s"),*LevelStreamingObject->GetName() );
  277. }
  278.  
  279. // break out of object iterator if we found a match
  280. break;
  281. }
  282. }
  283. }
  284.  
  285. if (LevelStreamingObject == NULL)
  286. {
  287. UE_LOG(LogStreaming, Log, TEXT("Unable to find streaming object %s"), *PackageName.ToString() );
  288. }
  289. }
  290. }
  291.  
  292. void APlayerController::ClientUpdateMultipleLevelsStreamingStatus_Implementation( const TArray<FUpdateLevelStreamingLevelStatus>& LevelStatuses )
  293. {
  294. for( const FUpdateLevelStreamingLevelStatus& LevelStatus : LevelStatuses )
  295. {
  296. ClientUpdateLevelStreamingStatus_Implementation( LevelStatus.PackageName, LevelStatus.bNewShouldBeLoaded, LevelStatus.bNewShouldBeVisible, LevelStatus.bNewShouldBlockOnLoad, LevelStatus.LODIndex );
  297. }
  298. }
  299.  
  300. void APlayerController::ClientFlushLevelStreaming_Implementation()
  301. {
  302. UWorld* World = GetWorld();
  303. // if we're already doing a map change, requesting another blocking load is just wasting time
  304. if (GEngine->ShouldCommitPendingMapChange(World))
  305. {
  306. // request level streaming be flushed next frame
  307. World->UpdateLevelStreaming();
  308. World->bRequestedBlockOnAsyncLoading = true;
  309. // request GC as soon as possible to remove any unloaded levels from memory
  310. GEngine->ForceGarbageCollection();
  311. }
  312. }
  313.  
  314.  
  315. void APlayerController::ServerUpdateLevelVisibility_Implementation(FName PackageName, bool bIsVisible)
  316. {
  317. UNetConnection* Connection = Cast<UNetConnection>(Player);
  318. if (Connection != NULL)
  319. {
  320. PackageName = NetworkRemapPath(PackageName, true);
  321. Connection->UpdateLevelVisibility(PackageName, bIsVisible);
  322. }
  323. }
  324.  
  325. bool APlayerController::ServerUpdateLevelVisibility_Validate(FName PackageName, bool bIsVisible)
  326. {
  327. RPC_VALIDATE( PackageName.IsValid() );
  328.  
  329. FText Reason;
  330.  
  331. if ( !FPackageName::IsValidLongPackageName( PackageName.ToString(), true, &Reason ) )
  332. {
  333. UE_LOG( LogPlayerController, Warning, TEXT( "ServerUpdateLevelVisibility() Invalid package name: %s (%s)" ), *PackageName.ToString(), *Reason.ToString() );
  334. return false;
  335. }
  336.  
  337. return true;
  338. }
  339.  
  340. void APlayerController::ServerUpdateMultipleLevelsVisibility_Implementation( const TArray<FUpdateLevelVisibilityLevelInfo>& LevelVisibilities )
  341. {
  342. for( const FUpdateLevelVisibilityLevelInfo& LevelVisibility : LevelVisibilities )
  343. {
  344. ServerUpdateLevelVisibility_Implementation( LevelVisibility.PackageName, LevelVisibility.bIsVisible );
  345. }
  346. }
  347.  
  348. bool APlayerController::ServerUpdateMultipleLevelsVisibility_Validate( const TArray<FUpdateLevelVisibilityLevelInfo>& LevelVisibilities )
  349. {
  350. for( const FUpdateLevelVisibilityLevelInfo& LevelVisibility : LevelVisibilities )
  351. {
  352. if( !ServerUpdateLevelVisibility_Validate( LevelVisibility.PackageName, LevelVisibility.bIsVisible ) )
  353. {
  354. return false;
  355. }
  356. }
  357.  
  358. return true;
  359. }
  360.  
  361. void APlayerController::ClientAddTextureStreamingLoc_Implementation(FVector InLoc, float Duration, bool bOverrideLocation )
  362. {
  363. if (!IStreamingManager::HasShutdown())
  364. {
  365. IStreamingManager::Get().AddViewSlaveLocation(InLoc, 1.0f, bOverrideLocation, Duration);
  366. }
  367. }
  368.  
  369. /// @endcond
  370.  
  371. void APlayerController::SetNetSpeed(int32 NewSpeed)
  372. {
  373. UNetDriver* Driver = GetWorld()->GetNetDriver();
  374. if (Player != NULL && Driver != NULL)
  375. {
  376. Player->CurrentNetSpeed = FMath::Clamp(NewSpeed, 1800, Driver->MaxClientRate);
  377. if (Driver->ServerConnection != NULL)
  378. {
  379. Driver->ServerConnection->CurrentNetSpeed = Player->CurrentNetSpeed;
  380. }
  381. }
  382. }
  383.  
  384. FString APlayerController::ConsoleCommand(const FString& Cmd, bool bWriteToLog)
  385. {
  386. if (Player != nullptr)
  387. {
  388. return Player->ConsoleCommand(Cmd, bWriteToLog);
  389. }
  390.  
  391. return TEXT("");
  392. }
  393.  
  394. void APlayerController::CleanUpAudioComponents()
  395. {
  396. TInlineComponentArray<UAudioComponent*> Components;
  397. GetComponents(Components);
  398.  
  399. for(int32 CompIndex = 0; CompIndex < Components.Num(); CompIndex++)
  400. {
  401. UAudioComponent* AComp = Components[CompIndex];
  402. if (AComp->Sound == NULL)
  403. {
  404. AComp->DestroyComponent();
  405. }
  406. }
  407. }
  408.  
  409. AActor* APlayerController::GetViewTarget() const
  410. {
  411. return PlayerCameraManager ? PlayerCameraManager->GetViewTarget() : NULL;
  412. }
  413.  
  414. void APlayerController::SetViewTarget(class AActor* NewViewTarget, struct FViewTargetTransitionParams TransitionParams)
  415. {
  416. // if we're being controlled by a director track, update it with the new viewtarget
  417. // so it returns to the proper viewtarget when it finishes.
  418. UInterpTrackInstDirector* const Director = GetControllingDirector();
  419. if (Director)
  420. {
  421. Director->OldViewTarget = NewViewTarget;
  422. }
  423.  
  424. if (PlayerCameraManager)
  425. {
  426. PlayerCameraManager->SetViewTarget(NewViewTarget, TransitionParams);
  427. }
  428. }
  429.  
  430.  
  431. void APlayerController::AutoManageActiveCameraTarget(AActor* SuggestedTarget)
  432. {
  433. if (bAutoManageActiveCameraTarget)
  434. {
  435. // See if there is a CameraActor with an auto-activate index that matches us.
  436. if (GetNetMode() == NM_Client)
  437. {
  438. // Clients don't know their own index on the server, so they have to trust that if they use a camera with an auto-activate index, that's their own index.
  439. ACameraActor* CurrentCameraActor = Cast<ACameraActor>(GetViewTarget());
  440. if (CurrentCameraActor)
  441. {
  442. const int32 CameraAutoIndex = CurrentCameraActor->GetAutoActivatePlayerIndex();
  443. if (CameraAutoIndex != INDEX_NONE)
  444. {
  445. return;
  446. }
  447. }
  448. }
  449. else
  450. {
  451. // See if there is a CameraActor in the level that auto-activates for this PC.
  452. ACameraActor* AutoCameraTarget = GetAutoActivateCameraForPlayer();
  453. if (AutoCameraTarget)
  454. {
  455. SetViewTarget(AutoCameraTarget);
  456. return;
  457. }
  458. }
  459.  
  460. // No auto-activate CameraActor, so use the suggested target.
  461. SetViewTarget(SuggestedTarget);
  462. }
  463. }
  464.  
  465.  
  466.  
  467. ACameraActor* APlayerController::GetAutoActivateCameraForPlayer() const
  468. {
  469. if (GetNetMode() == NM_Client)
  470. {
  471. // Clients get their view target replicated, they don't use placed cameras because they don't know their own index.
  472. return NULL;
  473. }
  474.  
  475. UWorld* CurWorld = GetWorld();
  476. if (!CurWorld)
  477. {
  478. return NULL;
  479. }
  480.  
  481. // Only bother if there are any registered cameras.
  482. FConstCameraActorIterator CameraIterator = CurWorld->GetAutoActivateCameraIterator();
  483. if (!CameraIterator)
  484. {
  485. return NULL;
  486. }
  487.  
  488. // Find our player index
  489. int32 IterIndex = 0;
  490. int32 PlayerIndex = INDEX_NONE;
  491. for( FConstPlayerControllerIterator Iterator = CurWorld->GetPlayerControllerIterator(); Iterator; ++Iterator, ++IterIndex )
  492. {
  493. const APlayerController* PlayerController = Iterator->Get();
  494. if (PlayerController == this)
  495. {
  496. PlayerIndex = IterIndex;
  497. break;
  498. }
  499. }
  500.  
  501. if (PlayerIndex != INDEX_NONE)
  502. {
  503. // Find the matching camera
  504. for( /*CameraIterater initialized above*/; CameraIterator; ++CameraIterator)
  505. {
  506. ACameraActor* CameraActor = CameraIterator->Get();
  507. if (CameraActor && CameraActor->GetAutoActivatePlayerIndex() == PlayerIndex)
  508. {
  509. return CameraActor;
  510. }
  511. }
  512. }
  513.  
  514. return NULL;
  515. }
  516.  
  517.  
  518.  
  519. void APlayerController::SetControllingDirector(UInterpTrackInstDirector* NewControllingDirector, bool bClientSimulatingViewTarget)
  520. {
  521. ControllingDirTrackInst = NewControllingDirector;
  522.  
  523. if (PlayerCameraManager != NULL)
  524. {
  525. PlayerCameraManager->bClientSimulatingViewTarget = (NewControllingDirector != NULL) ? bClientSimulatingViewTarget : false;
  526. }
  527. }
  528.  
  529.  
  530. UInterpTrackInstDirector* APlayerController::GetControllingDirector()
  531. {
  532. return ControllingDirTrackInst;
  533. }
  534.  
  535. /// @cond DOXYGEN_WARNINGS
  536.  
  537. bool APlayerController::ServerNotifyLoadedWorld_Validate(FName WorldPackageName)
  538. {
  539. RPC_VALIDATE( WorldPackageName.IsValid() );
  540. return true;
  541. }
  542.  
  543. void APlayerController::ServerNotifyLoadedWorld_Implementation(FName WorldPackageName)
  544. {
  545. UE_LOG(LogPlayerController, Verbose, TEXT("APlayerController::ServerNotifyLoadedWorld_Implementation: Client loaded %s"), *WorldPackageName.ToString());
  546.  
  547. UWorld* CurWorld = GetWorld();
  548.  
  549. // Only valid for calling, for PC's in the process of seamless traveling
  550. // NOTE: SeamlessTravelCount tracks client seamless travel, through the serverside gameplay code; this should not be replaced.
  551. if (CurWorld != NULL && CurWorld->IsServer() && SeamlessTravelCount > 0 && LastCompletedSeamlessTravelCount < SeamlessTravelCount)
  552. {
  553. // Update our info on what world the client is in
  554. UNetConnection* const Connection = Cast<UNetConnection>(Player);
  555.  
  556. if (Connection != NULL)
  557. {
  558. Connection->SetClientWorldPackageName(WorldPackageName);
  559. }
  560.  
  561. // if both the server and this client have completed the transition, handle it
  562. FSeamlessTravelHandler& SeamlessTravelHandler = GEngine->SeamlessTravelHandlerForWorld(CurWorld);
  563. AGameModeBase* CurGameMode = CurWorld->GetAuthGameMode();
  564.  
  565. if (!SeamlessTravelHandler.IsInTransition() && WorldPackageName == CurWorld->GetOutermost()->GetFName() && CurGameMode != NULL)
  566. {
  567. AController* TravelPlayer = this;
  568. CurGameMode->HandleSeamlessTravelPlayer(TravelPlayer);
  569. }
  570. }
  571. }
  572.  
  573. /// @cond DOXYGEN_WARNINGS
  574.  
  575. bool APlayerController::HasClientLoadedCurrentWorld()
  576. {
  577. UNetConnection* Connection = Cast<UNetConnection>(Player);
  578. if (Connection == NULL && UNetConnection::GNetConnectionBeingCleanedUp != NULL && UNetConnection::GNetConnectionBeingCleanedUp->PlayerController == this)
  579. {
  580. Connection = UNetConnection::GNetConnectionBeingCleanedUp;
  581. }
  582. if (Connection != NULL)
  583. {
  584. // NOTE: To prevent exploits, child connections must not use the parent connections ClientWorldPackageName value at all.
  585.  
  586. return (Connection->GetClientWorldPackageName() == GetWorld()->GetOutermost()->GetFName());
  587. }
  588. else
  589. {
  590. // if we have no client connection, we're local, so we always have the current world
  591. return true;
  592. }
  593. }
  594.  
  595. void APlayerController::ForceSingleNetUpdateFor(AActor* Target)
  596. {
  597. if (Target == NULL)
  598. {
  599. UE_LOG(LogPlayerController, Warning, TEXT("PlayerController::ForceSingleNetUpdateFor(): No Target specified"));
  600. }
  601. else if (GetNetMode() == NM_Client)
  602. {
  603. UE_LOG(LogPlayerController, Warning, TEXT("PlayerController::ForceSingleNetUpdateFor(): Only valid on server"));
  604. }
  605. else
  606. {
  607. UNetConnection* Conn = Cast<UNetConnection>(Player);
  608. if (Conn != NULL)
  609. {
  610. if (Conn->GetUChildConnection() != NULL)
  611. {
  612. Conn = ((UChildConnection*)Conn)->Parent;
  613. checkSlow(Conn != NULL);
  614. }
  615. UActorChannel* Channel = Conn->FindActorChannelRef(Target);
  616. if (Channel != NULL)
  617. {
  618. FNetworkObjectInfo* NetActor = Target->FindOrAddNetworkObjectInfo();
  619.  
  620. if (NetActor != nullptr)
  621. {
  622. NetActor->bPendingNetUpdate = true; // will cause some other clients to do lesser checks too, but that's unavoidable with the current functionality
  623. }
  624. }
  625. }
  626. }
  627. }
  628.  
  629. void APlayerController::SmoothTargetViewRotation(APawn* TargetPawn, float DeltaSeconds)
  630. {
  631. BlendedTargetViewRotation = FMath::RInterpTo(BlendedTargetViewRotation, TargetViewRotation, DeltaSeconds, SmoothTargetViewRotationSpeed);
  632. }
  633.  
  634.  
  635. void APlayerController::InitInputSystem()
  636. {
  637. if (PlayerInput == NULL)
  638. {
  639. PlayerInput = NewObject<UPlayerInput>(this);
  640. }
  641.  
  642. SetupInputComponent();
  643.  
  644. CurrentMouseCursor = DefaultMouseCursor;
  645. CurrentClickTraceChannel = DefaultClickTraceChannel;
  646.  
  647. UWorld* World = GetWorld();
  648. check(World);
  649. World->PersistentLevel->PushPendingAutoReceiveInput(this);
  650.  
  651. // add the player to any matinees running so that it gets in on any cinematics already running, etc
  652. // (already done on server in PostLogin())
  653. if (Role < ROLE_Authority)
  654. {
  655. TArray<AMatineeActor*> AllMatineeActors;
  656. World->GetMatineeActors(AllMatineeActors);
  657.  
  658. // tell them all to add this PC to any running Director tracks
  659. for (int32 i = 0; i < AllMatineeActors.Num(); i++)
  660. {
  661. AllMatineeActors[i]->AddPlayerToDirectorTracks(this);
  662. }
  663. }
  664.  
  665. // setup optional touchscreen interface
  666. CreateTouchInterface();
  667. }
  668.  
  669. void APlayerController::SafeRetryClientRestart()
  670. {
  671. if (AcknowledgedPawn != GetPawn())
  672. {
  673. UWorld* World = GetWorld();
  674. check(World);
  675.  
  676. if (World->TimeSince(LastRetryPlayerTime) > RetryClientRestartThrottleTime)
  677. {
  678. ClientRetryClientRestart(GetPawn());
  679. LastRetryPlayerTime = World->TimeSeconds;
  680. }
  681. }
  682. }
  683.  
  684.  
  685. /// @cond DOXYGEN_WARNINGS
  686.  
  687. /** Avoid calling ClientRestart if we have already accepted this pawn */
  688. void APlayerController::ClientRetryClientRestart_Implementation(APawn* NewPawn)
  689. {
  690. if (NewPawn == NULL)
  691. {
  692. return;
  693. }
  694.  
  695. UE_LOG(LogPlayerController, Verbose, TEXT("ClientRetryClientRestart_Implementation %s, AcknowledgedPawn: %s"), *GetNameSafe(NewPawn), *GetNameSafe(AcknowledgedPawn));
  696.  
  697. // Avoid calling ClientRestart if we have already accepted this pawn
  698. if( (GetPawn() != NewPawn) || (NewPawn->Controller != this) || (NewPawn != AcknowledgedPawn) )
  699. {
  700. SetPawn(NewPawn);
  701. NewPawn->Controller = this;
  702. NewPawn->OnRep_Controller();
  703. ClientRestart(GetPawn());
  704. }
  705. }
  706.  
  707. void APlayerController::ClientRestart_Implementation(APawn* NewPawn)
  708. {
  709. UE_LOG(LogPlayerController, Verbose, TEXT("ClientRestart_Implementation %s"), *GetNameSafe(NewPawn));
  710.  
  711. ResetIgnoreInputFlags();
  712. AcknowledgedPawn = NULL;
  713.  
  714. SetPawn(NewPawn);
  715. if ( (GetPawn() != NULL) && GetPawn()->GetTearOff() )
  716. {
  717. UnPossess();
  718. SetPawn(NULL);
  719. AcknowledgePossession(GetPawn());
  720. return;
  721. }
  722.  
  723. if ( GetPawn() == NULL )
  724. {
  725. // We failed to possess, ask server to verify and potentially resend the pawn
  726. ServerCheckClientPossessionReliable();
  727. return;
  728. }
  729.  
  730. // Only acknowledge non-null Pawns here. ClientRestart is only ever called by the Server for valid pawns,
  731. // but we may receive the function call before Pawn is replicated over, so it will resolve to NULL.
  732. AcknowledgePossession(GetPawn());
  733.  
  734. GetPawn()->Controller = this;
  735. GetPawn()->PawnClientRestart();
  736.  
  737. if (Role < ROLE_Authority)
  738. {
  739. ChangeState( NAME_Playing );
  740. if (bAutoManageActiveCameraTarget)
  741. {
  742. AutoManageActiveCameraTarget(GetPawn());
  743. ResetCameraMode();
  744. }
  745. }
  746. }
  747.  
  748. /// @endcond
  749.  
  750. void APlayerController::Possess(APawn* PawnToPossess)
  751. {
  752. if (!HasAuthority())
  753. {
  754. FMessageLog("PIE").Warning(FText::Format(
  755. LOCTEXT("PlayerControllerPossessAuthorityOnly", "Possess function should only be used by the network authority for {0}"),
  756. FText::FromName(GetFName())
  757. ));
  758. UE_LOG(LogPlayerController, Warning, TEXT("Trying to possess %s without network authority! Request will be ignored."), *GetNameSafe(PawnToPossess));
  759. return;
  760. }
  761.  
  762. if ( PawnToPossess != NULL &&
  763. (PlayerState == NULL || !PlayerState->bOnlySpectator) )
  764. {
  765. if (GetPawn() && GetPawn() != PawnToPossess)
  766. {
  767. UnPossess();
  768. }
  769.  
  770. if (PawnToPossess->Controller != NULL)
  771. {
  772. PawnToPossess->Controller->UnPossess();
  773. }
  774.  
  775. PawnToPossess->PossessedBy(this);
  776.  
  777. // update rotation to match possessed pawn's rotation
  778. SetControlRotation( PawnToPossess->GetActorRotation() );
  779.  
  780. SetPawn(PawnToPossess);
  781. check(GetPawn() != NULL);
  782.  
  783. if (GetPawn() && GetPawn()->PrimaryActorTick.bStartWithTickEnabled)
  784. {
  785. GetPawn()->SetActorTickEnabled(true);
  786. }
  787.  
  788. INetworkPredictionInterface* NetworkPredictionInterface = GetPawn() ? Cast<INetworkPredictionInterface>(GetPawn()->GetMovementComponent()) : NULL;
  789. if (NetworkPredictionInterface)
  790. {
  791. NetworkPredictionInterface->ResetPredictionData_Server();
  792. }
  793.  
  794. AcknowledgedPawn = NULL;
  795.  
  796. // Local PCs will have the Restart() triggered right away in ClientRestart (via PawnClientRestart()), but the server should call Restart() locally for remote PCs.
  797. // We're really just trying to avoid calling Restart() multiple times.
  798. if (!IsLocalPlayerController())
  799. {
  800. GetPawn()->Restart();
  801. }
  802.  
  803. ClientRestart(GetPawn());
  804.  
  805. ChangeState( NAME_Playing );
  806. if (bAutoManageActiveCameraTarget)
  807. {
  808. AutoManageActiveCameraTarget(GetPawn());
  809. ResetCameraMode();
  810. }
  811. // not calling UpdateNavigationComponents() anymore. The
  812. // PathFollowingComponent is now observing newly possessed
  813. // pawns (via OnNewPawn)
  814. }
  815. }
  816.  
  817. void APlayerController::AcknowledgePossession(APawn* P)
  818. {
  819. if (Cast<ULocalPlayer>(Player) != NULL)
  820. {
  821. AcknowledgedPawn = P;
  822. if (P != NULL)
  823. {
  824. P->RecalculateBaseEyeHeight();
  825. }
  826. ServerAcknowledgePossession(P);
  827. }
  828. }
  829.  
  830. void APlayerController::ReceivedPlayer()
  831. {
  832. if (IsInState(NAME_Spectating))
  833. {
  834. if (GetSpectatorPawn() == NULL)
  835. {
  836. BeginSpectatingState();
  837. }
  838. }
  839. }
  840.  
  841. FVector APlayerController::GetFocalLocation() const
  842. {
  843. if (GetPawnOrSpectator())
  844. {
  845. return GetPawnOrSpectator()->GetActorLocation();
  846. }
  847. else
  848. {
  849. return GetSpawnLocation();
  850. }
  851. }
  852.  
  853. void APlayerController::PostLoad()
  854. {
  855. Super::PostLoad();
  856.  
  857. if (GetLinkerUE4Version() < VER_UE4_SPLIT_TOUCH_AND_CLICK_ENABLES)
  858. {
  859. bEnableTouchEvents = bEnableClickEvents;
  860. }
  861. }
  862.  
  863. void APlayerController::GetActorEyesViewPoint( FVector& out_Location, FRotator& out_Rotation ) const
  864. {
  865. // If we have a Pawn, this is our view point.
  866. if (GetPawnOrSpectator() != NULL)
  867. {
  868. GetPawnOrSpectator()->GetActorEyesViewPoint(out_Location, out_Rotation);
  869. }
  870. else
  871. {
  872. out_Location = PlayerCameraManager ? PlayerCameraManager->GetCameraLocation() : GetSpawnLocation();
  873. out_Rotation = GetControlRotation();
  874. }
  875. }
  876.  
  877. void APlayerController::CalcCamera(float DeltaTime, FMinimalViewInfo& OutResult)
  878. {
  879. OutResult.Location = GetFocalLocation();
  880. OutResult.Rotation = GetControlRotation();
  881. }
  882.  
  883.  
  884. void APlayerController::GetPlayerViewPoint( FVector& out_Location, FRotator& out_Rotation ) const
  885. {
  886. if (IsInState(NAME_Spectating) && HasAuthority() && !IsLocalController())
  887. {
  888. // Server uses the synced location from clients. Important for view relevancy checks.
  889. out_Location = LastSpectatorSyncLocation;
  890. out_Rotation = LastSpectatorSyncRotation;
  891. }
  892. else if (PlayerCameraManager != NULL &&
  893. PlayerCameraManager->GetCameraCacheTime() > 0.f) // Whether camera was updated at least once)
  894. {
  895. PlayerCameraManager->GetCameraViewPoint(out_Location, out_Rotation);
  896. }
  897. else
  898. {
  899. AActor* TheViewTarget = GetViewTarget();
  900.  
  901. if( TheViewTarget != NULL )
  902. {
  903. out_Location = TheViewTarget->GetActorLocation();
  904. out_Rotation = TheViewTarget->GetActorRotation();
  905. }
  906. else
  907. {
  908. Super::GetPlayerViewPoint(out_Location,out_Rotation);
  909. }
  910.  
  911. out_Location.DiagnosticCheckNaN(*FString::Printf(TEXT("APlayerController::GetPlayerViewPoint: out_Location, ViewTarget=%s"), *GetNameSafe(TheViewTarget)));
  912. out_Rotation.DiagnosticCheckNaN(*FString::Printf(TEXT("APlayerController::GetPlayerViewPoint: out_Rotation, ViewTarget=%s"), *GetNameSafe(TheViewTarget)));
  913. }
  914. }
  915.  
  916. void APlayerController::UpdateRotation( float DeltaTime )
  917. {
  918. // Calculate Delta to be applied on ViewRotation
  919. FRotator DeltaRot(RotationInput);
  920.  
  921. FRotator ViewRotation = GetControlRotation();
  922.  
  923. if (PlayerCameraManager)
  924. {
  925. PlayerCameraManager->ProcessViewRotation(DeltaTime, ViewRotation, DeltaRot);
  926. }
  927.  
  928. AActor* ViewTarget = GetViewTarget();
  929. if (!PlayerCameraManager || !ViewTarget || !ViewTarget->HasActiveCameraComponent() || ViewTarget->HasActivePawnControlCameraComponent())
  930. {
  931. if (IsLocalPlayerController() && GEngine->XRSystem.IsValid() && GEngine->XRSystem->IsHeadTrackingAllowed())
  932. {
  933. auto XRCamera = GEngine->XRSystem->GetXRCamera();
  934. if (XRCamera.IsValid())
  935. {
  936. XRCamera->ApplyHMDRotation(this, ViewRotation);
  937. }
  938. }
  939. }
  940.  
  941. SetControlRotation(ViewRotation);
  942.  
  943. APawn* const P = GetPawnOrSpectator();
  944. if (P)
  945. {
  946. P->FaceRotation(ViewRotation, DeltaTime);
  947. }
  948. }
  949.  
  950. void APlayerController::FellOutOfWorld(const UDamageType& dmgType) {}
  951.  
  952. void APlayerController::PostInitializeComponents()
  953. {
  954. Super::PostInitializeComponents();
  955.  
  956. if ( !IsPendingKill() && (GetNetMode() != NM_Client) )
  957. {
  958. // create a new player replication info
  959. InitPlayerState();
  960. }
  961.  
  962. SpawnPlayerCameraManager();
  963. ResetCameraMode();
  964.  
  965. if ( GetNetMode() == NM_Client )
  966. {
  967. SpawnDefaultHUD();
  968. }
  969.  
  970. AddCheats();
  971.  
  972. bPlayerIsWaiting = true;
  973. StateName = NAME_Spectating; // Don't use ChangeState, because we want to defer spawning the SpectatorPawn until the Player is received
  974. }
  975.  
  976. /// @cond DOXYGEN_WARNINGS
  977.  
  978. bool APlayerController::ServerShortTimeout_Validate()
  979. {
  980. return true;
  981. }
  982.  
  983. void APlayerController::ServerShortTimeout_Implementation()
  984. {
  985. if (!bShortConnectTimeOut)
  986. {
  987. UWorld* World = GetWorld();
  988. check(World);
  989.  
  990. bShortConnectTimeOut = true;
  991.  
  992. // quick update of pickups and gameobjectives since this player is now relevant
  993. if (GetWorldSettings()->Pauser != NULL)
  994. {
  995. // update everything immediately, as TimeSeconds won't get advanced while paused
  996. // so otherwise it won't happen at all until the game is unpaused
  997. // this floods the network, but we're paused, so no gameplay is going on that would care much
  998. for (TSharedPtr<FNetworkObjectInfo> NetworkObjectInfo : World->GetNetDriver()->GetNetworkObjectList().GetAllObjects())
  999. {
  1000. if (NetworkObjectInfo.IsValid())
  1001. {
  1002. AActor* const A = NetworkObjectInfo->Actor;
  1003. if (A && !A->IsPendingKill())
  1004. {
  1005. if (!A->bOnlyRelevantToOwner)
  1006. {
  1007. A->ForceNetUpdate();
  1008. }
  1009. }
  1010. }
  1011. }
  1012. }
  1013. else
  1014. {
  1015. float NetUpdateTimeOffset = (World->GetAuthGameMode()->GetNumPlayers() < 8) ? 0.2f : 0.5f;
  1016. for (TSharedPtr<FNetworkObjectInfo> NetworkObjectInfo : World->GetNetDriver()->GetNetworkObjectList().GetAllObjects())
  1017. {
  1018. if (NetworkObjectInfo.IsValid())
  1019. {
  1020. AActor* const A = NetworkObjectInfo->Actor;
  1021. if (A && !A->IsPendingKill())
  1022. {
  1023. if ((A->NetUpdateFrequency < 1) && !A->bOnlyRelevantToOwner)
  1024. {
  1025. A->SetNetUpdateTime(World->TimeSeconds + NetUpdateTimeOffset * FMath::FRand());
  1026. }
  1027. }
  1028. }
  1029. }
  1030. }
  1031. }
  1032. }
  1033.  
  1034. /// @cond DOXYGEN_WARNINGS
  1035.  
  1036. void APlayerController::AddCheats(bool bForce)
  1037. {
  1038. UWorld* World = GetWorld();
  1039. check(World);
  1040.  
  1041. // Abort if cheat manager exists or there is no cheat class
  1042. if (CheatManager || !CheatClass)
  1043. {
  1044. return;
  1045. }
  1046.  
  1047. // Spawn if game mode says we are allowed, or if bForce
  1048. if ( (World->GetAuthGameMode() && World->GetAuthGameMode()->AllowCheats(this)) || bForce)
  1049. {
  1050. CheatManager = NewObject<UCheatManager>(this, CheatClass);
  1051. CheatManager->InitCheatManager();
  1052. }
  1053. }
  1054.  
  1055. void APlayerController::EnableCheats()
  1056. {
  1057. #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
  1058. AddCheats(true);
  1059. #else
  1060. AddCheats();
  1061. #endif
  1062. }
  1063.  
  1064.  
  1065. void APlayerController::SpawnDefaultHUD()
  1066. {
  1067. if ( Cast<ULocalPlayer>(Player) == NULL )
  1068. {
  1069. return;
  1070. }
  1071.  
  1072. UE_LOG(LogPlayerController, Verbose, TEXT("SpawnDefaultHUD"));
  1073. FActorSpawnParameters SpawnInfo;
  1074. SpawnInfo.Owner = this;
  1075. SpawnInfo.Instigator = Instigator;
  1076. SpawnInfo.ObjectFlags |= RF_Transient; // We never want to save HUDs into a map
  1077. MyHUD = GetWorld()->SpawnActor<AHUD>( SpawnInfo );
  1078. }
  1079.  
  1080. void APlayerController::CreateTouchInterface()
  1081. {
  1082. ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
  1083.  
  1084. // do we want to show virtual joysticks?
  1085. if (LocalPlayer && LocalPlayer->ViewportClient && SVirtualJoystick::ShouldDisplayTouchInterface())
  1086. {
  1087. // in case we already had one, remove it
  1088. if (VirtualJoystick.IsValid())
  1089. {
  1090. Cast<ULocalPlayer>(Player)->ViewportClient->RemoveViewportWidgetContent(VirtualJoystick.ToSharedRef());
  1091. }
  1092.  
  1093. if (CurrentTouchInterface == nullptr)
  1094. {
  1095. // load what the game wants to show at startup
  1096. FSoftObjectPath DefaultTouchInterfaceName = GetDefault<UInputSettings>()->DefaultTouchInterface;
  1097.  
  1098. if (DefaultTouchInterfaceName.IsValid())
  1099. {
  1100. // activate this interface if we have it
  1101. CurrentTouchInterface = LoadObject<UTouchInterface>(NULL, *DefaultTouchInterfaceName.ToString());
  1102. }
  1103. }
  1104.  
  1105. if (CurrentTouchInterface)
  1106. {
  1107. // create the joystick
  1108. VirtualJoystick = SNew(SVirtualJoystick);
  1109.  
  1110. // add it to the player's viewport
  1111. LocalPlayer->ViewportClient->AddViewportWidgetContent(VirtualJoystick.ToSharedRef());
  1112.  
  1113. ActivateTouchInterface(CurrentTouchInterface);
  1114. }
  1115. }
  1116. }
  1117.  
  1118. void APlayerController::CleanupGameViewport()
  1119. {
  1120. ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
  1121.  
  1122. if (VirtualJoystick.IsValid())
  1123. {
  1124. ActivateTouchInterface(nullptr);
  1125. }
  1126. }
  1127.  
  1128. AHUD* APlayerController::GetHUD() const
  1129. {
  1130. return MyHUD;
  1131. }
  1132.  
  1133. void APlayerController::SetMouseCursorWidget(EMouseCursor::Type Cursor, class UUserWidget* CursorWidget)
  1134. {
  1135. ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
  1136. if (LocalPlayer && LocalPlayer->ViewportClient)
  1137. {
  1138. LocalPlayer->ViewportClient->AddCursorWidget(Cursor, CursorWidget);
  1139. }
  1140. }
  1141.  
  1142. void APlayerController::GetViewportSize(int32& SizeX, int32& SizeY) const
  1143. {
  1144. SizeX = 0;
  1145. SizeY = 0;
  1146.  
  1147. ULocalPlayer* LocPlayer = Cast<ULocalPlayer>(Player);
  1148. if( LocPlayer && LocPlayer->ViewportClient )
  1149. {
  1150. FVector2D ViewportSize;
  1151. LocPlayer->ViewportClient->GetViewportSize(ViewportSize);
  1152.  
  1153. SizeX = ViewportSize.X;
  1154. SizeY = ViewportSize.Y;
  1155. }
  1156. }
  1157.  
  1158. void APlayerController::Reset()
  1159. {
  1160. if ( GetPawn() != NULL )
  1161. {
  1162. PawnPendingDestroy( GetPawn() );
  1163. UnPossess();
  1164. }
  1165.  
  1166. Super::Reset();
  1167.  
  1168. SetViewTarget(this);
  1169. ResetCameraMode();
  1170.  
  1171. bPlayerIsWaiting = !PlayerState->bOnlySpectator;
  1172. ChangeState(NAME_Spectating);
  1173. }
  1174.  
  1175. /// @cond DOXYGEN_WARNINGS
  1176.  
  1177. void APlayerController::ClientReset_Implementation()
  1178. {
  1179. ResetCameraMode();
  1180. SetViewTarget(this);
  1181.  
  1182. bPlayerIsWaiting = (PlayerState == nullptr) || !PlayerState->bOnlySpectator;
  1183. ChangeState(NAME_Spectating);
  1184. }
  1185.  
  1186. void APlayerController::ClientGotoState_Implementation(FName NewState)
  1187. {
  1188. ChangeState(NewState);
  1189. }
  1190.  
  1191. /// @endcond
  1192.  
  1193.  
  1194. void APlayerController::UnFreeze() {}
  1195.  
  1196. bool APlayerController::IsFrozen()
  1197. {
  1198. return GetWorldTimerManager().IsTimerActive(TimerHandle_UnFreeze);
  1199. }
  1200.  
  1201. /// @cond DOXYGEN_WARNINGS
  1202.  
  1203. void APlayerController::ServerAcknowledgePossession_Implementation(APawn* P)
  1204. {
  1205. UE_LOG(LogPlayerController, Verbose, TEXT("ServerAcknowledgePossession_Implementation %s"), *GetNameSafe(P));
  1206. AcknowledgedPawn = P;
  1207. }
  1208.  
  1209. bool APlayerController::ServerAcknowledgePossession_Validate(APawn* P)
  1210. {
  1211. if (P)
  1212. {
  1213. // Valid to acknowledge no possessed pawn
  1214. RPC_VALIDATE( !P->HasAnyFlags(RF_ClassDefaultObject) );
  1215. }
  1216. return true;
  1217. }
  1218.  
  1219. /// @endcond
  1220.  
  1221. void APlayerController::UnPossess()
  1222. {
  1223. if (GetPawn() != NULL)
  1224. {
  1225. if (Role == ROLE_Authority)
  1226. {
  1227. GetPawn()->SetReplicates(true);
  1228. }
  1229. GetPawn()->UnPossessed();
  1230.  
  1231. if (GetViewTarget() == GetPawn())
  1232. {
  1233. SetViewTarget(this);
  1234. }
  1235. }
  1236. SetPawn(NULL);
  1237. }
  1238.  
  1239. /// @cond DOXYGEN_WARNINGS
  1240.  
  1241. void APlayerController::ClientSetHUD_Implementation(TSubclassOf<AHUD> NewHUDClass)
  1242. {
  1243. if ( MyHUD != NULL )
  1244. {
  1245.  
  1246. MyHUD->Destroy();
  1247. MyHUD = NULL;
  1248. }
  1249.  
  1250. FActorSpawnParameters SpawnInfo;
  1251. SpawnInfo.Owner = this;
  1252. SpawnInfo.Instigator = Instigator;
  1253. SpawnInfo.ObjectFlags |= RF_Transient; // We never want to save HUDs into a map
  1254.  
  1255. MyHUD = GetWorld()->SpawnActor<AHUD>(NewHUDClass, SpawnInfo );
  1256. }
  1257.  
  1258. /// @endcond
  1259.  
  1260. void APlayerController::CleanupPlayerState()
  1261. {
  1262. if (PlayerState)
  1263. {
  1264. // By default this destroys it, but games can override
  1265. PlayerState->OnDeactivated();
  1266. }
  1267. PlayerState = NULL;
  1268. }
  1269.  
  1270. void APlayerController::OnActorChannelOpen(FInBunch& InBunch, UNetConnection* Connection)
  1271. {
  1272. SetAsLocalPlayerController();
  1273.  
  1274. // Attempt to match the player controller to a local viewport (client side)
  1275. InBunch << NetPlayerIndex;
  1276. if (Connection->Driver != NULL && Connection == Connection->Driver->ServerConnection)
  1277. {
  1278. if (NetPlayerIndex == 0)
  1279. {
  1280. // main connection PlayerController
  1281. Connection->HandleClientPlayer(this, Connection);
  1282. }
  1283. else
  1284. {
  1285. int32 ChildIndex = int32(NetPlayerIndex) - 1;
  1286. if (Connection->Children.IsValidIndex(ChildIndex))
  1287. {
  1288. // received a new PlayerController for an already existing child
  1289. Connection->Children[ChildIndex]->HandleClientPlayer(this, Connection);
  1290. }
  1291. else
  1292. {
  1293. // create a split connection on the client
  1294. UChildConnection* Child = Connection->Driver->CreateChild(Connection);
  1295. Child->HandleClientPlayer(this, Connection);
  1296. UE_LOG(LogNet, Verbose, TEXT("Client received PlayerController=%s. Num child connections=%i."), *GetName(), Connection->Children.Num());
  1297. }
  1298. }
  1299. }
  1300. }
  1301.  
  1302. bool APlayerController::UseShortConnectTimeout() const
  1303. {
  1304. return bShortConnectTimeOut;
  1305. }
  1306.  
  1307. void APlayerController::OnSerializeNewActor(FOutBunch& OutBunch)
  1308. {
  1309. // serialize PlayerIndex as part of the initial bunch for PlayerControllers so they can be matched to the correct client-side viewport
  1310. OutBunch << NetPlayerIndex;
  1311. }
  1312.  
  1313. void APlayerController::OnNetCleanup(UNetConnection* Connection)
  1314. {
  1315. UWorld* World = GetWorld();
  1316. // destroy the PC that was waiting for a swap, if it exists
  1317. if (World != NULL)
  1318. {
  1319. World->DestroySwappedPC(Connection);
  1320. }
  1321.  
  1322. check(UNetConnection::GNetConnectionBeingCleanedUp == NULL);
  1323. UNetConnection::GNetConnectionBeingCleanedUp = Connection;
  1324. //@note: if we ever implement support for splitscreen players leaving a match without the primary player leaving, we'll need to insert
  1325. // a call to ClearOnlineDelegates() here so that PlayerController.ClearOnlineDelegates can use the correct ControllerId (which lives
  1326. // in ULocalPlayer)
  1327. Player = NULL;
  1328. NetConnection = NULL;
  1329. Destroy( true );
  1330. UNetConnection::GNetConnectionBeingCleanedUp = NULL;
  1331. }
  1332.  
  1333. /// @cond DOXYGEN_WARNINGS
  1334.  
  1335. void APlayerController::ClientReceiveLocalizedMessage_Implementation( TSubclassOf<ULocalMessage> Message, int32 Switch, APlayerState* RelatedPlayerState_1, APlayerState* RelatedPlayerState_2, UObject* OptionalObject )
  1336. {
  1337. // Wait for player to be up to date with replication when joining a server, before stacking up messages
  1338. if (GetNetMode() == NM_DedicatedServer || GetWorld()->GetGameState() == nullptr || Message == nullptr)
  1339. {
  1340. return;
  1341. }
  1342.  
  1343. FClientReceiveData ClientData;
  1344. ClientData.LocalPC = this;
  1345. ClientData.MessageIndex = Switch;
  1346. ClientData.RelatedPlayerState_1 = RelatedPlayerState_1;
  1347. ClientData.RelatedPlayerState_2 = RelatedPlayerState_2;
  1348. ClientData.OptionalObject = OptionalObject;
  1349.  
  1350. Message->GetDefaultObject<ULocalMessage>()->ClientReceive( ClientData );
  1351. }
  1352.  
  1353. void APlayerController::ClientPlaySound_Implementation(USoundBase* Sound, float VolumeMultiplier /* = 1.f */, float PitchMultiplier /* = 1.f */)
  1354. {
  1355. FVector AudioPosition = GetFocalLocation();
  1356. UGameplayStatics::PlaySoundAtLocation( this, Sound, AudioPosition, VolumeMultiplier, PitchMultiplier );
  1357. }
  1358.  
  1359. void APlayerController::ClientPlaySoundAtLocation_Implementation(USoundBase* Sound, FVector Location, float VolumeMultiplier /* = 1.f */, float PitchMultiplier /* = 1.f */)
  1360. {
  1361. UGameplayStatics::PlaySoundAtLocation( this, Sound, Location, VolumeMultiplier, PitchMultiplier );
  1362. }
  1363.  
  1364. void APlayerController::ClientMessage_Implementation( const FString& S, FName Type, float MsgLifeTime )
  1365. {
  1366. if ( GetNetMode() == NM_DedicatedServer || GetWorld()->GetGameState() == nullptr )
  1367. {
  1368. return;
  1369. }
  1370.  
  1371. if (Type == NAME_None)
  1372. {
  1373. Type = FName(TEXT("Event"));
  1374. }
  1375.  
  1376. ClientTeamMessage(PlayerState, S, Type, MsgLifeTime);
  1377. }
  1378.  
  1379. void APlayerController::ClientTeamMessage_Implementation( APlayerState* SenderPlayerState, const FString& S, FName Type, float MsgLifeTime )
  1380. {
  1381. FString SMod = S;
  1382. static FName NAME_Say = FName(TEXT("Say"));
  1383. if( (Type == NAME_Say) && ( SenderPlayerState != NULL ) )
  1384. {
  1385. SMod = FString::Printf(TEXT("%s: %s"), *SenderPlayerState->GetPlayerName(), *SMod);
  1386. }
  1387.  
  1388. // since this is on the client, we can assume that if Player exists, it is a LocalPlayer
  1389. if (Player != NULL)
  1390. {
  1391. UGameViewportClient *ViewportClient = CastChecked<ULocalPlayer>(Player)->ViewportClient;
  1392. if ( ViewportClient && ViewportClient->ViewportConsole )
  1393. {
  1394. CastChecked<ULocalPlayer>(Player)->ViewportClient->ViewportConsole->OutputText(SMod);
  1395. }
  1396. }
  1397. }
  1398.  
  1399. bool APlayerController::ServerToggleAILogging_Validate()
  1400. {
  1401. return true;
  1402. }
  1403.  
  1404. void APlayerController::ServerToggleAILogging_Implementation()
  1405. {
  1406. if (CheatManager)
  1407. {
  1408. CheatManager->ServerToggleAILogging();
  1409. }
  1410. }
  1411.  
  1412. /// @endcond
  1413.  
  1414. void APlayerController::PawnLeavingGame()
  1415. {
  1416. if (GetPawn() != NULL)
  1417. {
  1418. GetPawn()->Destroy();
  1419. SetPawn(NULL);
  1420. }
  1421. }
  1422.  
  1423. void APlayerController::BeginPlay()
  1424. {
  1425. Super::BeginPlay();
  1426.  
  1427. // If the viewport is currently set to lock mouse always, we need to cache what widget the mouse needs to be locked to even if the
  1428. // widget does not have mouse capture.
  1429. ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>( Player );
  1430.  
  1431. if ( LocalPlayer && LocalPlayer->ViewportClient )
  1432. {
  1433. if ( LocalPlayer->ViewportClient->ShouldAlwaysLockMouse() )
  1434. {
  1435. LocalPlayer->GetSlateOperations().LockMouseToWidget( LocalPlayer->ViewportClient->GetGameViewportWidget().ToSharedRef() );
  1436. }
  1437. }
  1438.  
  1439. //If we are faking touch events show the cursor
  1440. if (FSlateApplication::IsInitialized() && FSlateApplication::Get().IsFakingTouchEvents())
  1441. {
  1442. bShowMouseCursor = true;
  1443. }
  1444.  
  1445. }
  1446.  
  1447. void APlayerController::EndPlay(const EEndPlayReason::Type EndPlayReason)
  1448. {
  1449. ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
  1450. if (LocalPlayer)
  1451. {
  1452. if (VirtualJoystick.IsValid())
  1453. {
  1454. ActivateTouchInterface(nullptr);
  1455. }
  1456.  
  1457. if (FSlateApplication::IsInitialized())
  1458. {
  1459. IInputInterface* InputInterface = FSlateApplication::Get().GetInputInterface();
  1460. if (InputInterface)
  1461. {
  1462. // Stop any force feedback effects that may be active
  1463. InputInterface->SetForceFeedbackChannelValues(LocalPlayer->GetControllerId(), FForceFeedbackValues());
  1464. }
  1465. }
  1466. }
  1467.  
  1468. if (CheatManager)
  1469. {
  1470. CheatManager->ReceiveEndPlay();
  1471. }
  1472.  
  1473. Super::EndPlay(EndPlayReason);
  1474. }
  1475.  
  1476. void APlayerController::Destroyed()
  1477. {
  1478. if (GetPawn() != NULL)
  1479. {
  1480. // Handle players leaving the game
  1481. if (Player == NULL && Role == ROLE_Authority)
  1482. {
  1483. PawnLeavingGame();
  1484. }
  1485. else
  1486. {
  1487. UnPossess();
  1488. }
  1489. }
  1490.  
  1491. if (GetSpectatorPawn() != NULL)
  1492. {
  1493. DestroySpectatorPawn();
  1494. }
  1495. if ( MyHUD != NULL )
  1496. {
  1497. MyHUD->Destroy();
  1498. MyHUD = NULL;
  1499. }
  1500.  
  1501. if (PlayerCameraManager != NULL)
  1502. {
  1503. PlayerCameraManager->Destroy();
  1504. PlayerCameraManager = NULL;
  1505. }
  1506.  
  1507. // Tells the game info to forcibly remove this player's CanUnpause delegates from its list of Pausers.
  1508. // Prevents the game from being stuck in a paused state when a PC that paused the game is destroyed before the game is unpaused.
  1509. AGameModeBase* const GameMode = GetWorld()->GetAuthGameMode();
  1510. if (GameMode)
  1511. {
  1512. GameMode->ForceClearUnpauseDelegates(this);
  1513. }
  1514.  
  1515. PlayerInput = NULL;
  1516. CheatManager = NULL;
  1517.  
  1518. Super::Destroyed();
  1519. }
  1520.  
  1521. void APlayerController::FOV(float F)
  1522. {
  1523. if (PlayerCameraManager != NULL)
  1524. {
  1525. PlayerCameraManager->SetFOV(F);
  1526. }
  1527. }
  1528.  
  1529. void APlayerController::PreClientTravel( const FString& PendingURL, ETravelType TravelType, bool bIsSeamlessTravel )
  1530. {
  1531. UGameInstance* GameInstance = GetGameInstance();
  1532. if (GameInstance)
  1533. {
  1534. GameInstance->NotifyPreClientTravel(PendingURL, TravelType, bIsSeamlessTravel);
  1535. }
  1536. }
  1537.  
  1538. void APlayerController::Camera( FName NewMode )
  1539. {
  1540. ServerCamera(NewMode);
  1541. }
  1542.  
  1543. /// @cond DOXYGEN_WARNINGS
  1544.  
  1545. void APlayerController::ServerCamera_Implementation( FName NewMode )
  1546. {
  1547. SetCameraMode(NewMode);
  1548. }
  1549.  
  1550. bool APlayerController::ServerCamera_Validate( FName NewMode )
  1551. {
  1552. RPC_VALIDATE( NewMode.IsValid() );
  1553. return true;
  1554. }
  1555.  
  1556. void APlayerController::ClientSetCameraMode_Implementation( FName NewCamMode )
  1557. {
  1558. if (PlayerCameraManager)
  1559. {
  1560. PlayerCameraManager->CameraStyle = NewCamMode;
  1561. }
  1562. }
  1563.  
  1564. /// @endcond
  1565.  
  1566. void APlayerController::SetCameraMode( FName NewCamMode )
  1567. {
  1568. if (PlayerCameraManager)
  1569. {
  1570. PlayerCameraManager->CameraStyle = NewCamMode;
  1571. }
  1572.  
  1573. if ( GetNetMode() == NM_DedicatedServer )
  1574. {
  1575. ClientSetCameraMode( NewCamMode );
  1576. }
  1577. }
  1578.  
  1579. void APlayerController::ResetCameraMode()
  1580. {
  1581. FName DefaultMode = NAME_Default;
  1582. if (PlayerCameraManager)
  1583. {
  1584. DefaultMode = PlayerCameraManager->CameraStyle;
  1585. }
  1586.  
  1587. SetCameraMode(DefaultMode);
  1588. }
  1589.  
  1590. /// @cond DOXYGEN_WARNINGS
  1591.  
  1592. void APlayerController::ClientSetCameraFade_Implementation(bool bEnableFading, FColor FadeColor, FVector2D FadeAlpha, float FadeTime, bool bFadeAudio)
  1593. {
  1594. if (PlayerCameraManager != nullptr)
  1595. {
  1596. if (bEnableFading)
  1597. {
  1598. PlayerCameraManager->StartCameraFade(FadeAlpha.X, FadeAlpha.Y, FadeTime, FadeColor.ReinterpretAsLinear(), bFadeAudio);
  1599. }
  1600. else
  1601. {
  1602. PlayerCameraManager->StopCameraFade();
  1603. }
  1604. }
  1605. }
  1606.  
  1607. /// @endcond
  1608.  
  1609. void APlayerController::SendClientAdjustment()
  1610. {
  1611. if (AcknowledgedPawn != GetPawn() && !GetSpectatorPawn())
  1612. {
  1613. return;
  1614. }
  1615.  
  1616. // Server sends updates.
  1617. // Note: we do this for both the pawn and spectator in case an implementation has a networked spectator.
  1618. APawn* RemotePawn = GetPawnOrSpectator();
  1619. if (RemotePawn && (RemotePawn->GetRemoteRole() == ROLE_AutonomousProxy) && !IsNetMode(NM_Client))
  1620. {
  1621. INetworkPredictionInterface* NetworkPredictionInterface = Cast<INetworkPredictionInterface>(RemotePawn->GetMovementComponent());
  1622. if (NetworkPredictionInterface)
  1623. {
  1624. NetworkPredictionInterface->SendClientAdjustment();
  1625. }
  1626. }
  1627. }
  1628.  
  1629. /// @cond DOXYGEN_WARNINGS
  1630.  
  1631. void APlayerController::ClientCapBandwidth_Implementation(int32 Cap)
  1632. {
  1633. ClientCap = Cap;
  1634. if( (Player != NULL) && (Player->CurrentNetSpeed > Cap) )
  1635. {
  1636. SetNetSpeed(Cap);
  1637. }
  1638. }
  1639.  
  1640. /// @endcond
  1641.  
  1642. void APlayerController::UpdatePing(float InPing)
  1643. {
  1644. if (PlayerState != NULL)
  1645. {
  1646. PlayerState->UpdatePing(InPing);
  1647. }
  1648. }
  1649.  
  1650.  
  1651. void APlayerController::SetSpawnLocation(const FVector& NewLocation)
  1652. {
  1653. SpawnLocation = NewLocation;
  1654. LastSpectatorSyncLocation = NewLocation;
  1655. }
  1656.  
  1657.  
  1658. void APlayerController::SetInitialLocationAndRotation(const FVector& NewLocation, const FRotator& NewRotation)
  1659. {
  1660. Super::SetInitialLocationAndRotation(NewLocation, NewRotation);
  1661. SetSpawnLocation(NewLocation);
  1662. if (GetSpectatorPawn())
  1663. {
  1664. GetSpectatorPawn()->TeleportTo(NewLocation, NewRotation, false, true);
  1665. }
  1666. }
  1667.  
  1668. /// @cond DOXYGEN_WARNINGS
  1669.  
  1670. bool APlayerController::ServerUpdateCamera_Validate(FVector_NetQuantize CamLoc, int32 CamPitchAndYaw)
  1671. {
  1672. return true;
  1673. }
  1674.  
  1675. void APlayerController::ServerUpdateCamera_Implementation(FVector_NetQuantize CamLoc, int32 CamPitchAndYaw)
  1676. {
  1677. if (!PlayerCameraManager || !PlayerCameraManager->bUseClientSideCameraUpdates)
  1678. {
  1679. return;
  1680. }
  1681.  
  1682. FPOV NewPOV;
  1683. NewPOV.Location = FRepMovement::RebaseOntoLocalOrigin(CamLoc, this);
  1684.  
  1685. NewPOV.Rotation.Yaw = FRotator::DecompressAxisFromShort( (CamPitchAndYaw >> 16) & 65535 );
  1686. NewPOV.Rotation.Pitch = FRotator::DecompressAxisFromShort(CamPitchAndYaw & 65535);
  1687.  
  1688. #if ENABLE_DRAW_DEBUG
  1689. if ( PlayerCameraManager->bDebugClientSideCamera )
  1690. {
  1691. // show differences (on server) between local and replicated camera
  1692. const FVector PlayerCameraLoc = PlayerCameraManager->GetCameraLocation();
  1693.  
  1694. UWorld* World = GetWorld();
  1695. DrawDebugSphere(World, PlayerCameraLoc, 10, 10, FColor::Green );
  1696. DrawDebugSphere(World, NewPOV.Location, 10, 10, FColor::Yellow );
  1697. DrawDebugLine(World, PlayerCameraLoc, PlayerCameraLoc + 100*PlayerCameraManager->GetCameraRotation().Vector(), FColor::Green);
  1698. DrawDebugLine(World, NewPOV.Location, NewPOV.Location + 100*NewPOV.Rotation.Vector(), FColor::Yellow);
  1699. }
  1700. else
  1701. #endif
  1702. {
  1703. //@TODO: CAMERA: Fat pipe
  1704. FMinimalViewInfo NewInfo = PlayerCameraManager->GetCameraCachePOV();
  1705. NewInfo.Location = NewPOV.Location;
  1706. NewInfo.Rotation = NewPOV.Rotation;
  1707. PlayerCameraManager->FillCameraCache(NewInfo);
  1708. }
  1709. }
  1710.  
  1711. /// @endcond
  1712.  
  1713. void APlayerController::RestartLevel()
  1714. {
  1715. if( GetNetMode()==NM_Standalone )
  1716. {
  1717. ClientTravel( TEXT("?restart"), TRAVEL_Relative );
  1718. }
  1719. }
  1720.  
  1721. void APlayerController::LocalTravel( const FString& FURL )
  1722. {
  1723. if( GetNetMode()==NM_Standalone )
  1724. {
  1725. ClientTravel( FURL, TRAVEL_Relative );
  1726. }
  1727. }
  1728.  
  1729. void APlayerController::ClientReturnToMainMenuWithTextReason_Implementation(const FText& ReturnReason)
  1730. {
  1731. if (UGameInstance* const GameInstance = GetGameInstance())
  1732. {
  1733. GameInstance->ReturnToMainMenu();
  1734. }
  1735. else
  1736. {
  1737. UWorld* const World = GetWorld();
  1738. GEngine->HandleDisconnect(World, World->GetNetDriver());
  1739. }
  1740. }
  1741.  
  1742. void APlayerController::ClientReturnToMainMenu_Implementation(const FString& ReturnReason)
  1743. {
  1744. ClientReturnToMainMenuWithTextReason_Implementation(FText::FromString(ReturnReason));
  1745. }
  1746.  
  1747. bool APlayerController::SetPause( bool bPause, FCanUnpause CanUnpauseDelegate)
  1748. {
  1749. bool bResult = false;
  1750. if (GetNetMode() != NM_Client)
  1751. {
  1752. AGameModeBase* const GameMode = GetWorld()->GetAuthGameMode();
  1753. if (GameMode != nullptr)
  1754. {
  1755. bool bCurrentPauseState = IsPaused();
  1756. if (bPause && !bCurrentPauseState)
  1757. {
  1758. // Pause gamepad rumbling too if needed
  1759. bResult = GameMode->SetPause(this, CanUnpauseDelegate);
  1760.  
  1761. // Force an update, otherwise since the game time is not updating, the net driver
  1762. // might not see that it is time for the world settings actor to replicate
  1763. ForceSingleNetUpdateFor(GetWorldSettings());
  1764. }
  1765. else if (!bPause && bCurrentPauseState)
  1766. {
  1767. bResult = GameMode->ClearPause();
  1768. }
  1769. }
  1770. }
  1771. return bResult;
  1772. }
  1773.  
  1774. bool APlayerController::IsPaused() const
  1775. {
  1776. return GetWorldSettings()->Pauser != NULL;
  1777. }
  1778.  
  1779. void APlayerController::Pause()
  1780. {
  1781. ServerPause();
  1782. }
  1783.  
  1784. /// @cond DOXYGEN_WARNINGS
  1785.  
  1786. bool APlayerController::ServerPause_Validate()
  1787. {
  1788. #if UE_BUILD_SHIPPING
  1789. // Don't let clients remotely pause the game in shipping builds.
  1790. return IsLocalController();
  1791. #else
  1792. return true;
  1793. #endif
  1794. }
  1795.  
  1796. void APlayerController::ServerPause_Implementation()
  1797. {
  1798. SetPause(!IsPaused());
  1799. }
  1800.  
  1801. /// @endcond
  1802.  
  1803. void APlayerController::SetName(const FString& S)
  1804. {
  1805. if (!S.IsEmpty())
  1806. {
  1807. // Games can override this to persist name on the client if desired
  1808. ServerChangeName(S);
  1809. }
  1810. }
  1811.  
  1812. /// @cond DOXYGEN_WARNINGS
  1813.  
  1814. void APlayerController::ServerChangeName_Implementation( const FString& S )
  1815. {
  1816. AGameModeBase* GameMode = GetWorld()->GetAuthGameMode();
  1817. if (!S.IsEmpty() && GameMode)
  1818. {
  1819. GameMode->ChangeName( this, S, true );
  1820. }
  1821. }
  1822.  
  1823. bool APlayerController::ServerChangeName_Validate( const FString& S )
  1824. {
  1825. RPC_VALIDATE( !S.IsEmpty() );
  1826. return true;
  1827. }
  1828.  
  1829. /// @endcond
  1830.  
  1831. void APlayerController::SwitchLevel(const FString& FURL)
  1832. {
  1833. const ENetMode NetMode = GetNetMode();
  1834. if (NetMode == NM_Standalone || NetMode == NM_ListenServer)
  1835. {
  1836. GetWorld()->ServerTravel(FURL);
  1837. }
  1838. }
  1839.  
  1840. void APlayerController::NotifyLoadedWorld(FName WorldPackageName, bool bFinalDest)
  1841. {
  1842. // place the camera at the first playerstart we can find
  1843. SetViewTarget(this);
  1844.  
  1845. for( TActorIterator<APlayerStart> It(GetWorld()); It; ++It )
  1846. {
  1847. APlayerStart* P = *It;
  1848.  
  1849. FRotator SpawnRotation(ForceInit);
  1850. SpawnRotation.Yaw = P->GetActorRotation().Yaw;
  1851. SetInitialLocationAndRotation(P->GetActorLocation(), SpawnRotation);
  1852. break;
  1853. }
  1854. }
  1855.  
  1856. void APlayerController::GameHasEnded(AActor* EndGameFocus, bool bIsWinner)
  1857. {
  1858. // and transition to the game ended state
  1859. SetViewTarget(EndGameFocus);
  1860. ClientGameEnded(EndGameFocus, bIsWinner);
  1861. }
  1862.  
  1863. /// @cond DOXYGEN_WARNINGS
  1864.  
  1865. void APlayerController::ClientGameEnded_Implementation(AActor* EndGameFocus, bool bIsWinner)
  1866. {
  1867. SetViewTarget(EndGameFocus);
  1868. }
  1869.  
  1870. /// @endcond
  1871.  
  1872. bool APlayerController::GetHitResultUnderCursor(ECollisionChannel TraceChannel, bool bTraceComplex, FHitResult& HitResult) const
  1873. {
  1874. ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
  1875. bool bHit = false;
  1876. if (LocalPlayer && LocalPlayer->ViewportClient)
  1877. {
  1878. FVector2D MousePosition;
  1879. if (LocalPlayer->ViewportClient->GetMousePosition(MousePosition))
  1880. {
  1881. bHit = GetHitResultAtScreenPosition(MousePosition, TraceChannel, bTraceComplex, HitResult);
  1882. }
  1883. }
  1884.  
  1885. if(!bHit) //If there was no hit we reset the results. This is redundant but helps Blueprint users
  1886. {
  1887. HitResult = FHitResult();
  1888. }
  1889.  
  1890. return bHit;
  1891. }
  1892.  
  1893. bool APlayerController::GetHitResultUnderCursorByChannel(ETraceTypeQuery TraceChannel, bool bTraceComplex, FHitResult& HitResult) const
  1894. {
  1895. ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
  1896. bool bHit = false;
  1897. if (LocalPlayer && LocalPlayer->ViewportClient)
  1898. {
  1899. FVector2D MousePosition;
  1900. if (LocalPlayer->ViewportClient->GetMousePosition(MousePosition))
  1901. {
  1902. bHit = GetHitResultAtScreenPosition(MousePosition, TraceChannel, bTraceComplex, HitResult);
  1903. }
  1904. }
  1905.  
  1906. if(!bHit) //If there was no hit we reset the results. This is redundant but helps Blueprint users
  1907. {
  1908. HitResult = FHitResult();
  1909. }
  1910.  
  1911. return bHit;
  1912. }
  1913.  
  1914. bool APlayerController::GetHitResultUnderCursorForObjects(const TArray<TEnumAsByte<EObjectTypeQuery> > & ObjectTypes, bool bTraceComplex, FHitResult& HitResult) const
  1915. {
  1916. ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
  1917. bool bHit = false;
  1918. if (LocalPlayer && LocalPlayer->ViewportClient)
  1919. {
  1920. FVector2D MousePosition;
  1921. if (LocalPlayer->ViewportClient->GetMousePosition(MousePosition))
  1922. {
  1923. bHit = GetHitResultAtScreenPosition(MousePosition, ObjectTypes, bTraceComplex, HitResult);
  1924. }
  1925. }
  1926.  
  1927. if(!bHit) //If there was no hit we reset the results. This is redundant but helps Blueprint users
  1928. {
  1929. HitResult = FHitResult();
  1930. }
  1931.  
  1932. return bHit;
  1933. }
  1934.  
  1935. bool APlayerController::GetHitResultUnderFinger(ETouchIndex::Type FingerIndex, ECollisionChannel TraceChannel, bool bTraceComplex, FHitResult& HitResult) const
  1936. {
  1937. bool bHit = false;
  1938. if (PlayerInput)
  1939. {
  1940. FVector2D TouchPosition;
  1941. bool bIsPressed = false;
  1942. GetInputTouchState(FingerIndex, TouchPosition.X, TouchPosition.Y, bIsPressed);
  1943. if (bIsPressed)
  1944. {
  1945. bHit = GetHitResultAtScreenPosition(TouchPosition, TraceChannel, bTraceComplex, HitResult);
  1946. }
  1947. }
  1948.  
  1949. if(!bHit) //If there was no hit we reset the results. This is redundant but helps Blueprint users
  1950. {
  1951. HitResult = FHitResult();
  1952. }
  1953.  
  1954. return bHit;
  1955. }
  1956.  
  1957. bool APlayerController::GetHitResultUnderFingerByChannel(ETouchIndex::Type FingerIndex, ETraceTypeQuery TraceChannel, bool bTraceComplex, FHitResult& HitResult) const
  1958. {
  1959. bool bHit = false;
  1960. if (PlayerInput)
  1961. {
  1962. FVector2D TouchPosition;
  1963. bool bIsPressed = false;
  1964. GetInputTouchState(FingerIndex, TouchPosition.X, TouchPosition.Y, bIsPressed);
  1965. if (bIsPressed)
  1966. {
  1967. bHit = GetHitResultAtScreenPosition(TouchPosition, TraceChannel, bTraceComplex, HitResult);
  1968. }
  1969. }
  1970.  
  1971. if(!bHit) //If there was no hit we reset the results. This is redundant but helps Blueprint users
  1972. {
  1973. HitResult = FHitResult();
  1974. }
  1975.  
  1976. return bHit;
  1977. }
  1978.  
  1979. bool APlayerController::GetHitResultUnderFingerForObjects(ETouchIndex::Type FingerIndex, const TArray<TEnumAsByte<EObjectTypeQuery> > & ObjectTypes, bool bTraceComplex, FHitResult& HitResult) const
  1980. {
  1981. bool bHit = false;
  1982. if (PlayerInput)
  1983. {
  1984. FVector2D TouchPosition;
  1985. bool bIsPressed = false;
  1986. GetInputTouchState(FingerIndex, TouchPosition.X, TouchPosition.Y, bIsPressed);
  1987. if (bIsPressed)
  1988. {
  1989. bHit = GetHitResultAtScreenPosition(TouchPosition, ObjectTypes, bTraceComplex, HitResult);
  1990. }
  1991. }
  1992.  
  1993. if(!bHit) //If there was no hit we reset the results. This is redundant but helps Blueprint users
  1994. {
  1995. HitResult = FHitResult();
  1996. }
  1997.  
  1998. return bHit;
  1999. }
  2000.  
  2001. bool APlayerController::DeprojectMousePositionToWorld(FVector& WorldLocation, FVector& WorldDirection) const
  2002. {
  2003. ULocalPlayer* const LocalPlayer = GetLocalPlayer();
  2004. if (LocalPlayer && LocalPlayer->ViewportClient)
  2005. {
  2006. FVector2D ScreenPosition;
  2007. if (LocalPlayer->ViewportClient->GetMousePosition(ScreenPosition))
  2008. {
  2009. return UGameplayStatics::DeprojectScreenToWorld(this, ScreenPosition, WorldLocation, WorldDirection);
  2010. }
  2011. }
  2012.  
  2013. return false;
  2014. }
  2015.  
  2016. bool APlayerController::DeprojectScreenPositionToWorld(float ScreenX, float ScreenY, FVector& WorldLocation, FVector& WorldDirection) const
  2017. {
  2018. return UGameplayStatics::DeprojectScreenToWorld(this, FVector2D(ScreenX, ScreenY), WorldLocation, WorldDirection);
  2019. }
  2020.  
  2021.  
  2022. bool APlayerController::ProjectWorldLocationToScreen(FVector WorldLocation, FVector2D& ScreenLocation, bool bPlayerViewportRelative) const
  2023. {
  2024. return UGameplayStatics::ProjectWorldToScreen(this, WorldLocation, ScreenLocation, bPlayerViewportRelative);
  2025. }
  2026.  
  2027. bool APlayerController::ProjectWorldLocationToScreenWithDistance(FVector WorldLocation, FVector& ScreenLocation, bool bPlayerViewportRelative) const
  2028. {
  2029. // find distance
  2030. ULocalPlayer const* const LP = GetLocalPlayer();
  2031. if (LP && LP->ViewportClient)
  2032. {
  2033. // get the projection data
  2034. FSceneViewProjectionData ProjectionData;
  2035. if (LP->GetProjectionData(LP->ViewportClient->Viewport, eSSP_FULL, /*out*/ ProjectionData))
  2036. {
  2037. FVector2D ScreenPosition2D;
  2038. FMatrix const ViewProjectionMatrix = ProjectionData.ComputeViewProjectionMatrix();
  2039. if ( FSceneView::ProjectWorldToScreen(WorldLocation, ProjectionData.GetConstrainedViewRect(), ViewProjectionMatrix, ScreenPosition2D) )
  2040. {
  2041. if ( bPlayerViewportRelative )
  2042. {
  2043. ScreenPosition2D -= FVector2D(ProjectionData.GetConstrainedViewRect().Min);
  2044. }
  2045.  
  2046. ScreenLocation = FVector(ScreenPosition2D.X, ScreenPosition2D.Y, FVector::Dist(ProjectionData.ViewOrigin, WorldLocation));
  2047.  
  2048. return true;
  2049. }
  2050. }
  2051. }
  2052.  
  2053. return false;
  2054. }
  2055.  
  2056. bool APlayerController::PostProcessWorldToScreen(FVector WorldLocation, FVector2D& ScreenLocation, bool bPlayerViewportRelative) const
  2057. {
  2058. return true;
  2059. }
  2060.  
  2061. bool APlayerController::GetHitResultAtScreenPosition(const FVector2D ScreenPosition, const ECollisionChannel TraceChannel, const FCollisionQueryParams& CollisionQueryParams, FHitResult& HitResult) const
  2062. {
  2063. // Early out if we clicked on a HUD hitbox
  2064. if (GetHUD() != NULL && GetHUD()->GetHitBoxAtCoordinates(ScreenPosition, true))
  2065. {
  2066. return false;
  2067. }
  2068.  
  2069. FVector WorldOrigin;
  2070. FVector WorldDirection;
  2071. if (UGameplayStatics::DeprojectScreenToWorld(this, ScreenPosition, WorldOrigin, WorldDirection) == true)
  2072. {
  2073. return GetWorld()->LineTraceSingleByChannel(HitResult, WorldOrigin, WorldOrigin + WorldDirection * HitResultTraceDistance, TraceChannel, CollisionQueryParams);
  2074. }
  2075.  
  2076. return false;
  2077. }
  2078.  
  2079. bool APlayerController::GetHitResultAtScreenPosition(const FVector2D ScreenPosition, const ECollisionChannel TraceChannel, bool bTraceComplex, FHitResult& HitResult) const
  2080. {
  2081. FCollisionQueryParams CollisionQueryParams(SCENE_QUERY_STAT(ClickableTrace), bTraceComplex );
  2082. return GetHitResultAtScreenPosition( ScreenPosition, TraceChannel, CollisionQueryParams, HitResult );
  2083. }
  2084.  
  2085. bool APlayerController::GetHitResultAtScreenPosition(const FVector2D ScreenPosition, const ETraceTypeQuery TraceChannel, bool bTraceComplex, FHitResult& HitResult) const
  2086. {
  2087. return GetHitResultAtScreenPosition( ScreenPosition, UEngineTypes::ConvertToCollisionChannel( TraceChannel ), bTraceComplex, HitResult );
  2088. }
  2089.  
  2090. bool APlayerController::GetHitResultAtScreenPosition(const FVector2D ScreenPosition, const TArray<TEnumAsByte<EObjectTypeQuery> > & ObjectTypes, bool bTraceComplex, FHitResult& HitResult) const
  2091. {
  2092. // Early out if we clicked on a HUD hitbox
  2093. if (GetHUD() != NULL && GetHUD()->GetHitBoxAtCoordinates(ScreenPosition, true))
  2094. {
  2095. return false;
  2096. }
  2097.  
  2098. FVector WorldOrigin;
  2099. FVector WorldDirection;
  2100. if (UGameplayStatics::DeprojectScreenToWorld(this, ScreenPosition, WorldOrigin, WorldDirection) == true)
  2101. {
  2102. FCollisionObjectQueryParams const ObjParam(ObjectTypes);
  2103. return GetWorld()->LineTraceSingleByObjectType(HitResult, WorldOrigin, WorldOrigin + WorldDirection * HitResultTraceDistance, ObjParam, FCollisionQueryParams(SCENE_QUERY_STAT(ClickableTrace), bTraceComplex));
  2104. }
  2105.  
  2106. return false;
  2107. }
  2108.  
  2109. void APlayerController::SetMouseLocation(const int X, const int Y)
  2110. {
  2111. ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>( Player );
  2112. if (LocalPlayer)
  2113. {
  2114. UGameViewportClient* ViewportClient = LocalPlayer->ViewportClient;
  2115. if (ViewportClient)
  2116. {
  2117. FViewport* Viewport = ViewportClient->Viewport;
  2118. if (Viewport)
  2119. {
  2120. Viewport->SetMouse( X, Y );
  2121. }
  2122. }
  2123. }
  2124. }
  2125.  
  2126. /* PlayerTick is only called if the PlayerController has a PlayerInput object. Therefore, it will not be called on servers for non-locally controlled playercontrollers. */
  2127. void APlayerController::PlayerTick( float DeltaTime )
  2128. {
  2129. if (!bShortConnectTimeOut)
  2130. {
  2131. bShortConnectTimeOut = true;
  2132. ServerShortTimeout();
  2133. }
  2134.  
  2135. TickPlayerInput(DeltaTime, DeltaTime == 0.f);
  2136.  
  2137. if ((Player != NULL) && (Player->PlayerController == this))
  2138. {
  2139. // Validate current state
  2140. bool bUpdateRotation = false;
  2141. if (IsInState(NAME_Playing))
  2142. {
  2143. if( GetPawn() == NULL )
  2144. {
  2145. ChangeState(NAME_Inactive);
  2146. }
  2147. else if (Player && GetPawn() && GetPawn() == AcknowledgedPawn)
  2148. {
  2149. bUpdateRotation = true;
  2150. }
  2151. }
  2152.  
  2153. if ( IsInState(NAME_Inactive) )
  2154. {
  2155. if (Role < ROLE_Authority)
  2156. {
  2157. SafeServerCheckClientPossession();
  2158. }
  2159.  
  2160. bUpdateRotation = !IsFrozen();
  2161. }
  2162. else if ( IsInState(NAME_Spectating) )
  2163. {
  2164. if (Role < ROLE_Authority)
  2165. {
  2166. SafeServerUpdateSpectatorState();
  2167. }
  2168.  
  2169. bUpdateRotation = true;
  2170. }
  2171.  
  2172. // Update rotation
  2173. if (bUpdateRotation)
  2174. {
  2175. UpdateRotation(DeltaTime);
  2176. }
  2177. }
  2178. }
  2179.  
  2180. void APlayerController::FlushPressedKeys()
  2181. {
  2182. if (PlayerInput)
  2183. {
  2184. PlayerInput->FlushPressedKeys();
  2185. }
  2186. }
  2187.  
  2188. bool APlayerController::InputKey(FKey Key, EInputEvent EventType, float AmountDepressed, bool bGamepad)
  2189. {
  2190.  
  2191. if (GEngine->XRSystem.IsValid())
  2192. {
  2193. auto XRInput = GEngine->XRSystem->GetXRInput();
  2194. if (XRInput && XRInput->HandleInputKey(PlayerInput, Key, EventType, AmountDepressed, bGamepad))
  2195. {
  2196. return true;
  2197. }
  2198. }
  2199.  
  2200. bool bResult = false;
  2201. if (PlayerInput)
  2202. {
  2203. bResult = PlayerInput->InputKey(Key, EventType, AmountDepressed, bGamepad);
  2204. if (bEnableClickEvents && (ClickEventKeys.Contains(Key) || ClickEventKeys.Contains(EKeys::AnyKey)))
  2205. {
  2206. FVector2D MousePosition;
  2207. UGameViewportClient* ViewportClient = CastChecked<ULocalPlayer>(Player)->ViewportClient;
  2208. if (ViewportClient && ViewportClient->GetMousePosition(MousePosition))
  2209. {
  2210. UPrimitiveComponent* ClickedPrimitive = NULL;
  2211. if (bEnableMouseOverEvents)
  2212. {
  2213. ClickedPrimitive = CurrentClickablePrimitive.Get();
  2214. }
  2215. else
  2216. {
  2217. FHitResult HitResult;
  2218. const bool bHit = GetHitResultAtScreenPosition(MousePosition, CurrentClickTraceChannel, true, HitResult);
  2219. if (bHit)
  2220. {
  2221. ClickedPrimitive = HitResult.Component.Get();
  2222. }
  2223. }
  2224. if( GetHUD() )
  2225. {
  2226. if (GetHUD()->UpdateAndDispatchHitBoxClickEvents(MousePosition, EventType))
  2227. {
  2228. ClickedPrimitive = NULL;
  2229. }
  2230. }
  2231.  
  2232. if (ClickedPrimitive)
  2233. {
  2234. switch(EventType)
  2235. {
  2236. case IE_Pressed:
  2237. case IE_DoubleClick:
  2238. ClickedPrimitive->DispatchOnClicked(Key);
  2239. break;
  2240.  
  2241. case IE_Released:
  2242. ClickedPrimitive->DispatchOnReleased(Key);
  2243. break;
  2244.  
  2245. case IE_Axis:
  2246. case IE_Repeat:
  2247. break;
  2248. }
  2249. }
  2250.  
  2251. bResult = true;
  2252. }
  2253. }
  2254. }
  2255.  
  2256. return bResult;
  2257. }
  2258.  
  2259. bool APlayerController::InputAxis(FKey Key, float Delta, float DeltaTime, int32 NumSamples, bool bGamepad)
  2260. {
  2261. bool bResult = false;
  2262.  
  2263. if (PlayerInput)
  2264. {
  2265. bResult = PlayerInput->InputAxis(Key, Delta, DeltaTime, NumSamples, bGamepad);
  2266. }
  2267.  
  2268. return bResult;
  2269. }
  2270.  
  2271. bool APlayerController::InputTouch(uint32 Handle, ETouchType::Type Type, const FVector2D& TouchLocation, float Force, FDateTime DeviceTimestamp, uint32 TouchpadIndex)
  2272. {
  2273. if (GEngine->XRSystem.IsValid())
  2274. {
  2275. auto XRInput = GEngine->XRSystem->GetXRInput();
  2276. if(XRInput && XRInput->HandleInputTouch(Handle, Type, TouchLocation, DeviceTimestamp, TouchpadIndex))
  2277. {
  2278. return true;
  2279. }
  2280. }
  2281.  
  2282. bool bResult = false;
  2283. if (PlayerInput)
  2284. {
  2285. bResult = PlayerInput->InputTouch(Handle, Type, TouchLocation, Force, DeviceTimestamp, TouchpadIndex);
  2286.  
  2287. if (bEnableTouchEvents || bEnableTouchOverEvents)
  2288. {
  2289. const ETouchIndex::Type FingerIndex = ETouchIndex::Type(Handle);
  2290.  
  2291. FHitResult HitResult;
  2292. const bool bHit = GetHitResultAtScreenPosition(TouchLocation, CurrentClickTraceChannel, true, HitResult);
  2293.  
  2294. UPrimitiveComponent* PreviousComponent = CurrentTouchablePrimitives[Handle].Get();
  2295. UPrimitiveComponent* CurrentComponent = (bHit ? HitResult.Component.Get() : NULL);
  2296.  
  2297. if (GetHUD())
  2298. {
  2299. if (Type == ETouchType::Began || Type == ETouchType::Ended)
  2300. {
  2301. if (GetHUD()->UpdateAndDispatchHitBoxClickEvents(TouchLocation, (Type == ETouchType::Began ? EInputEvent::IE_Pressed : EInputEvent::IE_Released)))
  2302. {
  2303. CurrentComponent = NULL;
  2304. }
  2305. }
  2306. }
  2307.  
  2308. switch(Type)
  2309. {
  2310. case ETouchType::Began:
  2311. // Give it a begin touch
  2312. if (bEnableTouchEvents && (CurrentComponent != NULL))
  2313. {
  2314. CurrentComponent->DispatchOnInputTouchBegin(FingerIndex);
  2315. }
  2316.  
  2317. // Give a touch enter event
  2318. if (bEnableTouchOverEvents)
  2319. {
  2320. UPrimitiveComponent::DispatchTouchOverEvents(FingerIndex, PreviousComponent, CurrentComponent);
  2321. CurrentTouchablePrimitives[Handle] = CurrentComponent;
  2322. }
  2323. break;
  2324. case ETouchType::Ended:
  2325. // Give it a touch exit
  2326. if (bEnableTouchEvents && (CurrentComponent != NULL))
  2327. {
  2328. CurrentComponent->DispatchOnInputTouchEnd(FingerIndex);
  2329. }
  2330.  
  2331. // Give it a end touch
  2332. if (bEnableTouchOverEvents)
  2333. {
  2334. // Handle the case where the finger moved faster than tick, and is being released over a different component than it was last dragged over
  2335. if ((PreviousComponent != CurrentComponent) && (PreviousComponent != NULL))
  2336. {
  2337. // First notify the old component that the touch left it to go to the current component
  2338. UPrimitiveComponent::DispatchTouchOverEvents(FingerIndex, PreviousComponent, CurrentComponent);
  2339. }
  2340.  
  2341. // Now notify that the current component is being released and thus the touch is leaving it
  2342. PreviousComponent = CurrentComponent;
  2343. CurrentComponent = NULL;
  2344. UPrimitiveComponent::DispatchTouchOverEvents(FingerIndex, PreviousComponent, CurrentComponent);
  2345. CurrentTouchablePrimitives[Handle] = CurrentComponent;
  2346. }
  2347. break;
  2348. default:
  2349. break;
  2350. };
  2351. }
  2352. }
  2353.  
  2354. return bResult;
  2355. }
  2356.  
  2357. bool APlayerController::InputMotion(const FVector& Tilt, const FVector& RotationRate, const FVector& Gravity, const FVector& Acceleration)
  2358. {
  2359. bool bResult = false;
  2360.  
  2361. if (PlayerInput)
  2362. {
  2363. bResult = PlayerInput->InputMotion(Tilt, RotationRate, Gravity, Acceleration);
  2364. }
  2365.  
  2366. return bResult;
  2367. }
  2368.  
  2369. bool APlayerController::ShouldShowMouseCursor() const
  2370. {
  2371. return bShowMouseCursor;
  2372. }
  2373.  
  2374. EMouseCursor::Type APlayerController::GetMouseCursor() const
  2375. {
  2376. if (ShouldShowMouseCursor())
  2377. {
  2378. return CurrentMouseCursor;
  2379. }
  2380.  
  2381. return EMouseCursor::None;
  2382. }
  2383.  
  2384. void APlayerController::SetupInputComponent()
  2385. {
  2386. // A subclass could create a different InputComponent class but still want the default bindings
  2387. if (InputComponent == NULL)
  2388. {
  2389. InputComponent = NewObject<UInputComponent>(this, TEXT("PC_InputComponent0"));
  2390. InputComponent->RegisterComponent();
  2391. }
  2392.  
  2393. if (UInputDelegateBinding::SupportsInputDelegate(GetClass()))
  2394. {
  2395. InputComponent->bBlockInput = bBlockInput;
  2396. UInputDelegateBinding::BindInputDelegates(GetClass(), InputComponent);
  2397. }
  2398. }
  2399.  
  2400.  
  2401. void APlayerController::BuildInputStack(TArray<UInputComponent*>& InputStack)
  2402. {
  2403. // Controlled pawn gets last dibs on the input stack
  2404. APawn* ControlledPawn = GetPawnOrSpectator();
  2405. if (ControlledPawn)
  2406. {
  2407. if (ControlledPawn->InputEnabled())
  2408. {
  2409. // Get the explicit input component that is created upon Pawn possession. This one gets last dibs.
  2410. if (ControlledPawn->InputComponent)
  2411. {
  2412. InputStack.Push(ControlledPawn->InputComponent);
  2413. }
  2414.  
  2415. // See if there is another InputComponent that was added to the Pawn's components array (possibly by script).
  2416. for (UActorComponent* ActorComponent : ControlledPawn->GetComponents())
  2417. {
  2418. UInputComponent* PawnInputComponent = Cast<UInputComponent>(ActorComponent);
  2419. if (PawnInputComponent && PawnInputComponent != ControlledPawn->InputComponent)
  2420. {
  2421. InputStack.Push(PawnInputComponent);
  2422. }
  2423. }
  2424. }
  2425. }
  2426.  
  2427. // LevelScriptActors are put on the stack next
  2428. for (ULevel* Level : GetWorld()->GetLevels())
  2429. {
  2430. ALevelScriptActor* ScriptActor = Level->GetLevelScriptActor();
  2431. if (ScriptActor)
  2432. {
  2433. if (ScriptActor->InputEnabled() && ScriptActor->InputComponent)
  2434. {
  2435. InputStack.Push(ScriptActor->InputComponent);
  2436. }
  2437. }
  2438. }
  2439.  
  2440. if (InputEnabled())
  2441. {
  2442. InputStack.Push(InputComponent);
  2443. }
  2444.  
  2445. // Components pushed on to the stack get priority
  2446. for (int32 Idx=0; Idx<CurrentInputStack.Num(); ++Idx)
  2447. {
  2448. UInputComponent* IC = CurrentInputStack[Idx].Get();
  2449. if (IC)
  2450. {
  2451. InputStack.Push(IC);
  2452. }
  2453. else
  2454. {
  2455. CurrentInputStack.RemoveAt(Idx--);
  2456. }
  2457. }
  2458. }
  2459.  
  2460. void APlayerController::ProcessPlayerInput(const float DeltaTime, const bool bGamePaused)
  2461. {
  2462. static TArray<UInputComponent*> InputStack;
  2463.  
  2464. // must be called non-recursively and on the game thread
  2465. check(IsInGameThread() && !InputStack.Num());
  2466.  
  2467. // process all input components in the stack, top down
  2468. {
  2469. SCOPE_CYCLE_COUNTER(STAT_PC_BuildInputStack);
  2470. BuildInputStack(InputStack);
  2471. }
  2472.  
  2473. // process the desired components
  2474. {
  2475. SCOPE_CYCLE_COUNTER(STAT_PC_ProcessInputStack);
  2476. PlayerInput->ProcessInputStack(InputStack, DeltaTime, bGamePaused);
  2477. }
  2478.  
  2479. InputStack.Reset();
  2480. }
  2481.  
  2482. void APlayerController::PreProcessInput(const float DeltaTime, const bool bGamePaused)
  2483. {
  2484. }
  2485.  
  2486. void APlayerController::PostProcessInput(const float DeltaTime, const bool bGamePaused)
  2487. {
  2488. if( IsLookInputIgnored() )
  2489. {
  2490. // zero look inputs
  2491. RotationInput = FRotator::ZeroRotator;
  2492. }
  2493. }
  2494.  
  2495. void APlayerController::ResetIgnoreInputFlags()
  2496. {
  2497. // The movement locks can be set in cinematic mode, but if a restart occurs, we don't want them to be reset.
  2498. if (!bCinemaDisableInputMove)
  2499. {
  2500. IgnoreMoveInput = GetDefault<APlayerController>()->IgnoreMoveInput;
  2501. }
  2502.  
  2503. if (!bCinemaDisableInputLook)
  2504. {
  2505. IgnoreLookInput = GetDefault<APlayerController>()->IgnoreLookInput;
  2506. }
  2507. }
  2508.  
  2509. void APlayerController::SetCinematicMode( bool bInCinematicMode, bool bAffectsMovement, bool bAffectsTurning)
  2510. {
  2511. if ( bAffectsMovement && (bInCinematicMode != bCinemaDisableInputMove) )
  2512. {
  2513. SetIgnoreMoveInput(bInCinematicMode);
  2514. bCinemaDisableInputMove = bInCinematicMode;
  2515. }
  2516. if ( bAffectsTurning && (bInCinematicMode != bCinemaDisableInputLook) )
  2517. {
  2518. SetIgnoreLookInput(bInCinematicMode);
  2519. bCinemaDisableInputLook = bInCinematicMode;
  2520. }
  2521. }
  2522.  
  2523.  
  2524. void APlayerController::SetViewTargetWithBlend(AActor* NewViewTarget, float BlendTime, EViewTargetBlendFunction BlendFunc, float BlendExp, bool bLockOutgoing)
  2525. {
  2526. FViewTargetTransitionParams TransitionParams;
  2527. TransitionParams.BlendTime = BlendTime;
  2528. TransitionParams.BlendFunction = BlendFunc;
  2529. TransitionParams.BlendExp = BlendExp;
  2530. TransitionParams.bLockOutgoing = bLockOutgoing;
  2531.  
  2532. SetViewTarget(NewViewTarget, TransitionParams);
  2533. }
  2534.  
  2535. /// @cond DOXYGEN_WARNINGS
  2536.  
  2537. void APlayerController::ClientSetViewTarget_Implementation( AActor* A, FViewTargetTransitionParams TransitionParams )
  2538. {
  2539. if (PlayerCameraManager && !PlayerCameraManager->bClientSimulatingViewTarget)
  2540. {
  2541. if( A == NULL )
  2542. {
  2543. ServerVerifyViewTarget();
  2544. return;
  2545. }
  2546. // don't force view to self while unpossessed (since server may be doing it having destroyed the pawn)
  2547. if ( IsInState(NAME_Inactive) && A == this )
  2548. {
  2549. return;
  2550. }
  2551. SetViewTarget(A, TransitionParams);
  2552. }
  2553. }
  2554.  
  2555. bool APlayerController::ServerVerifyViewTarget_Validate()
  2556. {
  2557. return true;
  2558. }
  2559.  
  2560. void APlayerController::ServerVerifyViewTarget_Implementation()
  2561. {
  2562. AActor* TheViewTarget = GetViewTarget();
  2563. if( TheViewTarget == this )
  2564. {
  2565. return;
  2566. }
  2567. ClientSetViewTarget( TheViewTarget );
  2568. }
  2569.  
  2570. /// @endcond
  2571.  
  2572. void APlayerController::SpawnPlayerCameraManager()
  2573. {
  2574. // servers and owning clients get cameras
  2575. // If no archetype specified, spawn an Engine.PlayerCameraManager. NOTE all games should specify an archetype.
  2576. FActorSpawnParameters SpawnInfo;
  2577. SpawnInfo.Owner = this;
  2578. SpawnInfo.Instigator = Instigator;
  2579. SpawnInfo.ObjectFlags |= RF_Transient; // We never want to save camera managers into a map
  2580. if (PlayerCameraManagerClass != NULL)
  2581. {
  2582. PlayerCameraManager = GetWorld()->SpawnActor<APlayerCameraManager>(PlayerCameraManagerClass, SpawnInfo);
  2583. }
  2584. else
  2585. {
  2586. PlayerCameraManager = GetWorld()->SpawnActor<APlayerCameraManager>(SpawnInfo);
  2587. }
  2588.  
  2589. if (PlayerCameraManager != NULL)
  2590. {
  2591. PlayerCameraManager->InitializeFor(this);
  2592. }
  2593. else
  2594. {
  2595. UE_LOG(LogPlayerController, Log, TEXT("Couldn't Spawn PlayerCameraManager for Player!!") );
  2596. }
  2597. }
  2598.  
  2599. void APlayerController::GetAudioListenerPosition(FVector& OutLocation, FVector& OutFrontDir, FVector& OutRightDir)
  2600. {
  2601. FVector ViewLocation;
  2602. FRotator ViewRotation;
  2603.  
  2604. if (bOverrideAudioListener)
  2605. {
  2606. USceneComponent* ListenerComponent = AudioListenerComponent.Get();
  2607. if (ListenerComponent != nullptr)
  2608. {
  2609. ViewRotation = ListenerComponent->GetComponentRotation() + AudioListenerRotationOverride;
  2610. ViewLocation = ListenerComponent->GetComponentLocation() + ViewRotation.RotateVector(AudioListenerLocationOverride);
  2611. }
  2612. else
  2613. {
  2614. ViewLocation = AudioListenerLocationOverride;
  2615. ViewRotation = AudioListenerRotationOverride;
  2616. }
  2617. }
  2618. else
  2619. {
  2620. GetPlayerViewPoint(ViewLocation, ViewRotation);
  2621. }
  2622.  
  2623. const FRotationTranslationMatrix ViewRotationMatrix(ViewRotation, ViewLocation);
  2624.  
  2625. OutLocation = ViewLocation;
  2626. OutFrontDir = ViewRotationMatrix.GetUnitAxis( EAxis::X );
  2627. OutRightDir = ViewRotationMatrix.GetUnitAxis( EAxis::Y );
  2628. }
  2629.  
  2630. bool APlayerController::GetAudioListenerAttenuationOverridePosition(FVector& OutLocation)
  2631. {
  2632. if (bOverrideAudioAttenuationListener)
  2633. {
  2634. USceneComponent* ListenerComponent = AudioListenerAttenuationComponent.Get();
  2635. if (ListenerComponent)
  2636. {
  2637. OutLocation = ListenerComponent->GetComponentLocation() + AudioListenerAttenuationOverride;
  2638. }
  2639. else
  2640. {
  2641. OutLocation = AudioListenerAttenuationOverride;
  2642. }
  2643. return true;
  2644. }
  2645. return false;
  2646. }
  2647.  
  2648.  
  2649. void APlayerController::SetAudioListenerOverride(USceneComponent* AttachedComponent, FVector Location, FRotator Rotation)
  2650. {
  2651. bOverrideAudioListener = true;
  2652. AudioListenerComponent = AttachedComponent;
  2653. AudioListenerLocationOverride = Location;
  2654. AudioListenerRotationOverride = Rotation;
  2655. }
  2656.  
  2657. void APlayerController::ClearAudioListenerOverride()
  2658. {
  2659. bOverrideAudioListener = false;
  2660. AudioListenerComponent = nullptr;
  2661. }
  2662.  
  2663. void APlayerController::SetAudioListenerAttenuationOverride(USceneComponent* AttachToComponent, FVector AttenuationLocationOverride)
  2664. {
  2665. bOverrideAudioAttenuationListener = true;
  2666. AudioListenerAttenuationComponent = AttachToComponent;
  2667. AudioListenerAttenuationOverride = AttenuationLocationOverride;
  2668. }
  2669.  
  2670. void APlayerController::ClearAudioListenerAttenuationOverride()
  2671. {
  2672. bOverrideAudioAttenuationListener = false;
  2673. AudioListenerAttenuationComponent = nullptr;
  2674. }
  2675.  
  2676. /// @cond DOXYGEN_WARNINGS
  2677.  
  2678. bool APlayerController::ServerCheckClientPossession_Validate()
  2679. {
  2680. return true;
  2681. }
  2682.  
  2683. void APlayerController::ServerCheckClientPossession_Implementation()
  2684. {
  2685. if (AcknowledgedPawn != GetPawn())
  2686. {
  2687. // Client already throttles their call to this function, so respond immediately by resetting LastRetryClientTime
  2688. LastRetryPlayerTime = ForceRetryClientRestartTime;
  2689. SafeRetryClientRestart();
  2690. }
  2691. }
  2692.  
  2693. bool APlayerController::ServerCheckClientPossessionReliable_Validate()
  2694. {
  2695. return true;
  2696. }
  2697.  
  2698. void APlayerController::ServerCheckClientPossessionReliable_Implementation()
  2699. {
  2700. ServerCheckClientPossession_Implementation();
  2701. }
  2702.  
  2703. /// @endcond
  2704.  
  2705. void APlayerController::SafeServerCheckClientPossession()
  2706. {
  2707. if (GetPawn() && AcknowledgedPawn != GetPawn())
  2708. {
  2709. UWorld* World = GetWorld();
  2710. if (World->TimeSince(LastRetryPlayerTime) > RetryServerAcknowledgeThrottleTime)
  2711. {
  2712. ServerCheckClientPossession();
  2713. LastRetryPlayerTime = World->TimeSeconds;
  2714. }
  2715. }
  2716. }
  2717.  
  2718. void APlayerController::SafeServerUpdateSpectatorState()
  2719. {
  2720. if (IsInState(NAME_Spectating))
  2721. {
  2722. UWorld* World = GetWorld();
  2723. if (World->TimeSince(LastSpectatorStateSynchTime) > RetryServerCheckSpectatorThrottleTime)
  2724. {
  2725. ServerSetSpectatorLocation(GetFocalLocation(), GetControlRotation());
  2726. LastSpectatorStateSynchTime = World->TimeSeconds;
  2727. }
  2728. }
  2729. }
  2730.  
  2731. /// @cond DOXYGEN_WARNINGS
  2732.  
  2733. bool APlayerController::ServerSetSpectatorLocation_Validate(FVector NewLoc, FRotator NewRot)
  2734. {
  2735. return true;
  2736. }
  2737.  
  2738. void APlayerController::ServerSetSpectatorLocation_Implementation(FVector NewLoc, FRotator NewRot)
  2739. {
  2740. UWorld* World = GetWorld();
  2741. if ( IsInState(NAME_Spectating) )
  2742. {
  2743. LastSpectatorSyncLocation = NewLoc;
  2744. LastSpectatorSyncRotation = NewRot;
  2745. if ( World->TimeSeconds - LastSpectatorStateSynchTime > 2.f )
  2746. {
  2747. ClientGotoState(GetStateName());
  2748. LastSpectatorStateSynchTime = World->TimeSeconds;
  2749. }
  2750. }
  2751. // if we receive this with !bIsSpectating, the client is in the wrong state; tell it what state it should be in
  2752. else if (World->TimeSeconds != LastSpectatorStateSynchTime)
  2753. {
  2754. if (AcknowledgedPawn != GetPawn())
  2755. {
  2756. SafeRetryClientRestart();
  2757. }
  2758. else
  2759. {
  2760. ClientGotoState(GetStateName());
  2761. ClientSetViewTarget(GetViewTarget());
  2762. }
  2763.  
  2764. LastSpectatorStateSynchTime = World->TimeSeconds;
  2765. }
  2766. }
  2767.  
  2768. bool APlayerController::ServerSetSpectatorWaiting_Validate(bool bWaiting)
  2769. {
  2770. return true;
  2771. }
  2772.  
  2773. void APlayerController::ServerSetSpectatorWaiting_Implementation(bool bWaiting)
  2774. {
  2775. if (IsInState(NAME_Spectating))
  2776. {
  2777. bPlayerIsWaiting = true;
  2778. }
  2779. }
  2780.  
  2781. void APlayerController::ClientSetSpectatorWaiting_Implementation(bool bWaiting)
  2782. {
  2783. if (IsInState(NAME_Spectating))
  2784. {
  2785. bPlayerIsWaiting = true;
  2786. }
  2787. }
  2788.  
  2789. bool APlayerController::ServerViewNextPlayer_Validate()
  2790. {
  2791. return true;
  2792. }
  2793.  
  2794. void APlayerController::ServerViewNextPlayer_Implementation()
  2795. {
  2796. if (IsInState(NAME_Spectating))
  2797. {
  2798. ViewAPlayer(+1);
  2799. }
  2800. }
  2801.  
  2802. bool APlayerController::ServerViewPrevPlayer_Validate()
  2803. {
  2804. return true;
  2805. }
  2806.  
  2807. void APlayerController::ServerViewPrevPlayer_Implementation()
  2808. {
  2809. if (IsInState(NAME_Spectating))
  2810. {
  2811. ViewAPlayer(-1);
  2812. }
  2813. }
  2814.  
  2815. /// @endcond
  2816.  
  2817. APlayerState* APlayerController::GetNextViewablePlayer(int32 dir)
  2818. {
  2819. int32 CurrentIndex = -1;
  2820.  
  2821. UWorld* World = GetWorld();
  2822. AGameModeBase* GameMode = World->GetAuthGameMode();
  2823. AGameStateBase* GameState = World->GetGameState();
  2824.  
  2825. if (PlayerCameraManager->ViewTarget.PlayerState )
  2826. {
  2827. // Find index of current viewtarget's PlayerState
  2828. for ( int32 i=0; i<GameState->PlayerArray.Num(); i++ )
  2829. {
  2830. if (PlayerCameraManager->ViewTarget.PlayerState == GameState->PlayerArray[i])
  2831. {
  2832. CurrentIndex = i;
  2833. break;
  2834. }
  2835. }
  2836. }
  2837.  
  2838. // Find next valid viewtarget in appropriate direction
  2839. int32 NewIndex;
  2840. for ( NewIndex=CurrentIndex+dir; (NewIndex>=0)&&(NewIndex<GameState->PlayerArray.Num()); NewIndex=NewIndex+dir )
  2841. {
  2842. APlayerState* const NextPlayerState = GameState->PlayerArray[NewIndex];
  2843. AController* NextController = (NextPlayerState ? Cast<AController>(NextPlayerState->GetOwner()) : nullptr);
  2844. if ( NextController && NextController->GetPawn() != nullptr && GameMode->CanSpectate(this, NextPlayerState) )
  2845. {
  2846. return NextPlayerState;
  2847. }
  2848. }
  2849.  
  2850. // wrap around
  2851. CurrentIndex = (NewIndex < 0) ? GameState->PlayerArray.Num() : -1;
  2852. for ( NewIndex=CurrentIndex+dir; (NewIndex>=0)&&(NewIndex<GameState->PlayerArray.Num()); NewIndex=NewIndex+dir )
  2853. {
  2854. APlayerState* const NextPlayerState = GameState->PlayerArray[NewIndex];
  2855. AController* NextController = (NextPlayerState ? Cast<AController>(NextPlayerState->GetOwner()) : nullptr);
  2856. if ( NextController && NextController->GetPawn() != nullptr && GameMode->CanSpectate(this, NextPlayerState) )
  2857. {
  2858. return NextPlayerState;
  2859. }
  2860. }
  2861.  
  2862. return nullptr;
  2863. }
  2864.  
  2865. void APlayerController::ViewAPlayer(int32 dir)
  2866. {
  2867. APlayerState* const NextPlayerState = GetNextViewablePlayer(dir);
  2868.  
  2869. if ( NextPlayerState != nullptr )
  2870. {
  2871. SetViewTarget(NextPlayerState);
  2872. }
  2873. }
  2874.  
  2875. /// @cond DOXYGEN_WARNINGS
  2876.  
  2877. bool APlayerController::ServerViewSelf_Validate(FViewTargetTransitionParams TransitionParams)
  2878. {
  2879. return true;
  2880. }
  2881.  
  2882. void APlayerController::ServerViewSelf_Implementation(FViewTargetTransitionParams TransitionParams)
  2883. {
  2884. if (IsInState(NAME_Spectating))
  2885. {
  2886. ResetCameraMode();
  2887. SetViewTarget( this, TransitionParams );
  2888. ClientSetViewTarget( this, TransitionParams );
  2889. }
  2890. }
  2891.  
  2892. /// @endcond
  2893.  
  2894. void APlayerController::StartFire( uint8 FireModeNum )
  2895. {
  2896. if ( ((IsInState(NAME_Spectating) && bPlayerIsWaiting) || IsInState(NAME_Inactive)) && !IsFrozen() )
  2897. {
  2898. ServerRestartPlayer();
  2899. }
  2900. else if ( IsInState(NAME_Spectating) )
  2901. {
  2902. ServerViewNextPlayer();
  2903. }
  2904. else if ( GetPawn() && !bCinematicMode && !GetWorld()->bPlayersOnly )
  2905. {
  2906. GetPawn()->PawnStartFire( FireModeNum );
  2907. }
  2908. }
  2909.  
  2910. bool APlayerController::NotifyServerReceivedClientData(APawn* InPawn, float TimeStamp)
  2911. {
  2912. if (GetPawn() != InPawn || (GetNetMode() == NM_Client))
  2913. {
  2914. return false;
  2915. }
  2916.  
  2917. if (AcknowledgedPawn != GetPawn())
  2918. {
  2919. SafeRetryClientRestart();
  2920. return false;
  2921. }
  2922.  
  2923. return true;
  2924. }
  2925.  
  2926. /// @cond DOXYGEN_WARNINGS
  2927.  
  2928. bool APlayerController::ServerRestartPlayer_Validate()
  2929. {
  2930. return true;
  2931. }
  2932.  
  2933. void APlayerController::ServerRestartPlayer_Implementation()
  2934. {
  2935. UE_LOG(LogPlayerController, Verbose, TEXT("SERVER RESTART PLAYER"));
  2936. if ( GetNetMode() == NM_Client )
  2937. {
  2938. return;
  2939. }
  2940.  
  2941. if ( IsInState(NAME_Inactive) || (IsInState(NAME_Spectating) && bPlayerIsWaiting) )
  2942. {
  2943. AGameModeBase* const GameMode = GetWorld()->GetAuthGameMode();
  2944. if ( !GameMode->PlayerCanRestart(this) )
  2945. {
  2946. return;
  2947. }
  2948.  
  2949. // If we're still attached to a Pawn, leave it
  2950. if ( GetPawn() != NULL )
  2951. {
  2952. UnPossess();
  2953. }
  2954.  
  2955. GameMode->RestartPlayer(this);
  2956. }
  2957. else if ( GetPawn() != NULL )
  2958. {
  2959. ClientRetryClientRestart(GetPawn());
  2960. }
  2961. }
  2962.  
  2963. /// @endcond
  2964.  
  2965. bool APlayerController::CanRestartPlayer()
  2966. {
  2967. return PlayerState && !PlayerState->bOnlySpectator && HasClientLoadedCurrentWorld() && PendingSwapConnection == NULL;
  2968. }
  2969.  
  2970. /// @cond DOXYGEN_WARNINGS
  2971.  
  2972. void APlayerController::ClientIgnoreMoveInput_Implementation(bool bIgnore)
  2973. {
  2974. SetIgnoreMoveInput(bIgnore);
  2975. }
  2976.  
  2977. void APlayerController::ClientIgnoreLookInput_Implementation(bool bIgnore)
  2978. {
  2979. SetIgnoreLookInput(bIgnore);
  2980. }
  2981.  
  2982. /// @endcond
  2983.  
  2984. void APlayerController::DisplayDebug(class UCanvas* Canvas, const FDebugDisplayInfo& DebugDisplay, float& YL, float& YPos)
  2985. {
  2986. Super::DisplayDebug(Canvas, DebugDisplay, YL, YPos);
  2987.  
  2988. FDisplayDebugManager& DisplayDebugManager = Canvas->DisplayDebugManager;
  2989. DisplayDebugManager.SetDrawColor(FColor(255, 255, 0));
  2990. DisplayDebugManager.DrawString(FString::Printf(TEXT("STATE %s"), *GetStateName().ToString()));
  2991.  
  2992. if (DebugDisplay.IsDisplayOn(NAME_Camera))
  2993. {
  2994. if (PlayerCameraManager != nullptr)
  2995. {
  2996. DisplayDebugManager.DrawString(FString(TEXT("<<<< CAMERA >>>>")));
  2997. PlayerCameraManager->DisplayDebug(Canvas, DebugDisplay, YL, YPos);
  2998. }
  2999. else
  3000. {
  3001. DisplayDebugManager.SetDrawColor(FColor::Red);
  3002. DisplayDebugManager.DrawString(FString(TEXT("<<<< NO CAMERA >>>>")));
  3003. }
  3004. }
  3005. if ( DebugDisplay.IsDisplayOn(NAME_Input) )
  3006. {
  3007. TArray<UInputComponent*> InputStack;
  3008. BuildInputStack(InputStack);
  3009.  
  3010. DisplayDebugManager.SetDrawColor(FColor::White);
  3011. DisplayDebugManager.DrawString(FString(TEXT("<<<< INPUT STACK >>>")));
  3012.  
  3013. for(int32 i=InputStack.Num() - 1; i >= 0; --i)
  3014. {
  3015. AActor* InputComponentOwner = InputStack[i]->GetOwner();
  3016. DisplayDebugManager.SetDrawColor(FColor::White);
  3017. if (InputComponentOwner)
  3018. {
  3019. DisplayDebugManager.DrawString(FString::Printf(TEXT(" %s.%s"), *InputComponentOwner->GetName(), *InputStack[i]->GetName()));
  3020. }
  3021. else
  3022. {
  3023. DisplayDebugManager.DrawString(FString::Printf(TEXT(" %s"), *InputStack[i]->GetName()));
  3024. }
  3025. }
  3026.  
  3027. if (PlayerInput)
  3028. {
  3029. PlayerInput->DisplayDebug(Canvas, DebugDisplay, YL, YPos);
  3030. }
  3031. else
  3032. {
  3033. DisplayDebugManager.SetDrawColor(FColor::Red);
  3034. DisplayDebugManager.DrawString(FString(TEXT("NO INPUT")));
  3035. }
  3036. }
  3037. if ( DebugDisplay.IsDisplayOn("ForceFeedback"))
  3038. {
  3039. DisplayDebugManager.SetDrawColor(FColor::White);
  3040. DisplayDebugManager.DrawString(FString::Printf(TEXT("Force Feedback - Enabled: %s LL: %.2f LS: %.2f RL: %.2f RS: %.2f"), (bForceFeedbackEnabled ? TEXT("true") : TEXT("false")), ForceFeedbackValues.LeftLarge, ForceFeedbackValues.LeftSmall, ForceFeedbackValues.RightLarge, ForceFeedbackValues.RightSmall));
  3041. DisplayDebugManager.DrawString(FString::Printf(TEXT("Pawn: %s"), this->AcknowledgedPawn ? *this->AcknowledgedPawn->GetFName().ToString() : TEXT("none")));
  3042.  
  3043. #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
  3044. DisplayDebugManager.DrawString(TEXT("-------------Last Played Force Feedback--------------"));
  3045. DisplayDebugManager.DrawString(TEXT("Name Tag Duration IsLooping StartTime"));
  3046. const float CurrentTime = GetWorld()->GetTimeSeconds();
  3047. for (int32 i = ForceFeedbackEffectHistoryEntries.Num() - 1; i >= 0; --i)
  3048. {
  3049. if (CurrentTime > ForceFeedbackEffectHistoryEntries[i].TimeShown + 5.0f)
  3050. {
  3051. ForceFeedbackEffectHistoryEntries.RemoveAtSwap(i, 1, /*bAllowShrinking=*/ false);
  3052. }
  3053. else
  3054. {
  3055. const FActiveForceFeedbackEffect& LastActiveEffect = ForceFeedbackEffectHistoryEntries[i].LastActiveForceFeedbackEffect;
  3056. const FString HistoryEntry = FString::Printf(TEXT("%s %s %f %s %f"),
  3057. *LastActiveEffect.ForceFeedbackEffect->GetFName().ToString(),
  3058. *LastActiveEffect.Tag.ToString(),
  3059. LastActiveEffect.ForceFeedbackEffect->GetDuration(),
  3060. (LastActiveEffect.bLooping ? TEXT("true") : TEXT("false")),
  3061. ForceFeedbackEffectHistoryEntries[i].TimeShown);
  3062. DisplayDebugManager.DrawString(HistoryEntry);
  3063. }
  3064. }
  3065. DisplayDebugManager.DrawString(TEXT("-----------------------------------------------------"));
  3066.  
  3067. DisplayDebugManager.DrawString(TEXT("----------Current Playing Force Feedback-------------"));
  3068. DisplayDebugManager.DrawString(TEXT("Name Tag/Component Distance Duration IsLooping PlayTime"));
  3069. for (int32 Index = ActiveForceFeedbackEffects.Num() - 1; Index >= 0; --Index)
  3070. {
  3071. const FActiveForceFeedbackEffect& ActiveEffect = ActiveForceFeedbackEffects[Index];
  3072. FForceFeedbackValues ActiveValues;
  3073. ActiveEffect.GetValues(ActiveValues);
  3074. if (ActiveValues.LeftLarge > 0.f || ActiveValues.LeftSmall > 0.f || ActiveValues.RightLarge > 0.f || ActiveValues.RightSmall > 0.f)
  3075. {
  3076. const FString ActiveEntry = FString::Printf(TEXT("%s %s N/A %.2f %s %.2f - LL: %.2f LS: %.2f RL: %.2f RS: %.2f"),
  3077. *ActiveEffect.ForceFeedbackEffect->GetFName().ToString(),
  3078. *ActiveEffect.Tag.ToString(),
  3079. ActiveEffect.ForceFeedbackEffect->GetDuration(),
  3080. (ActiveEffect.bLooping ? TEXT("true") : TEXT("false")),
  3081. ActiveEffect.PlayTime,
  3082. ActiveValues.LeftLarge, ActiveValues.LeftSmall, ActiveValues.RightLarge, ActiveValues.RightSmall);
  3083. DisplayDebugManager.DrawString(ActiveEntry);
  3084. }
  3085. }
  3086. if (FForceFeedbackManager* FFM = FForceFeedbackManager::Get(GetWorld()))
  3087. {
  3088. FFM->DrawDebug(GetFocalLocation(), DisplayDebugManager);
  3089. }
  3090. DisplayDebugManager.DrawString(TEXT("-----------------------------------------------------"));
  3091. #endif
  3092. }
  3093.  
  3094. YPos = DisplayDebugManager.GetYPos();
  3095. }
  3096.  
  3097. void APlayerController::SetCinematicMode(bool bInCinematicMode, bool bHidePlayer, bool bAffectsHUD, bool bAffectsMovement, bool bAffectsTurning)
  3098. {
  3099. bCinematicMode = bInCinematicMode;
  3100. bHidePawnInCinematicMode = bCinematicMode && bHidePlayer;
  3101.  
  3102. // If we have a pawn we need to determine if we should show/hide the player
  3103. if (GetPawn() != NULL)
  3104. {
  3105. // Only hide the pawn if in cinematic mode and we want to
  3106. if (bCinematicMode && bHidePawnInCinematicMode)
  3107. {
  3108. GetPawn()->SetActorHiddenInGame(true);
  3109. }
  3110. // Always safe to show the pawn when not in cinematic mode
  3111. else if (!bCinematicMode)
  3112. {
  3113. GetPawn()->SetActorHiddenInGame(false);
  3114. }
  3115. }
  3116.  
  3117. // Let the input system know about cinematic mode
  3118. SetCinematicMode(bCinematicMode, bAffectsMovement, bAffectsTurning);
  3119.  
  3120. // Replicate to the client
  3121. ClientSetCinematicMode(bCinematicMode, bAffectsMovement, bAffectsTurning, bAffectsHUD);
  3122. }
  3123.  
  3124. /// @cond DOXYGEN_WARNINGS
  3125.  
  3126. void APlayerController::ClientSetCinematicMode_Implementation(bool bInCinematicMode, bool bAffectsMovement, bool bAffectsTurning, bool bAffectsHUD)
  3127. {
  3128. bCinematicMode = bInCinematicMode;
  3129.  
  3130. // If there's a HUD, set whether it should be shown or not
  3131. if (MyHUD && bAffectsHUD)
  3132. {
  3133. MyHUD->bShowHUD = !bCinematicMode;
  3134. ULocalPlayer* LocPlayer = Cast<ULocalPlayer>(Player);
  3135. if (VirtualJoystick.IsValid())
  3136. {
  3137. VirtualJoystick->SetJoystickVisibility(MyHUD->bShowHUD, true);
  3138. }
  3139. }
  3140.  
  3141. // Let the input system know about cinematic mode
  3142. SetCinematicMode(bCinematicMode, bAffectsMovement, bAffectsTurning);
  3143. }
  3144.  
  3145. void APlayerController::ClientForceGarbageCollection_Implementation()
  3146. {
  3147. GEngine->ForceGarbageCollection();
  3148. }
  3149.  
  3150. /// @endcond
  3151.  
  3152. void APlayerController::LevelStreamingStatusChanged(ULevelStreaming* LevelObject, bool bNewShouldBeLoaded, bool bNewShouldBeVisible, bool bNewShouldBlockOnLoad, int32 LODIndex )
  3153. {
  3154. ClientUpdateLevelStreamingStatus(NetworkRemapPath(LevelObject->GetWorldAssetPackageFName(), false), bNewShouldBeLoaded, bNewShouldBeVisible, bNewShouldBlockOnLoad, LODIndex);
  3155. }
  3156.  
  3157. /// @cond DOXYGEN_WARNINGS
  3158.  
  3159. void APlayerController::ClientPrepareMapChange_Implementation(FName LevelName, bool bFirst, bool bLast)
  3160. {
  3161. // Only call on the first local player controller to handle it being called on multiple PCs for splitscreen.
  3162. if (GetGameInstance() == nullptr)
  3163. {
  3164. return;
  3165. }
  3166.  
  3167. APlayerController* PlayerController = GetGameInstance()->GetFirstLocalPlayerController();
  3168. if( PlayerController != this )
  3169. {
  3170. return;
  3171. }
  3172.  
  3173. if (bFirst)
  3174. {
  3175. PendingMapChangeLevelNames.Empty();
  3176. GetWorldTimerManager().ClearTimer(TimerHandle_DelayedPrepareMapChange);
  3177. }
  3178. PendingMapChangeLevelNames.Add(LevelName);
  3179. if (bLast)
  3180. {
  3181. DelayedPrepareMapChange();
  3182. }
  3183. }
  3184.  
  3185. /// @endcond
  3186.  
  3187. void APlayerController::DelayedPrepareMapChange()
  3188. {
  3189. UWorld* World = GetWorld();
  3190. if (World->IsPreparingMapChange())
  3191. {
  3192. // we must wait for the previous one to complete
  3193. GetWorldTimerManager().SetTimer(TimerHandle_DelayedPrepareMapChange, this, &APlayerController::DelayedPrepareMapChange, 0.01f );
  3194. }
  3195. else
  3196. {
  3197. World->PrepareMapChange(PendingMapChangeLevelNames);
  3198. }
  3199. }
  3200.  
  3201. /// @cond DOXYGEN_WARNINGS
  3202.  
  3203. void APlayerController::ClientCommitMapChange_Implementation()
  3204. {
  3205. if (GetWorldTimerManager().IsTimerActive(TimerHandle_DelayedPrepareMapChange))
  3206. {
  3207. GetWorldTimerManager().SetTimer(TimerHandle_ClientCommitMapChange, this, &APlayerController::ClientCommitMapChange, 0.01f);
  3208. }
  3209. else
  3210. {
  3211. if (bAutoManageActiveCameraTarget)
  3212. {
  3213. if (GetPawnOrSpectator() != NULL)
  3214. {
  3215. AutoManageActiveCameraTarget(GetPawnOrSpectator());
  3216. }
  3217. else
  3218. {
  3219. AutoManageActiveCameraTarget(this);
  3220. }
  3221. }
  3222. GetWorld()->CommitMapChange();
  3223. }
  3224. }
  3225.  
  3226. void APlayerController::ClientCancelPendingMapChange_Implementation()
  3227. {
  3228. GetWorld()->CancelPendingMapChange();
  3229. }
  3230.  
  3231. void APlayerController::ClientSetBlockOnAsyncLoading_Implementation()
  3232. {
  3233. GetWorld()->bRequestedBlockOnAsyncLoading = true;
  3234. }
  3235.  
  3236. /// @endcond
  3237.  
  3238. void APlayerController::GetSeamlessTravelActorList(bool bToEntry, TArray<AActor*>& ActorList)
  3239. {
  3240. if (MyHUD != NULL)
  3241. {
  3242. ActorList.Add(MyHUD);
  3243. }
  3244.  
  3245. // Should player camera persist or just be recreated? (clients have to recreate on host)
  3246. ActorList.Add(PlayerCameraManager);
  3247. }
  3248.  
  3249.  
  3250. void APlayerController::SeamlessTravelTo(APlayerController* NewPC)
  3251. {
  3252. CleanUpAudioComponents();
  3253. }
  3254.  
  3255. void APlayerController::SeamlessTravelFrom(APlayerController* OldPC)
  3256. {
  3257. // copy PlayerState data
  3258. if (OldPC->PlayerState)
  3259. {
  3260. OldPC->PlayerState->Reset();
  3261. OldPC->PlayerState->SeamlessTravelTo(PlayerState);
  3262.  
  3263. //@fixme: need a way to replace PlayerStates that doesn't cause incorrect "player left the game"/"player entered the game" messages
  3264. OldPC->PlayerState->Destroy();
  3265. OldPC->PlayerState = NULL;
  3266. }
  3267. }
  3268.  
  3269. void APlayerController::PostSeamlessTravel()
  3270. {
  3271. // Track the last completed seamless travel for the player
  3272. LastCompletedSeamlessTravelCount = SeamlessTravelCount;
  3273.  
  3274. CleanUpAudioComponents();
  3275.  
  3276. if (PlayerCameraManager == nullptr)
  3277. {
  3278. SpawnPlayerCameraManager();
  3279. }
  3280.  
  3281. }
  3282.  
  3283. /// @cond DOXYGEN_WARNINGS
  3284.  
  3285. void APlayerController::ClientEnableNetworkVoice_Implementation(bool bEnable)
  3286. {
  3287. ToggleSpeaking(bEnable);
  3288. }
  3289.  
  3290. /// @endcond
  3291.  
  3292. void APlayerController::StartTalking()
  3293. {
  3294. ToggleSpeaking(true);
  3295. }
  3296.  
  3297. void APlayerController::StopTalking()
  3298. {
  3299. ToggleSpeaking(false);
  3300. }
  3301.  
  3302. void APlayerController::ToggleSpeaking(bool bSpeaking)
  3303. {
  3304. ULocalPlayer* LP = Cast<ULocalPlayer>(Player);
  3305. if (LP != NULL)
  3306. {
  3307. UWorld* World = GetWorld();
  3308. if (bSpeaking)
  3309. {
  3310. UOnlineEngineInterface::Get()->StartNetworkedVoice(World, LP->GetControllerId());
  3311. }
  3312. else
  3313. {
  3314. UOnlineEngineInterface::Get()->StopNetworkedVoice(World, LP->GetControllerId());
  3315. }
  3316. }
  3317. }
  3318.  
  3319. /// @cond DOXYGEN_WARNINGS
  3320.  
  3321. void APlayerController::ClientVoiceHandshakeComplete_Implementation()
  3322. {
  3323. MuteList.bHasVoiceHandshakeCompleted = true;
  3324. }
  3325.  
  3326. /// @endcond
  3327.  
  3328. void APlayerController::GameplayMutePlayer(const FUniqueNetIdRepl& PlayerNetId)
  3329. {
  3330. if (PlayerNetId.IsValid())
  3331. {
  3332. MuteList.GameplayMutePlayer(this, PlayerNetId);
  3333. }
  3334. }
  3335.  
  3336. void APlayerController::GameplayUnmutePlayer(const FUniqueNetIdRepl& PlayerNetId)
  3337. {
  3338. if (PlayerNetId.IsValid())
  3339. {
  3340. MuteList.GameplayUnmutePlayer(this, PlayerNetId);
  3341. }
  3342. }
  3343.  
  3344. /// @cond DOXYGEN_WARNINGS
  3345.  
  3346. void APlayerController::ServerMutePlayer_Implementation(FUniqueNetIdRepl PlayerId)
  3347. {
  3348. MuteList.ServerMutePlayer(this, PlayerId);
  3349. }
  3350.  
  3351. bool APlayerController::ServerMutePlayer_Validate(FUniqueNetIdRepl PlayerId)
  3352. {
  3353. if (!PlayerId.IsValid())
  3354. {
  3355. return false;
  3356. }
  3357.  
  3358. return true;
  3359. }
  3360.  
  3361. void APlayerController::ServerUnmutePlayer_Implementation(FUniqueNetIdRepl PlayerId)
  3362. {
  3363. MuteList.ServerUnmutePlayer(this, PlayerId);
  3364. }
  3365.  
  3366. bool APlayerController::ServerUnmutePlayer_Validate(FUniqueNetIdRepl PlayerId)
  3367. {
  3368. if (!PlayerId.IsValid())
  3369. {
  3370. return false;
  3371. }
  3372.  
  3373. return true;
  3374. }
  3375.  
  3376. void APlayerController::ClientMutePlayer_Implementation(FUniqueNetIdRepl PlayerId)
  3377. {
  3378. MuteList.ClientMutePlayer(this, PlayerId);
  3379. }
  3380.  
  3381. void APlayerController::ClientUnmutePlayer_Implementation(FUniqueNetIdRepl PlayerId)
  3382. {
  3383. MuteList.ClientUnmutePlayer(this, PlayerId);
  3384. }
  3385.  
  3386. /// @endcond
  3387.  
  3388. APlayerController* APlayerController::GetPlayerControllerForMuting(const FUniqueNetIdRepl& PlayerNetId)
  3389. {
  3390. return GetPlayerControllerFromNetId(GetWorld(), *PlayerNetId.GetUniqueNetId());
  3391. }
  3392.  
  3393. bool APlayerController::IsPlayerMuted(const FUniqueNetId& PlayerId)
  3394. {
  3395. return MuteList.IsPlayerMuted(PlayerId);
  3396. }
  3397.  
  3398. void APlayerController::NotifyDirectorControl(bool bNowControlling, AMatineeActor* CurrentMatinee)
  3399. {
  3400. // matinee is done, make sure client syncs up viewtargets, since we were ignoring
  3401. // ClientSetViewTarget during the matinee.
  3402. if (!bNowControlling && (GetNetMode() == NM_Client) && PlayerCameraManager && PlayerCameraManager->bClientSimulatingViewTarget)
  3403. {
  3404. ServerVerifyViewTarget();
  3405. }
  3406. }
  3407.  
  3408. /// @cond DOXYGEN_WARNINGS
  3409.  
  3410. void APlayerController::ClientWasKicked_Implementation(const FText& KickReason)
  3411. {
  3412. }
  3413.  
  3414. void APlayerController::ClientStartOnlineSession_Implementation()
  3415. {
  3416. if (IsPrimaryPlayer() && PlayerState && GetGameInstance() && GetGameInstance()->GetOnlineSession())
  3417. {
  3418. GetGameInstance()->GetOnlineSession()->StartOnlineSession(PlayerState->SessionName);
  3419. }
  3420. }
  3421.  
  3422. void APlayerController::ClientEndOnlineSession_Implementation()
  3423. {
  3424. if (IsPrimaryPlayer() && PlayerState && GetGameInstance() && GetGameInstance()->GetOnlineSession())
  3425. {
  3426. GetGameInstance()->GetOnlineSession()->EndOnlineSession(PlayerState->SessionName);
  3427. }
  3428. }
  3429.  
  3430. /// @endcond
  3431.  
  3432. void APlayerController::ConsoleKey(FKey Key)
  3433. {
  3434. #if ALLOW_CONSOLE
  3435. if (ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player))
  3436. {
  3437. if (LocalPlayer->ViewportClient && LocalPlayer->ViewportClient->ViewportConsole)
  3438. {
  3439. LocalPlayer->ViewportClient->ViewportConsole->InputKey(0, Key, IE_Pressed);
  3440. }
  3441. }
  3442. #endif // ALLOW_CONSOLE
  3443. }
  3444. void APlayerController::SendToConsole(const FString& Command)
  3445. {
  3446. #if ALLOW_CONSOLE
  3447. if (ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player))
  3448. {
  3449. if (LocalPlayer->ViewportClient && LocalPlayer->ViewportClient->ViewportConsole)
  3450. {
  3451. LocalPlayer->ViewportClient->ViewportConsole->ConsoleCommand(Command);
  3452. }
  3453. }
  3454. #endif // ALLOW_CONSOLE
  3455. }
  3456.  
  3457.  
  3458. bool APlayerController::IsPrimaryPlayer() const
  3459. {
  3460. int32 SSIndex;
  3461. return !IsSplitscreenPlayer(&SSIndex) || SSIndex == 0;
  3462. }
  3463.  
  3464. bool APlayerController::IsSplitscreenPlayer(int32* OutSplitscreenPlayerIndex) const
  3465. {
  3466. bool bResult = false;
  3467.  
  3468. if (OutSplitscreenPlayerIndex)
  3469. {
  3470. *OutSplitscreenPlayerIndex = NetPlayerIndex;
  3471. }
  3472.  
  3473. if (Player != NULL)
  3474. {
  3475. ULocalPlayer* const LP = Cast<ULocalPlayer>(Player);
  3476. if (LP != NULL)
  3477. {
  3478. const TArray<ULocalPlayer*>& GamePlayers = LP->GetOuterUEngine()->GetGamePlayers(GetWorld());
  3479. if (GamePlayers.Num() > 1)
  3480. {
  3481. if (OutSplitscreenPlayerIndex)
  3482. {
  3483. *OutSplitscreenPlayerIndex = GamePlayers.Find(LP);
  3484. }
  3485. bResult = true;
  3486. }
  3487. }
  3488. else
  3489. {
  3490. UNetConnection* RemoteConnection = Cast<UNetConnection>(Player);
  3491. if (RemoteConnection->Children.Num() > 0)
  3492. {
  3493. if (OutSplitscreenPlayerIndex)
  3494. {
  3495. *OutSplitscreenPlayerIndex = 0;
  3496. }
  3497. bResult = true;
  3498. }
  3499. else
  3500. {
  3501. UChildConnection* const ChildRemoteConnection = Cast<UChildConnection>(RemoteConnection);
  3502. if (ChildRemoteConnection)
  3503. {
  3504. if (OutSplitscreenPlayerIndex && ChildRemoteConnection->Parent)
  3505. {
  3506. *OutSplitscreenPlayerIndex = ChildRemoteConnection->Parent->Children.Find(ChildRemoteConnection) + 1;
  3507. }
  3508. bResult = true;
  3509. }
  3510. }
  3511. }
  3512. }
  3513.  
  3514. return bResult;
  3515. }
  3516.  
  3517.  
  3518. APlayerState* APlayerController::GetSplitscreenPlayerByIndex(int32 PlayerIndex) const
  3519. {
  3520. APlayerState* Result = NULL;
  3521. if ( Player != NULL )
  3522. {
  3523. if ( IsSplitscreenPlayer() )
  3524. {
  3525. ULocalPlayer* LP = Cast<ULocalPlayer>(Player);
  3526. UNetConnection* RemoteConnection = Cast<UNetConnection>(Player);
  3527. if ( LP != NULL )
  3528. {
  3529. const TArray<ULocalPlayer*>& GamePlayers = LP->GetOuterUEngine()->GetGamePlayers(GetWorld());
  3530. // this PC is a local player
  3531. if ( PlayerIndex >= 0 && PlayerIndex < GamePlayers.Num() )
  3532. {
  3533. ULocalPlayer* SplitPlayer = GamePlayers[PlayerIndex];
  3534. Result = SplitPlayer->PlayerController->PlayerState;
  3535. }
  3536. else
  3537. {
  3538. UE_LOG(LogPlayerController, Warning, TEXT("(%s) APlayerController::%s:GetSplitscreenPlayerByIndex: requested player at invalid index! PlayerIndex:%i NumLocalPlayers:%i"),
  3539. *GetFName().ToString(), *GetStateName().ToString(), PlayerIndex, GamePlayers.Num());
  3540. }
  3541. }
  3542. else if ( RemoteConnection != NULL )
  3543. {
  3544. if ( GetNetMode() == NM_Client )
  3545. {
  3546. //THIS SHOULD NEVER HAPPEN - IF HAVE A REMOTECONNECTION, WE SHOULDN'T BE A CLIENT
  3547. // this player is a client
  3548. UE_LOG(LogPlayerController, Warning, TEXT("(%s) APlayerController::%s:GetSplitscreenPlayerByIndex: CALLED ON CLIENT WITH VALID REMOTE NETCONNECTION!"),
  3549. *GetFName().ToString(), *GetStateName().ToString());
  3550. }
  3551. else
  3552. {
  3553. UChildConnection* ChildRemoteConnection = Cast<UChildConnection>(RemoteConnection);
  3554. if ( ChildRemoteConnection != NULL )
  3555. {
  3556. // this player controller is not the primary player in the splitscreen layout
  3557. UNetConnection* MasterConnection = ChildRemoteConnection->Parent;
  3558. if ( PlayerIndex == 0 )
  3559. {
  3560. Result = MasterConnection->PlayerController->PlayerState;
  3561. }
  3562. else
  3563. {
  3564. PlayerIndex--;
  3565. if ( PlayerIndex >= 0 && PlayerIndex < MasterConnection->Children.Num() )
  3566. {
  3567. ChildRemoteConnection = MasterConnection->Children[PlayerIndex];
  3568. Result = ChildRemoteConnection->PlayerController->PlayerState;
  3569. }
  3570. }
  3571. }
  3572. else if ( RemoteConnection->Children.Num() > 0 )
  3573. {
  3574. // this PC is the primary splitscreen player
  3575. if ( PlayerIndex == 0 )
  3576. {
  3577. // they want this player controller's PlayerState
  3578. Result = PlayerState;
  3579. }
  3580. else
  3581. {
  3582. // our split-screen's PlayerState is being requested.
  3583. PlayerIndex--;
  3584. if ( PlayerIndex >= 0 && PlayerIndex < RemoteConnection->Children.Num() )
  3585. {
  3586. ChildRemoteConnection = RemoteConnection->Children[PlayerIndex];
  3587. Result = ChildRemoteConnection->PlayerController->PlayerState;
  3588. }
  3589. }
  3590. }
  3591. else
  3592. {
  3593. UE_LOG(LogPlayerController, Log, TEXT("(%s) APlayerController::%s:%s: %s IS NOT THE PRIMARY CONNECTION AND HAS NO CHILD CONNECTIONS!"), *GetFName().ToString(), *GetStateName().ToString(), Player);
  3594. }
  3595. }
  3596. }
  3597. else
  3598. {
  3599. UE_LOG(LogPlayerController, Log, TEXT("(%s) APlayerController::%s:%s: %s IS NOT A ULocalPlayer* AND NOT A RemoteConnection! (No valid UPlayer* reference)"), *GetFName().ToString(), *GetStateName().ToString(), Player);
  3600. }
  3601. }
  3602. }
  3603. else
  3604. {
  3605. UE_LOG(LogPlayerController, Log, TEXT("(%s) APlayerController::%s:%s: %s"), *GetFName().ToString(), *GetStateName().ToString(), "NULL value for Player!");
  3606. }
  3607.  
  3608. return Result;
  3609. }
  3610.  
  3611.  
  3612. int32 APlayerController::GetSplitscreenPlayerCount() const
  3613. {
  3614. int32 Result = 0;
  3615.  
  3616. if ( IsSplitscreenPlayer() )
  3617. {
  3618. if ( Player != NULL )
  3619. {
  3620. ULocalPlayer* const LP = Cast<ULocalPlayer>(Player);
  3621. UNetConnection* RemoteConnection = Cast<UNetConnection>(Player);
  3622. if ( LP != NULL )
  3623. {
  3624. Result = LP->GetOuterUEngine()->GetNumGamePlayers(GetWorld());
  3625. }
  3626. else if ( RemoteConnection != NULL )
  3627. {
  3628. if ( Cast<UChildConnection>(RemoteConnection) != NULL )
  3629. {
  3630. // we're the secondary (or otherwise) player in the split - we need to move up to the primary connection
  3631. RemoteConnection = Cast<UChildConnection>(RemoteConnection)->Parent;
  3632. }
  3633.  
  3634. // add one for the primary player
  3635. Result = RemoteConnection->Children.Num() + 1;
  3636. }
  3637. else
  3638. {
  3639. UE_LOG(LogPlayerController, Log, TEXT("(%s) APlayerController::%s:%s NOT A ULocalPlayer* AND NOT A RemoteConnection!"), *GetFName().ToString(), *GetStateName().ToString());
  3640. }
  3641. }
  3642. else
  3643. {
  3644. UE_LOG(LogPlayerController, Log, TEXT("(%s) APlayerController::%s:%s called without a valid UPlayer* value!"), *GetFName().ToString(), *GetStateName().ToString());
  3645. }
  3646. }
  3647.  
  3648. return Result;
  3649. }
  3650.  
  3651. /// @cond DOXYGEN_WARNINGS
  3652.  
  3653. void APlayerController::ClientSetForceMipLevelsToBeResident_Implementation( UMaterialInterface* Material, float ForceDuration, int32 CinematicTextureGroups )
  3654. {
  3655. if ( Material != NULL && IsPrimaryPlayer() )
  3656. {
  3657. Material->SetForceMipLevelsToBeResident( false, false, ForceDuration, CinematicTextureGroups );
  3658. }
  3659. }
  3660.  
  3661. void APlayerController::ClientPrestreamTextures_Implementation( AActor* ForcedActor, float ForceDuration, bool bEnableStreaming, int32 CinematicTextureGroups)
  3662. {
  3663. if ( ForcedActor != NULL && IsPrimaryPlayer() )
  3664. {
  3665. ForcedActor->PrestreamTextures( ForceDuration, bEnableStreaming, CinematicTextureGroups );
  3666. }
  3667. }
  3668.  
  3669. void APlayerController::ClientPlayForceFeedback_Implementation( UForceFeedbackEffect* ForceFeedbackEffect, bool bLooping, bool bIgnoreTimeDilation, FName Tag)
  3670. {
  3671. if (ForceFeedbackEffect)
  3672. {
  3673. if (Tag != NAME_None)
  3674. {
  3675. for (int32 Index = ActiveForceFeedbackEffects.Num() - 1; Index >= 0; --Index)
  3676. {
  3677. if (ActiveForceFeedbackEffects[Index].Tag == Tag)
  3678. {
  3679. ActiveForceFeedbackEffects.RemoveAtSwap(Index);
  3680. }
  3681. }
  3682. }
  3683.  
  3684. ActiveForceFeedbackEffects.Emplace(ForceFeedbackEffect, bLooping, bIgnoreTimeDilation, Tag);
  3685.  
  3686. #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
  3687. ForceFeedbackEffectHistoryEntries.Emplace(ActiveForceFeedbackEffects.Last(), GetWorld()->GetTimeSeconds());
  3688. #endif
  3689. }
  3690. }
  3691.  
  3692. void APlayerController::ClientStopForceFeedback_Implementation( UForceFeedbackEffect* ForceFeedbackEffect, FName Tag)
  3693. {
  3694. if (ForceFeedbackEffect == NULL && Tag == NAME_None)
  3695. {
  3696. ActiveForceFeedbackEffects.Empty();
  3697. }
  3698. else
  3699. {
  3700. for (int32 Index = ActiveForceFeedbackEffects.Num() - 1; Index >= 0; --Index)
  3701. {
  3702. if ( (ForceFeedbackEffect == NULL || ActiveForceFeedbackEffects[Index].ForceFeedbackEffect == ForceFeedbackEffect)
  3703. && (Tag == NAME_None || ActiveForceFeedbackEffects[Index].Tag == Tag) )
  3704. {
  3705. ActiveForceFeedbackEffects.RemoveAtSwap(Index);
  3706. }
  3707. }
  3708. }
  3709. }
  3710.  
  3711. /// @endcond
  3712.  
  3713. uint64 APlayerController::FDynamicForceFeedbackAction::HandleAllocator = 0;
  3714.  
  3715. bool APlayerController::FDynamicForceFeedbackAction::Update(const float DeltaTime, FForceFeedbackValues& Values)
  3716. {
  3717. TimeElapsed += DeltaTime;
  3718.  
  3719. if (TotalTime >= 0.f && TimeElapsed >= TotalTime)
  3720. {
  3721. return false;
  3722. }
  3723.  
  3724. ForceFeedbackDetails.Update(Values);
  3725. return true;
  3726. }
  3727.  
  3728. /** Action that interpolates a component over time to a desired position */
  3729. class FLatentDynamicForceFeedbackAction : public FPendingLatentAction
  3730. {
  3731. public:
  3732. /** Time over which interpolation should happen */
  3733. float TotalTime;
  3734. /** Time so far elapsed for the interpolation */
  3735. float TimeElapsed;
  3736. /** If we are currently running. If false, update will complete */
  3737. uint8 bRunning:1;
  3738. /** Whether the latent action is currently in the player controller's array */
  3739. uint8 bAddedToPlayerController:1;
  3740.  
  3741. TWeakObjectPtr<APlayerController> PlayerController;
  3742.  
  3743. FDynamicForceFeedbackDetails ForceFeedbackDetails;
  3744.  
  3745. /** Function to execute on completion */
  3746. FName ExecutionFunction;
  3747. /** Link to fire on completion */
  3748. int32 OutputLink;
  3749. /** Latent action ID */
  3750. int32 LatentUUID;
  3751. /** Object to call callback on upon completion */
  3752. FWeakObjectPtr CallbackTarget;
  3753.  
  3754. FLatentDynamicForceFeedbackAction(APlayerController* InPlayerController, const float InDuration, const FLatentActionInfo& LatentInfo)
  3755. : TotalTime(InDuration)
  3756. , TimeElapsed(0.f)
  3757. , bRunning(true)
  3758. , bAddedToPlayerController(false)
  3759. , PlayerController(InPlayerController)
  3760. , ExecutionFunction(LatentInfo.ExecutionFunction)
  3761. , OutputLink(LatentInfo.Linkage)
  3762. , LatentUUID(LatentInfo.UUID)
  3763. , CallbackTarget(LatentInfo.CallbackTarget)
  3764. {
  3765. }
  3766.  
  3767. ~FLatentDynamicForceFeedbackAction()
  3768. {
  3769. if (bAddedToPlayerController)
  3770. {
  3771. if (APlayerController* PC = PlayerController.Get())
  3772. {
  3773. PC->LatentDynamicForceFeedbacks.Remove(LatentUUID);
  3774. }
  3775. }
  3776. }
  3777.  
  3778. virtual void UpdateOperation(FLatentResponse& Response) override
  3779. {
  3780. // Update elapsed time
  3781. TimeElapsed += Response.ElapsedTime();
  3782.  
  3783. const bool bComplete = (!bRunning || (TotalTime >= 0.f && TimeElapsed >= TotalTime) || !PlayerController.IsValid());
  3784.  
  3785. if (APlayerController* PC = PlayerController.Get())
  3786. {
  3787. if (bComplete)
  3788. {
  3789. PC->LatentDynamicForceFeedbacks.Remove(LatentUUID);
  3790. bAddedToPlayerController = false;
  3791. }
  3792. else
  3793. {
  3794. PC->LatentDynamicForceFeedbacks.Add(LatentUUID, &ForceFeedbackDetails);
  3795. bAddedToPlayerController = true;
  3796. }
  3797. }
  3798.  
  3799. Response.FinishAndTriggerIf(bComplete, ExecutionFunction, OutputLink, CallbackTarget);
  3800. }
  3801.  
  3802. virtual void NotifyObjectDestroyed() override
  3803. {
  3804. if (APlayerController* PC = PlayerController.Get())
  3805. {
  3806. PC->LatentDynamicForceFeedbacks.Remove(LatentUUID);
  3807. bAddedToPlayerController = false;
  3808. }
  3809. }
  3810.  
  3811. virtual void NotifyActionAborted() override
  3812. {
  3813. if (APlayerController* PC = PlayerController.Get())
  3814. {
  3815. PC->LatentDynamicForceFeedbacks.Remove(LatentUUID);
  3816. bAddedToPlayerController = false;
  3817. }
  3818. }
  3819. };
  3820.  
  3821. void APlayerController::PlayDynamicForceFeedback(float Intensity, float Duration, bool bAffectsLeftLarge, bool bAffectsLeftSmall, bool bAffectsRightLarge, bool bAffectsRightSmall, TEnumAsByte<EDynamicForceFeedbackAction::Type> Action, FLatentActionInfo LatentInfo)
  3822. {
  3823. FLatentActionManager& LatentActionManager = GetWorld()->GetLatentActionManager();
  3824. FLatentDynamicForceFeedbackAction* LatentAction = LatentActionManager.FindExistingAction<FLatentDynamicForceFeedbackAction>(LatentInfo.CallbackTarget, LatentInfo.UUID);
  3825.  
  3826. if (LatentAction)
  3827. {
  3828. if (Action == EDynamicForceFeedbackAction::Stop)
  3829. {
  3830. LatentAction->bRunning = false;
  3831. }
  3832. else
  3833. {
  3834. if (Action == EDynamicForceFeedbackAction::Start)
  3835. {
  3836. LatentAction->TotalTime = Duration;
  3837. LatentAction->TimeElapsed = 0.f;
  3838. LatentAction->bRunning = true;
  3839. }
  3840.  
  3841. LatentAction->ForceFeedbackDetails.Intensity = Intensity;
  3842. LatentAction->ForceFeedbackDetails.bAffectsLeftLarge = bAffectsLeftLarge;
  3843. LatentAction->ForceFeedbackDetails.bAffectsLeftSmall = bAffectsLeftSmall;
  3844. LatentAction->ForceFeedbackDetails.bAffectsRightLarge = bAffectsRightLarge;
  3845. LatentAction->ForceFeedbackDetails.bAffectsRightSmall = bAffectsRightSmall;
  3846. }
  3847. }
  3848. else if (Action == EDynamicForceFeedbackAction::Start)
  3849. {
  3850. LatentAction = new FLatentDynamicForceFeedbackAction(this, Duration, LatentInfo);
  3851.  
  3852. LatentAction->ForceFeedbackDetails.Intensity = Intensity;
  3853. LatentAction->ForceFeedbackDetails.bAffectsLeftLarge = bAffectsLeftLarge;
  3854. LatentAction->ForceFeedbackDetails.bAffectsLeftSmall = bAffectsLeftSmall;
  3855. LatentAction->ForceFeedbackDetails.bAffectsRightLarge = bAffectsRightLarge;
  3856. LatentAction->ForceFeedbackDetails.bAffectsRightSmall = bAffectsRightSmall;
  3857.  
  3858. LatentActionManager.AddNewAction(LatentInfo.CallbackTarget, LatentInfo.UUID, LatentAction);
  3859. }
  3860. }
  3861.  
  3862. FDynamicForceFeedbackHandle APlayerController::PlayDynamicForceFeedback(float Intensity, float Duration, bool bAffectsLeftLarge, bool bAffectsLeftSmall, bool bAffectsRightLarge, bool bAffectsRightSmall, EDynamicForceFeedbackAction::Type Action, FDynamicForceFeedbackHandle ActionHandle)
  3863. {
  3864. FDynamicForceFeedbackHandle FeedbackHandle = 0;
  3865.  
  3866. if (Action == EDynamicForceFeedbackAction::Stop)
  3867. {
  3868. if (ActionHandle > 0)
  3869. {
  3870. DynamicForceFeedbacks.Remove(ActionHandle);
  3871. }
  3872. }
  3873. else
  3874. {
  3875. FDynamicForceFeedbackAction* FeedbackAction = (ActionHandle > 0 ? DynamicForceFeedbacks.Find(ActionHandle) : nullptr);
  3876.  
  3877. if (FeedbackAction == nullptr && Action == EDynamicForceFeedbackAction::Start)
  3878. {
  3879. if (ActionHandle > 0)
  3880. {
  3881. if (ActionHandle <= FDynamicForceFeedbackAction::HandleAllocator)
  3882. {
  3883. // Restarting a stopped/finished index, this is fine
  3884. FeedbackAction = &DynamicForceFeedbacks.Add(ActionHandle);
  3885. FeedbackAction->Handle = ActionHandle;
  3886. }
  3887. else
  3888. {
  3889. UE_LOG(LogPlayerController, Error, TEXT("Specifying an ID to start a dynamic force feedback with that has not yet been assigned is unsafe. No action has been started."));
  3890. }
  3891. }
  3892. else
  3893. {
  3894. FeedbackAction = &DynamicForceFeedbacks.Add(++FDynamicForceFeedbackAction::HandleAllocator);
  3895. FeedbackAction->Handle = FDynamicForceFeedbackAction::HandleAllocator;
  3896. }
  3897. }
  3898.  
  3899. if (FeedbackAction)
  3900. {
  3901. if (Action == EDynamicForceFeedbackAction::Start)
  3902. {
  3903. FeedbackAction->TotalTime = Duration;
  3904. FeedbackAction->TimeElapsed = 0.f;
  3905. }
  3906.  
  3907. FeedbackAction->ForceFeedbackDetails.Intensity = Intensity;
  3908. FeedbackAction->ForceFeedbackDetails.bAffectsLeftLarge = bAffectsLeftLarge;
  3909. FeedbackAction->ForceFeedbackDetails.bAffectsLeftSmall = bAffectsLeftSmall;
  3910. FeedbackAction->ForceFeedbackDetails.bAffectsRightLarge = bAffectsRightLarge;
  3911. FeedbackAction->ForceFeedbackDetails.bAffectsRightSmall = bAffectsRightSmall;
  3912.  
  3913. FeedbackHandle = FeedbackAction->Handle;
  3914. }
  3915. }
  3916.  
  3917. return FeedbackHandle;
  3918. }
  3919.  
  3920. void APlayerController::PlayHapticEffect(UHapticFeedbackEffect_Base* HapticEffect, EControllerHand Hand, float Scale, bool bLoop)
  3921. {
  3922. if (HapticEffect)
  3923. {
  3924. switch (Hand)
  3925. {
  3926. case EControllerHand::Left:
  3927. ActiveHapticEffect_Left.Reset();
  3928. ActiveHapticEffect_Left = MakeShareable(new FActiveHapticFeedbackEffect(HapticEffect, Scale, bLoop));
  3929. break;
  3930. case EControllerHand::Right:
  3931. ActiveHapticEffect_Right.Reset();
  3932. ActiveHapticEffect_Right = MakeShareable(new FActiveHapticFeedbackEffect(HapticEffect, Scale, bLoop));
  3933. break;
  3934. case EControllerHand::Gun:
  3935. ActiveHapticEffect_Gun.Reset();
  3936. ActiveHapticEffect_Gun = MakeShareable(new FActiveHapticFeedbackEffect(HapticEffect, Scale, bLoop));
  3937. default:
  3938. UE_LOG(LogPlayerController, Warning, TEXT("Invalid hand specified (%d) for haptic feedback effect %s"), (int32)Hand, *HapticEffect->GetName());
  3939. break;
  3940. }
  3941. }
  3942. }
  3943.  
  3944. void APlayerController::StopHapticEffect(EControllerHand Hand)
  3945. {
  3946. SetHapticsByValue(0.f, 0.f, Hand);
  3947. }
  3948.  
  3949. void APlayerController::SetDisableHaptics(bool bNewDisabled)
  3950. {
  3951. if (bNewDisabled)
  3952. {
  3953. StopHapticEffect(EControllerHand::Left);
  3954. StopHapticEffect(EControllerHand::Right);
  3955. StopHapticEffect(EControllerHand::Gun);
  3956. }
  3957.  
  3958. bDisableHaptics = bNewDisabled;
  3959. }
  3960.  
  3961. static TAutoConsoleVariable<int32> CVarDisableHaptics(TEXT("input.DisableHaptics"),0,TEXT("If greater than zero, no haptic feedback is processed."));
  3962.  
  3963. void APlayerController::SetHapticsByValue(const float Frequency, const float Amplitude, EControllerHand Hand)
  3964. {
  3965. bool bAreHapticsDisabled = bDisableHaptics || (CVarDisableHaptics.GetValueOnGameThread() > 0);
  3966. if (bAreHapticsDisabled)
  3967. {
  3968. return;
  3969. }
  3970.  
  3971. if (Hand == EControllerHand::Left)
  3972. {
  3973. ActiveHapticEffect_Left.Reset();
  3974. }
  3975. else if (Hand == EControllerHand::Right)
  3976. {
  3977. ActiveHapticEffect_Right.Reset();
  3978. }
  3979. else if (Hand == EControllerHand::Gun)
  3980. {
  3981. ActiveHapticEffect_Gun.Reset();
  3982. }
  3983. else
  3984. {
  3985. UE_LOG(LogPlayerController, Warning, TEXT("Invalid hand specified (%d) for setting haptic feedback values (F: %f A: %f)"), (int32)Hand, Frequency, Amplitude);
  3986. return;
  3987. }
  3988.  
  3989. if (Player == nullptr)
  3990. {
  3991. return;
  3992. }
  3993.  
  3994. IInputInterface* InputInterface = FSlateApplication::Get().GetInputInterface();
  3995. if (InputInterface)
  3996. {
  3997. const int32 ControllerId = CastChecked<ULocalPlayer>(Player)->GetControllerId();
  3998.  
  3999. FHapticFeedbackValues Values(Frequency, Amplitude);
  4000. InputInterface->SetHapticFeedbackValues(ControllerId, (int32)Hand, Values);
  4001. }
  4002. }
  4003.  
  4004. void APlayerController::SetControllerLightColor(FColor Color)
  4005. {
  4006. if (Player == nullptr)
  4007. {
  4008. return;
  4009. }
  4010.  
  4011. IInputInterface* InputInterface = FSlateApplication::Get().GetInputInterface();
  4012. if (InputInterface)
  4013. {
  4014. const int32 ControllerId = CastChecked<ULocalPlayer>(Player)->GetControllerId();
  4015. InputInterface->SetLightColor(ControllerId, Color);
  4016. }
  4017. }
  4018.  
  4019. void APlayerController::ProcessForceFeedbackAndHaptics(const float DeltaTime, const bool bGamePaused)
  4020. {
  4021. if (Player == nullptr)
  4022. {
  4023. return;
  4024. }
  4025.  
  4026. ForceFeedbackValues.LeftLarge = ForceFeedbackValues.LeftSmall = ForceFeedbackValues.RightLarge = ForceFeedbackValues.RightSmall = 0.f;
  4027.  
  4028. FHapticFeedbackValues LeftHaptics, RightHaptics, GunHaptics;
  4029. bool bLeftHapticsNeedUpdate = false;
  4030. bool bRightHapticsNeedUpdate = false;
  4031. bool bGunHapticsNeedUpdate = false;
  4032.  
  4033. bool bProcessFeedback = !bGamePaused;
  4034. #if WITH_EDITOR
  4035. if (bProcessFeedback)
  4036. {
  4037. const ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
  4038. if (LocalPlayer && LocalPlayer->ViewportClient)
  4039. {
  4040. if (FSceneViewport* Viewport = LocalPlayer->ViewportClient->GetGameViewport())
  4041. {
  4042. bProcessFeedback = !Viewport->GetPlayInEditorIsSimulate();
  4043. }
  4044. }
  4045. }
  4046. #endif
  4047.  
  4048. UWorld* World = GetWorld();
  4049.  
  4050. if (bProcessFeedback)
  4051. {
  4052. // --- Force Feedback --------------------------
  4053. for (int32 Index = ActiveForceFeedbackEffects.Num() - 1; Index >= 0; --Index)
  4054. {
  4055. if (!ActiveForceFeedbackEffects[Index].Update(DeltaTime, ForceFeedbackValues))
  4056. {
  4057. ActiveForceFeedbackEffects.RemoveAtSwap(Index);
  4058. }
  4059. }
  4060.  
  4061. for (TSortedMap<uint64, FDynamicForceFeedbackAction>::TIterator It(DynamicForceFeedbacks.CreateIterator()); It; ++It)
  4062. {
  4063. if (!It.Value().Update(DeltaTime, ForceFeedbackValues))
  4064. {
  4065. It.RemoveCurrent();
  4066. }
  4067. }
  4068.  
  4069. for (const TPair<int32, FDynamicForceFeedbackDetails*>& DynamicEntry : LatentDynamicForceFeedbacks)
  4070. {
  4071. DynamicEntry.Value->Update(ForceFeedbackValues);
  4072. }
  4073.  
  4074. if (FForceFeedbackManager* ForceFeedbackManager = FForceFeedbackManager::Get(World))
  4075. {
  4076. ForceFeedbackManager->Update(GetFocalLocation(), ForceFeedbackValues);
  4077. }
  4078.  
  4079. // Apply ForceFeedbackScale
  4080. ForceFeedbackValues.LeftLarge = FMath::Clamp(ForceFeedbackValues.LeftLarge * ForceFeedbackScale, 0.f, 1.f);
  4081. ForceFeedbackValues.RightLarge = FMath::Clamp(ForceFeedbackValues.RightLarge * ForceFeedbackScale, 0.f, 1.f);
  4082. ForceFeedbackValues.LeftSmall = FMath::Clamp(ForceFeedbackValues.LeftSmall * ForceFeedbackScale, 0.f, 1.f);
  4083. ForceFeedbackValues.RightSmall = FMath::Clamp(ForceFeedbackValues.RightSmall * ForceFeedbackScale, 0.f, 1.f);
  4084.  
  4085. // --- Haptic Feedback -------------------------
  4086. if (ActiveHapticEffect_Left.IsValid())
  4087. {
  4088. const bool bPlaying = ActiveHapticEffect_Left->Update(DeltaTime, LeftHaptics);
  4089. if (!bPlaying)
  4090. {
  4091. ActiveHapticEffect_Left->bLoop ? ActiveHapticEffect_Left->Restart() : ActiveHapticEffect_Left.Reset();
  4092. }
  4093.  
  4094. bLeftHapticsNeedUpdate = true;
  4095. }
  4096.  
  4097. if (ActiveHapticEffect_Right.IsValid())
  4098. {
  4099. const bool bPlaying = ActiveHapticEffect_Right->Update(DeltaTime, RightHaptics);
  4100. if (!bPlaying)
  4101. {
  4102. ActiveHapticEffect_Right->bLoop ? ActiveHapticEffect_Right->Restart() : ActiveHapticEffect_Right.Reset();
  4103. }
  4104.  
  4105. bRightHapticsNeedUpdate = true;
  4106. }
  4107.  
  4108. if (ActiveHapticEffect_Gun.IsValid())
  4109. {
  4110. const bool bPlaying = ActiveHapticEffect_Gun->Update(DeltaTime, GunHaptics);
  4111. if (!bPlaying)
  4112. {
  4113. ActiveHapticEffect_Gun->bLoop ? ActiveHapticEffect_Gun->Restart() : ActiveHapticEffect_Gun.Reset();
  4114. }
  4115.  
  4116. bGunHapticsNeedUpdate = true;
  4117. }
  4118.  
  4119. }
  4120.  
  4121. if (FSlateApplication::IsInitialized())
  4122. {
  4123. int32 ControllerId = GetInputIndex();
  4124.  
  4125. if (ControllerId != INVALID_CONTROLLERID)
  4126. {
  4127. IInputInterface* InputInterface = FSlateApplication::Get().GetInputInterface();
  4128. if (InputInterface)
  4129. {
  4130. // Adjust the ControllerId to account for the controller ID offset applied in UGameViewportClient::InputKey/Axis
  4131. // to play the force feedback on the correct controller if the offset player gamepad IDs feature is in use.
  4132. const int32 NumLocalPlayers = World->GetGameInstance()->GetNumLocalPlayers();
  4133. if (NumLocalPlayers > 1 && GetDefault<UGameMapsSettings>()->bOffsetPlayerGamepadIds)
  4134. {
  4135. --ControllerId;
  4136. }
  4137.  
  4138. InputInterface->SetForceFeedbackChannelValues(ControllerId, (bForceFeedbackEnabled ? ForceFeedbackValues : FForceFeedbackValues()));
  4139.  
  4140. const bool bAreHapticsDisabled = (CVarDisableHaptics.GetValueOnGameThread() > 0) || bDisableHaptics;
  4141. if (!bAreHapticsDisabled)
  4142. {
  4143. // Haptic Updates
  4144. if (bLeftHapticsNeedUpdate)
  4145. {
  4146. InputInterface->SetHapticFeedbackValues(ControllerId, (int32)EControllerHand::Left, LeftHaptics);
  4147. }
  4148. if (bRightHapticsNeedUpdate)
  4149. {
  4150. InputInterface->SetHapticFeedbackValues(ControllerId, (int32)EControllerHand::Right, RightHaptics);
  4151. }
  4152. if (bGunHapticsNeedUpdate)
  4153. {
  4154. InputInterface->SetHapticFeedbackValues(ControllerId, (int32)EControllerHand::Gun, GunHaptics);
  4155. }
  4156. }
  4157. }
  4158. }
  4159. }
  4160. }
  4161.  
  4162. /// @cond DOXYGEN_WARNINGS
  4163.  
  4164. void APlayerController::ClientPlayCameraShake_Implementation( TSubclassOf<class UCameraShake> Shake, float Scale, ECameraAnimPlaySpace::Type PlaySpace, FRotator UserPlaySpaceRot )
  4165. {
  4166. if (PlayerCameraManager != NULL)
  4167. {
  4168. PlayerCameraManager->PlayCameraShake(Shake, Scale, PlaySpace, UserPlaySpaceRot);
  4169. }
  4170. }
  4171.  
  4172. void APlayerController::ClientStopCameraShake_Implementation( TSubclassOf<class UCameraShake> Shake, bool bImmediately )
  4173. {
  4174. if (PlayerCameraManager != NULL)
  4175. {
  4176. PlayerCameraManager->StopAllInstancesOfCameraShake(Shake, bImmediately);
  4177. }
  4178. }
  4179.  
  4180. void APlayerController::ClientPlayCameraAnim_Implementation( UCameraAnim* AnimToPlay, float Scale, float Rate,
  4181. float BlendInTime, float BlendOutTime, bool bLoop,
  4182. bool bRandomStartTime, ECameraAnimPlaySpace::Type Space, FRotator CustomPlaySpace )
  4183. {
  4184. if (PlayerCameraManager != NULL)
  4185. {
  4186. PlayerCameraManager->PlayCameraAnim(AnimToPlay, Rate, Scale, BlendInTime, BlendOutTime, bLoop, bRandomStartTime, 0.f, Space, CustomPlaySpace);
  4187. }
  4188. }
  4189.  
  4190. void APlayerController::ClientStopCameraAnim_Implementation(UCameraAnim* AnimToStop)
  4191. {
  4192. if (PlayerCameraManager != NULL)
  4193. {
  4194. PlayerCameraManager->StopAllInstancesOfCameraAnim(AnimToStop);
  4195. }
  4196. }
  4197.  
  4198. void APlayerController::ClientSpawnCameraLensEffect_Implementation( TSubclassOf<AEmitterCameraLensEffectBase> LensEffectEmitterClass )
  4199. {
  4200. if (PlayerCameraManager != NULL)
  4201. {
  4202. PlayerCameraManager->AddCameraLensEffect(LensEffectEmitterClass);
  4203. }
  4204. }
  4205.  
  4206. void APlayerController::ClientClearCameraLensEffects_Implementation()
  4207. {
  4208. if (PlayerCameraManager != NULL)
  4209. {
  4210. PlayerCameraManager->ClearCameraLensEffects();
  4211. }
  4212. }
  4213.  
  4214. /// @endcond
  4215.  
  4216. void APlayerController::ReceivedGameModeClass(TSubclassOf<AGameModeBase> GameModeClass)
  4217. {
  4218. }
  4219.  
  4220. void APlayerController::ReceivedSpectatorClass(TSubclassOf<ASpectatorPawn> SpectatorClass)
  4221. {
  4222. if (IsInState(NAME_Spectating))
  4223. {
  4224. if (GetSpectatorPawn() == NULL)
  4225. {
  4226. BeginSpectatingState();
  4227. }
  4228. }
  4229. }
  4230.  
  4231. void APlayerController::SetPawn(APawn* InPawn)
  4232. {
  4233. if (InPawn == NULL)
  4234. {
  4235. // Attempt to move the PC to the current camera location if no pawn was specified
  4236. const FVector NewLocation = (PlayerCameraManager != NULL) ? PlayerCameraManager->GetCameraLocation() : GetSpawnLocation();
  4237. SetSpawnLocation(NewLocation);
  4238.  
  4239. if (bAutoManageActiveCameraTarget)
  4240. {
  4241. AutoManageActiveCameraTarget(this);
  4242. }
  4243. }
  4244.  
  4245. Super::SetPawn(InPawn);
  4246.  
  4247. // If we have a pawn we need to determine if we should show/hide the player for cinematic mode
  4248. if (GetPawn() && bCinematicMode && bHidePawnInCinematicMode)
  4249. {
  4250. GetPawn()->SetActorHiddenInGame(true);
  4251. }
  4252. }
  4253.  
  4254. void APlayerController::GetLifetimeReplicatedProps(TArray< FLifetimeProperty > & OutLifetimeProps) const
  4255. {
  4256. Super::GetLifetimeReplicatedProps(OutLifetimeProps);
  4257.  
  4258. // These used to only replicate if PlayerCameraManager->GetViewTargetPawn() != GetPawn()
  4259. // But, since they also don't update unless that condition is true, these values won't change, thus won't send
  4260. // This is a little less efficient, but fits into the new condition system well, and shouldn't really add much overhead
  4261. DOREPLIFETIME_CONDITION(APlayerController, TargetViewRotation, COND_OwnerOnly);
  4262.  
  4263. // Replicate SpawnLocation for remote spectators
  4264. DOREPLIFETIME_CONDITION(APlayerController, SpawnLocation, COND_OwnerOnly);
  4265. }
  4266.  
  4267. void APlayerController::SetPlayer( UPlayer* InPlayer )
  4268. {
  4269. check(InPlayer!=NULL);
  4270.  
  4271. const bool bIsSameLevel = InPlayer->PlayerController && (InPlayer->PlayerController->GetLevel() == GetLevel());
  4272. // Detach old player if it's in the same level.
  4273. if (bIsSameLevel)
  4274. {
  4275. InPlayer->PlayerController->Player = NULL;
  4276. }
  4277.  
  4278. // Set the viewport.
  4279. Player = InPlayer;
  4280. InPlayer->PlayerController = this;
  4281.  
  4282. // cap outgoing rate to max set by server
  4283. UNetDriver* Driver = GetWorld()->GetNetDriver();
  4284. if( (ClientCap>=2600) && Driver && Driver->ServerConnection )
  4285. {
  4286. Player->CurrentNetSpeed = Driver->ServerConnection->CurrentNetSpeed = FMath::Clamp( ClientCap, 1800, Driver->MaxClientRate );
  4287. }
  4288.  
  4289. // initializations only for local players
  4290. ULocalPlayer *LP = Cast<ULocalPlayer>(InPlayer);
  4291. if (LP != NULL)
  4292. {
  4293. // Clients need this marked as local (server already knew at construction time)
  4294. SetAsLocalPlayerController();
  4295. LP->InitOnlineSession();
  4296. InitInputSystem();
  4297. }
  4298. else
  4299. {
  4300. NetConnection = Cast<UNetConnection>(InPlayer);
  4301. if (NetConnection)
  4302. {
  4303. NetConnection->OwningActor = this;
  4304. }
  4305. }
  4306.  
  4307. UpdateStateInputComponents();
  4308.  
  4309. #if ENABLE_VISUAL_LOG
  4310. if (Role == ROLE_Authority && FVisualLogger::Get().IsRecordingOnServer())
  4311. {
  4312. OnServerStartedVisualLogger(true);
  4313. }
  4314. #endif
  4315.  
  4316. // notify script that we've been assigned a valid player
  4317. ReceivedPlayer();
  4318. }
  4319.  
  4320. ULocalPlayer* APlayerController::GetLocalPlayer() const
  4321. {
  4322. return Cast<ULocalPlayer>(Player);
  4323. }
  4324.  
  4325. bool APlayerController::IsInViewportClient(UGameViewportClient* ViewportClient) const
  4326. {
  4327. return ViewportClient && ViewportClient->GetGameViewportWidget().IsValid() && ViewportClient->GetGameViewportWidget()->IsDirectlyHovered();
  4328. }
  4329.  
  4330. int32 APlayerController::GetInputIndex() const
  4331. {
  4332. if (ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player))
  4333. {
  4334. return LocalPlayer->GetControllerId();
  4335. }
  4336. return INVALID_CONTROLLERID;
  4337. }
  4338.  
  4339. void APlayerController::TickPlayerInput(const float DeltaSeconds, const bool bGamePaused)
  4340. {
  4341. SCOPE_CYCLE_COUNTER(STAT_PC_TickInput);
  4342.  
  4343. check(PlayerInput);
  4344. PlayerInput->Tick(DeltaSeconds);
  4345.  
  4346. if (ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player))
  4347. {
  4348. if (bEnableMouseOverEvents)
  4349. {
  4350. FVector2D MousePosition;
  4351. FHitResult HitResult;
  4352. bool bHit = false;
  4353.  
  4354. UGameViewportClient* ViewportClient = LocalPlayer->ViewportClient;
  4355.  
  4356. // Only send mouse hit events if we're directly over the viewport.
  4357. if ( IsInViewportClient(ViewportClient) )
  4358. {
  4359. if ( ViewportClient->GetMousePosition(MousePosition) )
  4360. {
  4361. bHit = GetHitResultAtScreenPosition(MousePosition, CurrentClickTraceChannel, true, /*out*/ HitResult);
  4362. }
  4363. }
  4364.  
  4365. UPrimitiveComponent* PreviousComponent = CurrentClickablePrimitive.Get();
  4366. UPrimitiveComponent* CurrentComponent = (bHit ? HitResult.Component.Get() : NULL);
  4367.  
  4368. UPrimitiveComponent::DispatchMouseOverEvents(PreviousComponent, CurrentComponent);
  4369.  
  4370. CurrentClickablePrimitive = CurrentComponent;
  4371. }
  4372.  
  4373. if (bEnableTouchOverEvents)
  4374. {
  4375. for (int32 TouchIndexInt = 0; TouchIndexInt < EKeys::NUM_TOUCH_KEYS; ++TouchIndexInt)
  4376. {
  4377. const ETouchIndex::Type FingerIndex = ETouchIndex::Type(TouchIndexInt);
  4378.  
  4379. FHitResult HitResult;
  4380. const bool bHit = GetHitResultUnderFinger(FingerIndex, CurrentClickTraceChannel, true, /*out*/ HitResult);
  4381.  
  4382. UPrimitiveComponent* PreviousComponent = CurrentTouchablePrimitives[TouchIndexInt].Get();
  4383. UPrimitiveComponent* CurrentComponent = (bHit ? HitResult.Component.Get() : NULL);
  4384.  
  4385. UPrimitiveComponent::DispatchTouchOverEvents(FingerIndex, PreviousComponent, CurrentComponent);
  4386.  
  4387. CurrentTouchablePrimitives[TouchIndexInt] = CurrentComponent;
  4388. }
  4389. }
  4390. }
  4391.  
  4392. ProcessPlayerInput(DeltaSeconds, bGamePaused);
  4393. ProcessForceFeedbackAndHaptics(DeltaSeconds, bGamePaused);
  4394. }
  4395.  
  4396. void APlayerController::TickActor( float DeltaSeconds, ELevelTick TickType, FActorTickFunction& ThisTickFunction )
  4397. {
  4398. SCOPE_CYCLE_COUNTER(STAT_PlayerControllerTick);
  4399. SCOPE_CYCLE_COUNTER(STAT_PC_TickActor);
  4400.  
  4401. if (TickType == LEVELTICK_PauseTick && !ShouldPerformFullTickWhenPaused())
  4402. {
  4403. if (PlayerInput)
  4404. {
  4405. TickPlayerInput(DeltaSeconds, true);
  4406. }
  4407.  
  4408. // Clear axis inputs from previous frame.
  4409. RotationInput = FRotator::ZeroRotator;
  4410.  
  4411. if (!IsPendingKill())
  4412. {
  4413. Tick(DeltaSeconds); // perform any tick functions unique to an actor subclass
  4414. }
  4415.  
  4416. return; //root of tick hierarchy
  4417. }
  4418.  
  4419. //root of tick hierarchy
  4420.  
  4421. if ((GetRemoteRole() == ROLE_AutonomousProxy) && !IsNetMode(NM_Client) && !IsLocalPlayerController())
  4422. {
  4423. // force physics update for clients that aren't sending movement updates in a timely manner
  4424. // this prevents cheats associated with artificially induced ping spikes
  4425. // skip updates if pawn lost autonomous proxy role (e.g. TurnOff() call)
  4426. if (GetPawn() && !GetPawn()->IsPendingKill() && GetPawn()->GetRemoteRole() == ROLE_AutonomousProxy && GetPawn()->bReplicateMovement)
  4427. {
  4428. UMovementComponent* PawnMovement = GetPawn()->GetMovementComponent();
  4429. INetworkPredictionInterface* NetworkPredictionInterface = Cast<INetworkPredictionInterface>(PawnMovement);
  4430. if (NetworkPredictionInterface && IsValid(PawnMovement->UpdatedComponent))
  4431. {
  4432. FNetworkPredictionData_Server* ServerData = NetworkPredictionInterface->HasPredictionData_Server() ? NetworkPredictionInterface->GetPredictionData_Server() : nullptr;
  4433. if (ServerData)
  4434. {
  4435. UWorld* World = GetWorld();
  4436. if (ServerData->ServerTimeStamp != 0.f)
  4437. {
  4438. const float TimeSinceUpdate = World->GetTimeSeconds() - ServerData->ServerTimeStamp;
  4439. const float PawnTimeSinceUpdate = TimeSinceUpdate * GetPawn()->CustomTimeDilation;
  4440. if (PawnTimeSinceUpdate > FMath::Max<float>(DeltaSeconds+0.06f, AGameNetworkManager::StaticClass()->GetDefaultObject<AGameNetworkManager>()->MAXCLIENTUPDATEINTERVAL * GetPawn()->GetActorTimeDilation()))
  4441. {
  4442. //UE_LOG(LogPlayerController, Warning, TEXT("ForcedMovementTick. PawnTimeSinceUpdate: %f, DeltaSeconds: %f, DeltaSeconds+: %f"), PawnTimeSinceUpdate, DeltaSeconds, DeltaSeconds+0.06f);
  4443. const USkeletalMeshComponent* PawnMesh = GetPawn()->FindComponentByClass<USkeletalMeshComponent>();
  4444. if (!PawnMesh || !PawnMesh->IsSimulatingPhysics())
  4445. {
  4446. // We are setting the ServerData timestamp BEFORE updating position below since that may cause ServerData to become deleted (like if the pawn was unpossessed as a result of the move)
  4447. // Also null the pointer to make sure no one accidentally starts using it below the call to ForcePositionUpdate
  4448. ServerData->ServerTimeStamp = World->GetTimeSeconds();
  4449. ServerData = nullptr;
  4450.  
  4451. NetworkPredictionInterface->ForcePositionUpdate(PawnTimeSinceUpdate);
  4452. }
  4453. }
  4454. }
  4455. else
  4456. {
  4457. // If timestamp is zero, set to current time so we don't have a huge initial delta time for correction.
  4458. ServerData->ServerTimeStamp = World->GetTimeSeconds();
  4459. }
  4460. }
  4461. }
  4462. }
  4463.  
  4464. // update viewtarget replicated info
  4465. if (PlayerCameraManager != NULL)
  4466. {
  4467. APawn* TargetPawn = PlayerCameraManager->GetViewTargetPawn();
  4468.  
  4469. if ((TargetPawn != GetPawn()) && (TargetPawn != NULL))
  4470. {
  4471. TargetViewRotation = TargetPawn->GetViewRotation();
  4472. }
  4473. }
  4474. }
  4475. else if (Role > ROLE_SimulatedProxy)
  4476. {
  4477. // Process PlayerTick with input.
  4478. if (!PlayerInput && (Player == NULL || Cast<ULocalPlayer>( Player ) != NULL))
  4479. {
  4480. InitInputSystem();
  4481. }
  4482.  
  4483. if (PlayerInput)
  4484. {
  4485. PlayerTick(DeltaSeconds);
  4486. }
  4487.  
  4488. if (IsPendingKill())
  4489. {
  4490. return;
  4491. }
  4492.  
  4493. // update viewtarget replicated info
  4494. if (PlayerCameraManager != NULL)
  4495. {
  4496. APawn* TargetPawn = PlayerCameraManager->GetViewTargetPawn();
  4497. if ((TargetPawn != GetPawn()) && (TargetPawn != NULL))
  4498. {
  4499. SmoothTargetViewRotation(TargetPawn, DeltaSeconds);
  4500. }
  4501. }
  4502. }
  4503.  
  4504. if (!IsPendingKill())
  4505. {
  4506. Tick(DeltaSeconds); // perform any tick functions unique to an actor subclass
  4507. }
  4508.  
  4509. // Clear old axis inputs since we are done with them.
  4510. RotationInput = FRotator::ZeroRotator;
  4511.  
  4512. #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
  4513. if (CheatManager != NULL)
  4514. {
  4515. CheatManager->TickCollisionDebug();
  4516. }
  4517. #endif // !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
  4518. }
  4519.  
  4520. bool APlayerController::IsNetRelevantFor(const AActor* RealViewer, const AActor* ViewTarget, const FVector& SrcLocation) const
  4521. {
  4522. return ( this==RealViewer );
  4523. }
  4524.  
  4525. void APlayerController::ClientTravel(const FString& URL, ETravelType TravelType, bool bSeamless, FGuid MapPackageGuid)
  4526. {
  4527. // Keep track of seamless travel serverside
  4528. if (bSeamless && TravelType == TRAVEL_Relative)
  4529. {
  4530. SeamlessTravelCount++;
  4531. }
  4532.  
  4533. // Now pass on to the RPC
  4534. ClientTravelInternal(URL, TravelType, bSeamless, MapPackageGuid);
  4535. }
  4536.  
  4537. /// @cond DOXYGEN_WARNINGS
  4538.  
  4539. void APlayerController::ClientTravelInternal_Implementation(const FString& URL, ETravelType TravelType, bool bSeamless, FGuid MapPackageGuid)
  4540. {
  4541. UWorld* World = GetWorld();
  4542.  
  4543. // Warn the client.
  4544. PreClientTravel(URL, TravelType, bSeamless);
  4545.  
  4546. if (bSeamless && TravelType == TRAVEL_Relative)
  4547. {
  4548. World->SeamlessTravel(URL);
  4549. }
  4550. else
  4551. {
  4552. if (bSeamless)
  4553. {
  4554. UE_LOG(LogPlayerController, Warning, TEXT("Unable to perform seamless travel because TravelType was %i, not TRAVEL_Relative"), int32(TravelType));
  4555. }
  4556. // Do the travel.
  4557. GEngine->SetClientTravel(World, *URL, (ETravelType)TravelType);
  4558. }
  4559. }
  4560.  
  4561. /// @endcond
  4562.  
  4563. FString APlayerController::GetPlayerNetworkAddress()
  4564. {
  4565. if( Player && Player->IsA(UNetConnection::StaticClass()) )
  4566. return Cast<UNetConnection>(Player)->LowLevelGetRemoteAddress();
  4567. else
  4568. return TEXT("");
  4569. }
  4570.  
  4571. FString APlayerController::GetServerNetworkAddress()
  4572. {
  4573. UNetDriver* NetDriver = NULL;
  4574. if (UWorld* World = GetWorld())
  4575. {
  4576. NetDriver = World->GetNetDriver();
  4577. }
  4578.  
  4579. if( NetDriver && NetDriver->ServerConnection )
  4580. {
  4581. return NetDriver->ServerConnection->LowLevelGetRemoteAddress();
  4582. }
  4583.  
  4584. return TEXT("");
  4585. }
  4586.  
  4587. bool APlayerController::DefaultCanUnpause()
  4588. {
  4589. return GetWorldSettings() != NULL && GetWorldSettings()->Pauser == PlayerState;
  4590. }
  4591.  
  4592. void APlayerController::StartSpectatingOnly()
  4593. {
  4594. ChangeState(NAME_Spectating);
  4595. PlayerState->bIsSpectator = true;
  4596. PlayerState->bOnlySpectator = true;
  4597. bPlayerIsWaiting = false; // Can't spawn, we are only allowed to be a spectator.
  4598. }
  4599.  
  4600. void APlayerController::EndPlayingState()
  4601. {
  4602. if ( GetPawn() != NULL )
  4603. {
  4604. GetPawn()->SetRemoteViewPitch( 0.f );
  4605. }
  4606. }
  4607.  
  4608.  
  4609. void APlayerController::BeginSpectatingState()
  4610. {
  4611. if (GetPawn() != NULL && Role == ROLE_Authority)
  4612. {
  4613. UnPossess();
  4614. }
  4615.  
  4616. DestroySpectatorPawn();
  4617. SetSpectatorPawn(SpawnSpectatorPawn());
  4618. }
  4619.  
  4620. void APlayerController::SetSpectatorPawn(class ASpectatorPawn* NewSpectatorPawn)
  4621. {
  4622. if (IsInState(NAME_Spectating))
  4623. {
  4624. RemovePawnTickDependency(SpectatorPawn);
  4625. SpectatorPawn = NewSpectatorPawn;
  4626.  
  4627. if (NewSpectatorPawn)
  4628. {
  4629. // setting to a new valid spectator pawn
  4630. AttachToPawn(NewSpectatorPawn);
  4631. AddPawnTickDependency(NewSpectatorPawn);
  4632. AutoManageActiveCameraTarget(NewSpectatorPawn);
  4633. }
  4634. else
  4635. {
  4636. // clearing the spectator pawn, try to attach to the regular pawn
  4637. APawn* const MyPawn = GetPawn();
  4638. AttachToPawn(MyPawn);
  4639. AddPawnTickDependency(MyPawn);
  4640. if (MyPawn)
  4641. {
  4642. AutoManageActiveCameraTarget(MyPawn);
  4643. }
  4644. else
  4645. {
  4646. AutoManageActiveCameraTarget(this);
  4647. }
  4648. }
  4649. }
  4650. }
  4651.  
  4652. ASpectatorPawn* APlayerController::SpawnSpectatorPawn()
  4653. {
  4654. ASpectatorPawn* SpawnedSpectator = nullptr;
  4655.  
  4656. // Only spawned for the local player
  4657. if ((GetSpectatorPawn() == nullptr) && IsLocalController())
  4658. {
  4659. UWorld* World = GetWorld();
  4660. if (AGameStateBase const* const GameState = World->GetGameState())
  4661. {
  4662. if (UClass* SpectatorClass = GameState->SpectatorClass)
  4663. {
  4664. FActorSpawnParameters SpawnParams;
  4665. SpawnParams.Owner = this;
  4666. SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
  4667.  
  4668. SpawnParams.ObjectFlags |= RF_Transient; // We never want to save spectator pawns into a map
  4669. SpawnedSpectator = World->SpawnActor<ASpectatorPawn>(SpectatorClass, GetSpawnLocation(), GetControlRotation(), SpawnParams);
  4670. if (SpawnedSpectator)
  4671. {
  4672. SpawnedSpectator->SetReplicates(false); // Client-side only
  4673. SpawnedSpectator->PossessedBy(this);
  4674. SpawnedSpectator->PawnClientRestart();
  4675. if (SpawnedSpectator->PrimaryActorTick.bStartWithTickEnabled)
  4676. {
  4677. SpawnedSpectator->SetActorTickEnabled(true);
  4678. }
  4679.  
  4680. UE_LOG(LogPlayerController, Verbose, TEXT("Spawned spectator %s [server:%d]"), *GetNameSafe(SpawnedSpectator), GetNetMode() < NM_Client);
  4681. }
  4682. else
  4683. {
  4684. UE_LOG(LogPlayerController, Warning, TEXT("Failed to spawn spectator with class %s"), *GetNameSafe(SpectatorClass));
  4685. }
  4686. }
  4687. }
  4688. else
  4689. {
  4690. // This normally happens on clients if the Player is replicated but the GameState has not yet.
  4691. UE_LOG(LogPlayerController, Verbose, TEXT("NULL GameState when trying to spawn spectator!"));
  4692. }
  4693. }
  4694.  
  4695. return SpawnedSpectator;
  4696. }
  4697.  
  4698.  
  4699. void APlayerController::DestroySpectatorPawn()
  4700. {
  4701. if (GetSpectatorPawn())
  4702. {
  4703. if (GetViewTarget() == GetSpectatorPawn())
  4704. {
  4705. SetViewTarget(this);
  4706. }
  4707.  
  4708. GetSpectatorPawn()->UnPossessed();
  4709. GetWorld()->DestroyActor(GetSpectatorPawn());
  4710. SetSpectatorPawn(NULL);
  4711. }
  4712. }
  4713.  
  4714.  
  4715. APawn* APlayerController::GetPawnOrSpectator() const
  4716. {
  4717. return GetPawn() ? GetPawn() : GetSpectatorPawn();
  4718. }
  4719.  
  4720.  
  4721. void APlayerController::UpdateStateInputComponents()
  4722. {
  4723. // update Inactive state component
  4724. if (StateName == NAME_Inactive && IsLocalController())
  4725. {
  4726. if (InactiveStateInputComponent == NULL)
  4727. {
  4728. static const FName InactiveStateInputComponentName(TEXT("PC_InactiveStateInputComponent0"));
  4729. InactiveStateInputComponent = NewObject<UInputComponent>(this, InactiveStateInputComponentName);
  4730. SetupInactiveStateInputComponent(InactiveStateInputComponent);
  4731. InactiveStateInputComponent->RegisterComponent();
  4732. PushInputComponent(InactiveStateInputComponent);
  4733. }
  4734. }
  4735. else if (InactiveStateInputComponent)
  4736. {
  4737. PopInputComponent(InactiveStateInputComponent);
  4738. InactiveStateInputComponent->DestroyComponent();
  4739. InactiveStateInputComponent = NULL;
  4740. }
  4741. }
  4742.  
  4743. void APlayerController::ChangeState(FName NewState)
  4744. {
  4745. if(NewState != StateName)
  4746. {
  4747. // end current state
  4748. if(StateName == NAME_Spectating)
  4749. {
  4750. EndSpectatingState();
  4751. }
  4752. else if(StateName == NAME_Playing)
  4753. {
  4754. EndPlayingState();
  4755. }
  4756.  
  4757. Super::ChangeState(NewState); // Will set StateName, also handles EndInactiveState/BeginInactiveState
  4758.  
  4759. // start new state
  4760. if(StateName == NAME_Playing)
  4761. {
  4762. BeginPlayingState();
  4763. }
  4764. else if (StateName == NAME_Spectating)
  4765. {
  4766. BeginSpectatingState();
  4767. }
  4768.  
  4769. UpdateStateInputComponents();
  4770. }
  4771. }
  4772.  
  4773. void APlayerController::BeginPlayingState()
  4774. {
  4775. }
  4776.  
  4777. void APlayerController::EndSpectatingState()
  4778. {
  4779. if ( PlayerState != NULL )
  4780. {
  4781. if ( PlayerState->bOnlySpectator )
  4782. {
  4783. UE_LOG(LogPlayerController, Warning, TEXT("Spectator only UPlayer* leaving spectating state"));
  4784. }
  4785. PlayerState->bIsSpectator = false;
  4786. }
  4787.  
  4788. bPlayerIsWaiting = false;
  4789.  
  4790. DestroySpectatorPawn();
  4791. }
  4792.  
  4793. void APlayerController::BeginInactiveState()
  4794. {
  4795. if ( (GetPawn() != NULL) && (GetPawn()->Controller == this) )
  4796. {
  4797. GetPawn()->Controller = NULL;
  4798. }
  4799. SetPawn(NULL);
  4800.  
  4801. GetWorldTimerManager().SetTimer(TimerHandle_UnFreeze, this, &APlayerController::UnFreeze, GetMinRespawnDelay());
  4802. }
  4803.  
  4804. float APlayerController::GetMinRespawnDelay()
  4805. {
  4806. AGameStateBase const* const GameState = GetWorld()->GetGameState();
  4807.  
  4808. if (GameState)
  4809. {
  4810. return GameState->GetPlayerRespawnDelay(this);
  4811. }
  4812. return 1.0f;
  4813. }
  4814.  
  4815. void APlayerController::EndInactiveState()
  4816. {
  4817. }
  4818.  
  4819. void APlayerController::SetupInactiveStateInputComponent(UInputComponent* InComponent)
  4820. {
  4821. check(InComponent);
  4822.  
  4823. InComponent->BindAxis("Spectator_Turn", this, &APlayerController::AddYawInput);
  4824. InComponent->BindAxis("Spectator_LookUp", this, &APlayerController::AddPitchInput);
  4825. }
  4826.  
  4827.  
  4828. void APlayerController::PushInputComponent(UInputComponent* InInputComponent)
  4829. {
  4830. if (InInputComponent)
  4831. {
  4832. bool bPushed = false;
  4833. CurrentInputStack.RemoveSingle(InInputComponent);
  4834. for (int32 Index = CurrentInputStack.Num() - 1; Index >= 0; --Index)
  4835. {
  4836. UInputComponent* IC = CurrentInputStack[Index].Get();
  4837. if (IC == nullptr)
  4838. {
  4839. CurrentInputStack.RemoveAt(Index);
  4840. }
  4841. else if (IC->Priority <= InInputComponent->Priority)
  4842. {
  4843. CurrentInputStack.Insert(InInputComponent, Index + 1);
  4844. bPushed = true;
  4845. break;
  4846. }
  4847. }
  4848. if (!bPushed)
  4849. {
  4850. CurrentInputStack.Insert(InInputComponent, 0);
  4851. }
  4852. }
  4853. }
  4854.  
  4855. bool APlayerController::PopInputComponent(UInputComponent* InInputComponent)
  4856. {
  4857. if (InInputComponent)
  4858. {
  4859. if (CurrentInputStack.RemoveSingle(InInputComponent) > 0)
  4860. {
  4861. InInputComponent->ClearBindingValues();
  4862. return true;
  4863. }
  4864. }
  4865. return false;
  4866. }
  4867.  
  4868. void APlayerController::AddPitchInput(float Val)
  4869. {
  4870. RotationInput.Pitch += !IsLookInputIgnored() ? Val * InputPitchScale : 0.f;
  4871. }
  4872.  
  4873. void APlayerController::AddYawInput(float Val)
  4874. {
  4875. RotationInput.Yaw += !IsLookInputIgnored() ? Val * InputYawScale : 0.f;
  4876. }
  4877.  
  4878. void APlayerController::AddRollInput(float Val)
  4879. {
  4880. RotationInput.Roll += !IsLookInputIgnored() ? Val * InputRollScale : 0.f;
  4881. }
  4882.  
  4883. bool APlayerController::IsInputKeyDown(const FKey Key) const
  4884. {
  4885. return (PlayerInput ? PlayerInput->IsPressed(Key) : false);
  4886. }
  4887.  
  4888. bool APlayerController::WasInputKeyJustPressed(const FKey Key) const
  4889. {
  4890. return (PlayerInput ? PlayerInput->WasJustPressed(Key) : false);
  4891. }
  4892.  
  4893. bool APlayerController::WasInputKeyJustReleased(const FKey Key) const
  4894. {
  4895. return (PlayerInput ? PlayerInput->WasJustReleased(Key) : false);
  4896. }
  4897.  
  4898. float APlayerController::GetInputAnalogKeyState(const FKey Key) const
  4899. {
  4900. return (PlayerInput ? PlayerInput->GetKeyValue(Key) : 0.f);
  4901. }
  4902.  
  4903. FVector APlayerController::GetInputVectorKeyState(const FKey Key) const
  4904. {
  4905. return (PlayerInput ? PlayerInput->GetVectorKeyValue(Key) : FVector());
  4906. }
  4907.  
  4908. void APlayerController::GetInputTouchState(ETouchIndex::Type FingerIndex, float& LocationX, float& LocationY, bool& bIsCurrentlyPressed) const
  4909. {
  4910. if (PlayerInput)
  4911. {
  4912. if (FingerIndex < EKeys::NUM_TOUCH_KEYS)
  4913. {
  4914. LocationX = PlayerInput->Touches[FingerIndex].X;
  4915. LocationY = PlayerInput->Touches[FingerIndex].Y;
  4916. bIsCurrentlyPressed = PlayerInput->Touches[FingerIndex].Z != 0 ? true : false;
  4917. }
  4918. else
  4919. {
  4920. bIsCurrentlyPressed = false;
  4921. UE_LOG(LogPlayerController, Warning, TEXT("Requesting information for invalid finger index."));
  4922. }
  4923. }
  4924. else
  4925. {
  4926. LocationX = LocationY = 0.f;
  4927. bIsCurrentlyPressed = false;
  4928. }
  4929. }
  4930.  
  4931. void APlayerController::GetInputMotionState(FVector& Tilt, FVector& RotationRate, FVector& Gravity, FVector& Acceleration) const
  4932. {
  4933. Tilt = GetInputVectorKeyState(EKeys::Tilt);
  4934. RotationRate = GetInputVectorKeyState(EKeys::RotationRate);
  4935. Gravity = GetInputVectorKeyState(EKeys::Gravity);
  4936. Acceleration = GetInputVectorKeyState(EKeys::Acceleration);
  4937. }
  4938.  
  4939. float APlayerController::GetInputKeyTimeDown(const FKey Key) const
  4940. {
  4941. return (PlayerInput ? PlayerInput->GetTimeDown(Key) : 0.f);
  4942. }
  4943.  
  4944. bool APlayerController::GetMousePosition(float& LocationX, float& LocationY) const
  4945. {
  4946. bool bGotMousePosition = false;
  4947. ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
  4948.  
  4949. if (LocalPlayer && LocalPlayer->ViewportClient)
  4950. {
  4951. FVector2D MousePosition;
  4952.  
  4953. bGotMousePosition = LocalPlayer->ViewportClient->GetMousePosition(MousePosition);
  4954.  
  4955. if (bGotMousePosition)
  4956. {
  4957. LocationX = MousePosition.X;
  4958. LocationY = MousePosition.Y;
  4959. }
  4960. }
  4961.  
  4962. return bGotMousePosition;
  4963. }
  4964.  
  4965. void APlayerController::GetInputMouseDelta(float& DeltaX, float& DeltaY) const
  4966. {
  4967. if (PlayerInput)
  4968. {
  4969. DeltaX = PlayerInput->GetKeyValue(EKeys::MouseX);
  4970. DeltaY = PlayerInput->GetKeyValue(EKeys::MouseY);
  4971. }
  4972. else
  4973. {
  4974. DeltaX = DeltaY = 0.f;
  4975. }
  4976. }
  4977.  
  4978. void APlayerController::GetInputAnalogStickState(EControllerAnalogStick::Type WhichStick, float& StickX, float& StickY) const
  4979. {
  4980. if (PlayerInput)
  4981. {
  4982. switch (WhichStick)
  4983. {
  4984. case EControllerAnalogStick::CAS_LeftStick:
  4985. StickX = PlayerInput->GetKeyValue(EKeys::Gamepad_LeftX);
  4986. StickY = PlayerInput->GetKeyValue(EKeys::Gamepad_LeftY);
  4987. break;
  4988.  
  4989. case EControllerAnalogStick::CAS_RightStick:
  4990. StickX = PlayerInput->GetKeyValue(EKeys::Gamepad_RightX);
  4991. StickY = PlayerInput->GetKeyValue(EKeys::Gamepad_RightY);
  4992. break;
  4993.  
  4994. default:
  4995. StickX = 0.f;
  4996. StickY = 0.f;
  4997. }
  4998. }
  4999. else
  5000. {
  5001. StickX = StickY = 0.f;
  5002. }
  5003. }
  5004.  
  5005. void APlayerController::EnableInput(class APlayerController* PlayerController)
  5006. {
  5007. if (PlayerController == this || PlayerController == NULL)
  5008. {
  5009. bInputEnabled = true;
  5010. }
  5011. else
  5012. {
  5013. UE_LOG(LogPlayerController, Error, TEXT("EnableInput can only be specified on a PlayerController for itself"));
  5014. }
  5015. }
  5016.  
  5017. void APlayerController::DisableInput(class APlayerController* PlayerController)
  5018. {
  5019. if (PlayerController == this || PlayerController == NULL)
  5020. {
  5021. bInputEnabled = false;
  5022. }
  5023. else
  5024. {
  5025. UE_LOG(LogPlayerController, Error, TEXT("DisableInput can only be specified on a PlayerController for itself"));
  5026. }
  5027. }
  5028.  
  5029.  
  5030. void APlayerController::ActivateTouchInterface(UTouchInterface* NewTouchInterface)
  5031. {
  5032. CurrentTouchInterface = NewTouchInterface;
  5033. if(NewTouchInterface)
  5034. {
  5035. if (!VirtualJoystick.IsValid())
  5036. {
  5037. CreateTouchInterface();
  5038. }
  5039. else
  5040. {
  5041. NewTouchInterface->Activate(VirtualJoystick);
  5042. }
  5043. }
  5044. else if (VirtualJoystick.IsValid())
  5045. {
  5046. ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player);
  5047. if (LocalPlayer && LocalPlayer->ViewportClient)
  5048. {
  5049. LocalPlayer->ViewportClient->RemoveViewportWidgetContent(VirtualJoystick.ToSharedRef());
  5050. }
  5051. //clear any input before clearing the VirtualJoystick
  5052. FlushPressedKeys();
  5053. VirtualJoystick = NULL;
  5054. }
  5055. }
  5056.  
  5057. void APlayerController::SetVirtualJoystickVisibility(bool bVisible)
  5058. {
  5059. if (VirtualJoystick.IsValid())
  5060. {
  5061. VirtualJoystick->SetJoystickVisibility(bVisible, false);
  5062. }
  5063. }
  5064.  
  5065. void FInputModeDataBase::SetFocusAndLocking(FReply& SlateOperations, TSharedPtr<SWidget> InWidgetToFocus, bool bLockMouseToViewport, TSharedRef<SViewport> InViewportWidget) const
  5066. {
  5067. if (InWidgetToFocus.IsValid())
  5068. {
  5069. SlateOperations.SetUserFocus(InWidgetToFocus.ToSharedRef());
  5070. }
  5071.  
  5072. if (bLockMouseToViewport)
  5073. {
  5074. SlateOperations.LockMouseToWidget(InViewportWidget);
  5075. }
  5076. else
  5077. {
  5078. SlateOperations.ReleaseMouseLock();
  5079. }
  5080. }
  5081.  
  5082. void FInputModeUIOnly::ApplyInputMode(FReply& SlateOperations, class UGameViewportClient& GameViewportClient) const
  5083. {
  5084. TSharedPtr<SViewport> ViewportWidget = GameViewportClient.GetGameViewportWidget();
  5085. if (ViewportWidget.IsValid())
  5086. {
  5087. SetFocusAndLocking(SlateOperations, WidgetToFocus, MouseLockMode == EMouseLockMode::LockAlways, ViewportWidget.ToSharedRef());
  5088.  
  5089. SlateOperations.ReleaseMouseCapture();
  5090.  
  5091. GameViewportClient.SetMouseLockMode(MouseLockMode);
  5092. GameViewportClient.SetIgnoreInput(true);
  5093. GameViewportClient.SetCaptureMouseOnClick(EMouseCaptureMode::NoCapture);
  5094. }
  5095. }
  5096.  
  5097. void FInputModeGameAndUI::ApplyInputMode(FReply& SlateOperations, class UGameViewportClient& GameViewportClient) const
  5098. {
  5099. TSharedPtr<SViewport> ViewportWidget = GameViewportClient.GetGameViewportWidget();
  5100. if (ViewportWidget.IsValid())
  5101. {
  5102. SetFocusAndLocking(SlateOperations, WidgetToFocus, MouseLockMode == EMouseLockMode::LockAlways, ViewportWidget.ToSharedRef());
  5103.  
  5104. SlateOperations.ReleaseMouseCapture();
  5105.  
  5106. GameViewportClient.SetMouseLockMode(MouseLockMode);
  5107. GameViewportClient.SetIgnoreInput(false);
  5108. GameViewportClient.SetHideCursorDuringCapture(bHideCursorDuringCapture);
  5109. GameViewportClient.SetCaptureMouseOnClick(EMouseCaptureMode::CaptureDuringMouseDown);
  5110. }
  5111. }
  5112.  
  5113. void FInputModeGameOnly::ApplyInputMode(FReply& SlateOperations, class UGameViewportClient& GameViewportClient) const
  5114. {
  5115. TSharedPtr<SViewport> ViewportWidget = GameViewportClient.GetGameViewportWidget();
  5116. if (ViewportWidget.IsValid())
  5117. {
  5118. TSharedRef<SViewport> ViewportWidgetRef = ViewportWidget.ToSharedRef();
  5119. SlateOperations.UseHighPrecisionMouseMovement(ViewportWidgetRef);
  5120. SlateOperations.SetUserFocus(ViewportWidgetRef);
  5121. SlateOperations.LockMouseToWidget(ViewportWidgetRef);
  5122. GameViewportClient.SetMouseLockMode(EMouseLockMode::LockOnCapture);
  5123. GameViewportClient.SetIgnoreInput(false);
  5124. GameViewportClient.SetCaptureMouseOnClick(bConsumeCaptureMouseDown ? EMouseCaptureMode::CapturePermanently : EMouseCaptureMode::CapturePermanently_IncludingInitialMouseDown);
  5125. }
  5126. }
  5127.  
  5128. void APlayerController::SetInputMode(const FInputModeDataBase& InData)
  5129. {
  5130. UGameViewportClient* GameViewportClient = GetWorld()->GetGameViewport();
  5131. ULocalPlayer* LocalPlayer = Cast< ULocalPlayer >( Player );
  5132. if ( GameViewportClient && LocalPlayer )
  5133. {
  5134. InData.ApplyInputMode( LocalPlayer->GetSlateOperations(), *GameViewportClient );
  5135. }
  5136. }
  5137.  
  5138. void APlayerController::UpdateCameraManager(float DeltaSeconds)
  5139. {
  5140. if (PlayerCameraManager != NULL)
  5141. {
  5142. PlayerCameraManager->UpdateCamera(DeltaSeconds);
  5143. }
  5144. }
  5145.  
  5146. void APlayerController::BuildHiddenComponentList(const FVector& ViewLocation, TSet<FPrimitiveComponentId>& HiddenComponentsOut)
  5147. {
  5148. // Makes no sens to build hidden component list if should not render any components.
  5149. check(bRenderPrimitiveComponents);
  5150.  
  5151. // Translate the hidden actors list to a hidden primitive list.
  5152. UpdateHiddenActors(ViewLocation);
  5153.  
  5154. for (int32 ActorIndex = 0; ActorIndex < HiddenActors.Num(); ++ActorIndex)
  5155. {
  5156. AActor* HiddenActor = HiddenActors[ActorIndex];
  5157. if (HiddenActor != NULL)
  5158. {
  5159. TInlineComponentArray<UPrimitiveComponent*> Components;
  5160. HiddenActor->GetComponents(Components);
  5161.  
  5162. for (int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++)
  5163. {
  5164. UPrimitiveComponent* PrimitiveComponent = Components[ComponentIndex];
  5165. if (PrimitiveComponent->IsRegistered())
  5166. {
  5167. HiddenComponentsOut.Add(PrimitiveComponent->ComponentId);
  5168.  
  5169. for (USceneComponent* AttachedChild : PrimitiveComponent->GetAttachChildren())
  5170. {
  5171. UPrimitiveComponent* AttachChildPC = Cast<UPrimitiveComponent>(AttachedChild);
  5172. if (AttachChildPC && AttachChildPC->IsRegistered())
  5173. {
  5174. HiddenComponentsOut.Add(AttachChildPC->ComponentId);
  5175. }
  5176. }
  5177. }
  5178. }
  5179. }
  5180. else
  5181. {
  5182. HiddenActors.RemoveAt(ActorIndex);
  5183. ActorIndex--;
  5184. }
  5185. }
  5186.  
  5187. // iterate backwards so we can remove as we go
  5188. for (int32 ComponentIndx = HiddenPrimitiveComponents.Num() - 1; ComponentIndx >= 0; --ComponentIndx)
  5189. {
  5190. TWeakObjectPtr<UPrimitiveComponent> ComponentPtr = HiddenPrimitiveComponents[ComponentIndx];
  5191. if (ComponentPtr.IsValid())
  5192. {
  5193. UPrimitiveComponent* Component = ComponentPtr.Get();
  5194. if (Component->IsRegistered())
  5195. {
  5196. HiddenComponentsOut.Add(Component->ComponentId);
  5197. }
  5198. }
  5199. else
  5200. {
  5201. HiddenPrimitiveComponents.RemoveAt(ComponentIndx);
  5202. }
  5203. }
  5204.  
  5205. // Allow a chance to operate on a per primitive basis
  5206. UpdateHiddenComponents(ViewLocation, HiddenComponentsOut);
  5207. }
  5208.  
  5209. /// @cond DOXYGEN_WARNINGS
  5210.  
  5211. void APlayerController::ClientRepObjRef_Implementation(UObject *Object)
  5212. {
  5213. UE_LOG(LogPlayerController, Warning, TEXT("APlayerController::ClientRepObjRef repped: %s"), Object ? *Object->GetName() : TEXT("NULL") );
  5214. }
  5215.  
  5216. /// @endcond
  5217.  
  5218. void FDynamicForceFeedbackDetails::Update(FForceFeedbackValues& Values) const
  5219. {
  5220. if (bAffectsLeftLarge)
  5221. {
  5222. Values.LeftLarge = FMath::Clamp(Intensity, Values.LeftLarge, 1.f);
  5223. }
  5224. if (bAffectsLeftSmall)
  5225. {
  5226. Values.LeftSmall = FMath::Clamp(Intensity, Values.LeftSmall, 1.f);
  5227. }
  5228. if (bAffectsRightLarge)
  5229. {
  5230. Values.RightLarge = FMath::Clamp(Intensity, Values.RightLarge, 1.f);
  5231. }
  5232. if (bAffectsRightSmall)
  5233. {
  5234. Values.RightSmall = FMath::Clamp(Intensity, Values.RightSmall, 1.f);
  5235. }
  5236. }
  5237.  
  5238. /// @cond DOXYGEN_WARNINGS
  5239.  
  5240. void APlayerController::OnServerStartedVisualLogger_Implementation(bool bIsLogging)
  5241. {
  5242. #if ENABLE_VISUAL_LOG
  5243. FVisualLogger::Get().SetIsRecordingOnServer(bIsLogging);
  5244. ClientMessage(FString::Printf(TEXT("Visual Loggger is %s."), FVisualLogger::Get().IsRecordingOnServer() ? TEXT("now recording") : TEXT("disabled")));
  5245. #endif
  5246. }
  5247.  
  5248. /// @endcond
  5249.  
  5250. bool APlayerController::ShouldPerformFullTickWhenPaused() const
  5251. {
  5252. return bShouldPerformFullTickWhenPaused ||
  5253. (/*bIsInVr =*/GEngine->StereoRenderingDevice.IsValid() && GEngine->StereoRenderingDevice->IsStereoEnabled() &&
  5254. GEngine->XRSystem.IsValid() && GEngine->XRSystem->GetHMDDevice() && GEngine->XRSystem->GetHMDDevice()->IsHMDConnected());
  5255. }
  5256.  
  5257. #undef LOCTEXT_NAMESPACE
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement