bool FGameplayDebugger::IsGameplayDebuggerActiveForPlayerController(APlayerController* PlayerController) { #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) if (PlayerController == NULL) { return false; } UWorld* World = PlayerController->GetWorld(); if (World == NULL) { return false; } for (auto It = GetAllReplicators(World).CreateConstIterator(); It; ++It) { AGameplayDebuggingReplicator* Replicator = It->Get(); if (Replicator && Replicator->GetLocalPlayerOwner() == PlayerController) { return Replicator->IsDrawEnabled(); } } #endif return false; }
void FBehaviorTreeDebugger::FindLockedDebugActor(UWorld* World) { APlayerController* LocalPC = GEngine->GetFirstLocalPlayerController(World); if (LocalPC && LocalPC->GetHUD() && LocalPC->GetPawnOrSpectator()) { AGameplayDebuggingReplicator* DebuggingReplicator = NULL; for (TActorIterator<AGameplayDebuggingReplicator> It(World); It; ++It) { AGameplayDebuggingReplicator* A = *It; if (!A->IsPendingKill()) { DebuggingReplicator = A; break; } } const APawn* LockedPawn = DebuggingReplicator != NULL ? Cast<APawn>(DebuggingReplicator->GetSelectedActorToDebug()) : NULL; UBehaviorTreeComponent* TestInstance = FindInstanceInActor((APawn*)LockedPawn); if (TestInstance) { TreeInstance = TestInstance; #if USE_BEHAVIORTREE_DEBUGGER ActiveStepIndex = TestInstance->DebuggerSteps.Num() - 1; #endif } } }
void UGameplayDebuggingComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) if (World && World->GetNetMode() < NM_Client) { if (bEnabledTargetSelection) { AGameplayDebuggingReplicator* Replicator = Cast<AGameplayDebuggingReplicator>(GetOwner()); if (Replicator) { if (Replicator->GetLocalPlayerOwner()) { SelectTargetToDebug(); } } } CollectDataToReplicate(true); } AGameplayDebuggingReplicator* Replicator = Cast<AGameplayDebuggingReplicator>(GetOwner()); #endif //!(UE_BUILD_SHIPPING || UE_BUILD_TEST) }
//----------------------------------------------------------------------// // rendering //----------------------------------------------------------------------// FPrimitiveSceneProxy* UGameplayDebuggingComponent::CreateSceneProxy() { FDebugRenderSceneCompositeProxy* CompositeProxy = NULL; AGameplayDebuggingReplicator* Replicator = Cast<AGameplayDebuggingReplicator>(GetOwner()); if (!World || World->GetNetMode() == NM_DedicatedServer) { return NULL; } if (!Replicator || !Replicator->IsDrawEnabled()) { return NULL; } #if WITH_RECAST if (ShouldReplicateData(EAIDebugDrawDataView::NavMesh)) { FNavMeshSceneProxyData NewNavmeshRenderData; NewNavmeshRenderData.Reset(); NewNavmeshRenderData.bNeedsNewData = false; NewNavmeshRenderData.bEnableDrawing = false; PrepareNavMeshData(&NewNavmeshRenderData); NavMeshBounds = NewNavmeshRenderData.Bounds; CompositeProxy = CompositeProxy ? CompositeProxy : (new FDebugRenderSceneCompositeProxy(this)); CompositeProxy->AddChild(new FRecastRenderingSceneProxy(this, &NewNavmeshRenderData, true)); } #endif #if USE_EQS_DEBUGGER if (ShouldReplicateData(EAIDebugDrawDataView::EQS) && IsClientEQSSceneProxyEnabled()) { const int32 EQSIndex = EQSLocalData.Num() > 0 ? FMath::Clamp(CurrentEQSIndex, 0, EQSLocalData.Num() - 1) : INDEX_NONE; if (EQSLocalData.IsValidIndex(EQSIndex)) { CompositeProxy = CompositeProxy ? CompositeProxy : (new FDebugRenderSceneCompositeProxy(this)); auto& CurrentLocalData = EQSLocalData[EQSIndex]; FString ViewFlagName = TEXT("Game"); #if WITH_EDITOR UEditorEngine* EEngine = Cast<UEditorEngine>(GEngine); if (EEngine && EEngine->bIsSimulatingInEditor) { ViewFlagName = TEXT("DebugAI"); } #endif CompositeProxy->AddChild(new FEQSSceneProxy(this, ViewFlagName, false, CurrentLocalData.SolidSpheres, CurrentLocalData.Texts)); } } #endif // USE_EQS_DEBUGGER return CompositeProxy; }
void UGameplayDebuggingComponent::CollectDataToReplicate(bool bCollectExtendedData) { #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) if (!GetSelectedActor()) { return; } if (ShouldReplicateData(EAIDebugDrawDataView::Basic) || ShouldReplicateData(EAIDebugDrawDataView::OverHead)) { CollectBasicData(); } AGameplayDebuggingReplicator* Replicator = Cast<AGameplayDebuggingReplicator>(GetOwner()); const bool bDrawFullData = Replicator->GetSelectedActorToDebug() == GetSelectedActor(); if (bDrawFullData && ShouldReplicateData(EAIDebugDrawDataView::Basic)) { CollectPathData(); } if (bCollectExtendedData && bDrawFullData) { if (ShouldReplicateData(EAIDebugDrawDataView::BehaviorTree)) { CollectBehaviorTreeData(); } #if WITH_EQS if (ShouldReplicateData(EAIDebugDrawDataView::EQS)) { bool bEnabledEnvironmentQueryEd = true; if (GConfig) { GConfig->GetBool(TEXT("EnvironmentQueryEd"), TEXT("EnableEnvironmentQueryEd"), bEnabledEnvironmentQueryEd, GEngineIni); } if (bEnabledEnvironmentQueryEd) { CollectEQSData(); } } #endif // WITH_EQS } #endif //!(UE_BUILD_SHIPPING || UE_BUILD_TEST) }
AGameplayDebuggingReplicator* AGameplayDebuggingHUDComponent::GetDebuggingReplicator() { #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) if (CachedDebuggingReplicator.IsValid() && CachedDebuggingReplicator->GetLocalPlayerOwner() == PlayerOwner) { return CachedDebuggingReplicator.Get(); } for (TActorIterator<AGameplayDebuggingReplicator> It(GetWorld()); It; ++It) { AGameplayDebuggingReplicator* Replicator = *It; if (!Replicator->IsPendingKill() && Replicator->GetLocalPlayerOwner() == PlayerOwner) { CachedDebuggingReplicator = Replicator; return Replicator; } } #endif return NULL; }
void FGameplayDebugger::OnLevelActorDeleted(AActor* InActor) { #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) if (!InActor) { return; } UWorld* World = InActor->GetWorld(); if (!World) { return; } AGameplayDebuggingReplicator* Replicator = Cast<AGameplayDebuggingReplicator>(InActor); if (Replicator) { RemoveReplicator(World, Replicator); } else { APlayerController* PC = Cast<APlayerController>(InActor); if (PC) { // Take a copy because the destroy could lead to removes on the replicator array TArray<TWeakObjectPtr<AGameplayDebuggingReplicator>> ReplicatorsForWorld = GetAllReplicators(World); for (TWeakObjectPtr<AGameplayDebuggingReplicator> ReplicatorPtr : ReplicatorsForWorld) { AGameplayDebuggingReplicator* ReplicatorInWorld = ReplicatorPtr.Get(); if (ReplicatorInWorld && ReplicatorInWorld->GetLocalPlayerOwner() == PC) { ReplicatorInWorld->Destroy(); break; } } } } #endif }
bool FGameplayDebugger::CreateGameplayDebuggerForPlayerController(APlayerController* PlayerController) { #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) if (PlayerController == NULL) { return false; } bool bIsServer = PlayerController->GetNetMode() < ENetMode::NM_Client; // (Only create on some sort of server) if (!bIsServer) { return false; } UWorld* World = PlayerController->GetWorld(); if (World == NULL) { return false; } if (DoesGameplayDebuggingReplicatorExistForPlayerController(PlayerController)) { // No need to create one if we already have one. return false; } FActorSpawnParameters SpawnInfo; SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; SpawnInfo.ObjectFlags = RF_Transient; SpawnInfo.Name = *FString::Printf(TEXT("GameplayDebuggingReplicator_%s"), *PlayerController->GetName()); AGameplayDebuggingReplicator* DestActor = World->SpawnActor<AGameplayDebuggingReplicator>(FVector::ZeroVector, FRotator::ZeroRotator, SpawnInfo); if (DestActor != NULL) { DestActor->SetLocalPlayerOwner(PlayerController); DestActor->SetReplicates(true); DestActor->SetAsGlobalInWorld(false); #if WITH_EDITOR UEditorEngine* EEngine = Cast<UEditorEngine>(GEngine); if (EEngine && EEngine->bIsSimulatingInEditor) { DestActor->CreateTool(); DestActor->EnableTool(); } #endif AddReplicator(World, DestActor); return true; } #endif return false; }
void FGameplayDebugger::WorldAdded(UWorld* InWorld) { #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) bool bIsServer = InWorld && InWorld->GetNetMode() < ENetMode::NM_Client; // (Only server code) if (!bIsServer) { return; } if (InWorld == NULL || InWorld->IsPendingKill() || InWorld->IsGameWorld() == false) { return; } for (auto It = GetAllReplicators(InWorld).CreateConstIterator(); It; ++It) { AGameplayDebuggingReplicator* Replicator = It->Get(); if (Replicator && Replicator->IsGlobalInWorld()) { // Ok, we have global replicator on level return; } } // create global replicator on level FActorSpawnParameters SpawnInfo; SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; SpawnInfo.ObjectFlags = RF_Transient; SpawnInfo.Name = *FString::Printf(TEXT("GameplayDebuggingReplicator_Global")); AGameplayDebuggingReplicator* DestActor = InWorld->SpawnActor<AGameplayDebuggingReplicator>(FVector::ZeroVector, FRotator::ZeroRotator, SpawnInfo); if (DestActor != NULL) { DestActor->SetLocalPlayerOwner(NULL); DestActor->SetReplicates(false); DestActor->SetActorTickEnabled(true); DestActor->SetAsGlobalInWorld(true); AddReplicator(InWorld, DestActor); } #endif //!(UE_BUILD_SHIPPING || UE_BUILD_TEST) }
bool FGameplayDebugger::Exec(UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar) { #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) bool bHandled = false; if (FParse::Command(&Cmd, TEXT("RunEQS")) && InWorld) { APlayerController* MyPC = InWorld->GetGameInstance() ? InWorld->GetGameInstance()->GetFirstLocalPlayerController() : nullptr; UAISystem* AISys = UAISystem::GetCurrent(*InWorld); UEnvQueryManager* EQS = AISys ? AISys->GetEnvironmentQueryManager() : NULL; if (MyPC && EQS) { AGameplayDebuggingReplicator* DebuggingReplicator = NULL; for (TActorIterator<AGameplayDebuggingReplicator> It(InWorld); It; ++It) { AGameplayDebuggingReplicator* A = *It; if (!A->IsPendingKill()) { DebuggingReplicator = A; if (!DebuggingReplicator->IsGlobalInWorld() && DebuggingReplicator->GetLocalPlayerOwner() == MyPC) { break; } } } UObject* Target = DebuggingReplicator != NULL ? DebuggingReplicator->GetSelectedActorToDebug() : NULL; FString QueryName = FParse::Token(Cmd, 0); if (Target) { AISys->RunEQS(QueryName, Target); } else { MyPC->ClientMessage(TEXT("No debugging target to run EQS")); } } return true; } if (FParse::Command(&Cmd, TEXT("EnableGDT")) == false) { return false; } FString UniquePlayerId = FParse::Token(Cmd, 0); APlayerController* LocalPC = NULL; UWorld* MyWorld = InWorld; if (MyWorld == nullptr) { if (UniquePlayerId.Len() > 0) { // let's find correct world based on Player Id const TIndirectArray<FWorldContext> WorldContexts = GEngine->GetWorldContexts(); for (auto& Context : WorldContexts) { if (Context.WorldType != EWorldType::Game && Context.WorldType != EWorldType::PIE) { continue; } UWorld *CurrentWorld = Context.World(); for (FConstPlayerControllerIterator Iterator = CurrentWorld->GetPlayerControllerIterator(); Iterator; ++Iterator) { APlayerController* PC = *Iterator; if (PC && PC->PlayerState->UniqueId.ToString() == UniquePlayerId) { LocalPC = PC; MyWorld = PC->GetWorld(); break; } } if (LocalPC && MyWorld) { break; } } } } if (MyWorld == nullptr) { return false; } if (LocalPC == nullptr) { if (UniquePlayerId.Len() > 0) { for (FConstPlayerControllerIterator Iterator = MyWorld->GetPlayerControllerIterator(); Iterator; ++Iterator) { APlayerController* PlayerController = *Iterator; UE_LOG(LogGameplayDebugger, Log, TEXT("- Client: %s"), *PlayerController->PlayerState->UniqueId.ToString()); if (PlayerController && PlayerController->PlayerState->UniqueId.ToString() == UniquePlayerId) { LocalPC = PlayerController; break; } } } if (!LocalPC && MyWorld->GetNetMode() != NM_DedicatedServer) { LocalPC = MyWorld->GetGameInstance() ? MyWorld->GetGameInstance()->GetFirstLocalPlayerController() : nullptr; } } if (LocalPC == nullptr) { return false; } if (MyWorld->GetNetMode() == NM_Client) { AGameplayDebuggingReplicator* Replicator = NULL; for (TActorIterator<AGameplayDebuggingReplicator> It(MyWorld); It; ++It) { Replicator = *It; if (Replicator && !Replicator->IsPendingKill()) { APlayerController* PCOwner = Replicator->GetLocalPlayerOwner(); if (LocalPC == PCOwner) { break; } } Replicator = NULL; } if (!Replicator) { LocalPC->ClientMessage(TEXT("Enabling GameplayDebugger on server, please wait for replicated data...")); if (LocalPC->PlayerState) { const FString ServerCheatString = FString::Printf(TEXT("cheat EnableGDT %s"), *LocalPC->PlayerState->UniqueId.ToString()); UE_LOG(LogGameplayDebugger, Warning, TEXT("Sending to Server: %s"), *ServerCheatString); LocalPC->ConsoleCommand(*ServerCheatString); bHandled = true; } } else { if (Replicator->IsToolCreated() == false) { Replicator->CreateTool(); } Replicator->EnableTool(); bHandled = true; } } else { UE_LOG(LogGameplayDebugger, Warning, TEXT("Got from client: EnableGDT %s"), *UniquePlayerId); { AGameplayDebuggingReplicator* Replicator = NULL; for (TActorIterator<AGameplayDebuggingReplicator> It(MyWorld); It; ++It) { Replicator = *It; if (Replicator && !Replicator->IsPendingKill()) { APlayerController* PCOwner = Replicator->GetLocalPlayerOwner(); if (LocalPC == PCOwner) { break; } } Replicator = NULL; } if (!Replicator) { CreateGameplayDebuggerForPlayerController(LocalPC); for (TActorIterator<AGameplayDebuggingReplicator> It(MyWorld); It; ++It) { Replicator = *It; if (Replicator && !Replicator->IsPendingKill()) { APlayerController* PCOwner = Replicator->GetLocalPlayerOwner(); if (LocalPC == PCOwner) { break; } } Replicator = NULL; } } if (MyWorld->GetNetMode() != NM_DedicatedServer) { if (Replicator && !Replicator->IsToolCreated()) { Replicator->CreateTool(); Replicator->EnableTool(); bHandled = true; } } else { if (Replicator) { Replicator->ClientAutoActivate(); bHandled = true; } } } } return bHandled; #else return false; #endif //!(UE_BUILD_SHIPPING || UE_BUILD_TEST) }
void UGameplayDebuggingComponent::SelectTargetToDebug() { #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) AGameplayDebuggingReplicator* Replicator = Cast<AGameplayDebuggingReplicator>(GetOwner()); APlayerController* MyPC = Replicator->GetLocalPlayerOwner(); if (MyPC ) { APawn* BestTarget = NULL; if (MyPC->GetViewTarget() != NULL && MyPC->GetViewTarget() != MyPC->GetPawn()) { BestTarget = Cast<APawn>(MyPC->GetViewTarget()); if (BestTarget && ((BestTarget->PlayerState != NULL && BestTarget->PlayerState->bIsABot == false) || BestTarget->GetActorEnableCollision() == false)) { BestTarget = NULL; } } float bestAim = 0.f; FVector CamLocation; FRotator CamRotation; check(MyPC->PlayerCameraManager != NULL); MyPC->PlayerCameraManager->GetCameraViewPoint(CamLocation, CamRotation); FVector FireDir = CamRotation.Vector(); UWorld* World = MyPC->GetWorld(); check( World ); APawn* PossibleTarget = NULL; for (FConstPawnIterator Iterator = World->GetPawnIterator(); Iterator; ++Iterator ) { APawn* NewTarget = *Iterator; if (NewTarget == NULL || NewTarget == MyPC->GetPawn() || (NewTarget->PlayerState != NULL && NewTarget->PlayerState->bIsABot == false) || NewTarget->GetActorEnableCollision() == false) { continue; } if (BestTarget == NULL && (NewTarget != MyPC->GetPawn())) { // look for best controlled pawn target const FVector AimDir = NewTarget->GetActorLocation() - CamLocation; float FireDist = AimDir.SizeSquared(); // only find targets which are < 25000 units away if (FireDist < 625000000.f) { FireDist = FMath::Sqrt(FireDist); float newAim = FireDir | AimDir; newAim = newAim/FireDist; if (newAim > bestAim) { PossibleTarget = NewTarget; bestAim = newAim; } } } } BestTarget = BestTarget == NULL ? PossibleTarget : BestTarget; if (BestTarget != NULL && BestTarget != GetSelectedActor()) { if (AGameplayDebuggingReplicator* Replicator = Cast<AGameplayDebuggingReplicator>(GetOwner())) { Replicator->SetActorToDebug(Cast<AActor>(BestTarget)); } //always update component for best target SetActorToDebug(Cast<AActor>(BestTarget)); ServerReplicateData(EDebugComponentMessage::ActivateReplication, EAIDebugDrawDataView::Empty); } } #endif //!(UE_BUILD_SHIPPING || UE_BUILD_TEST) }