PyObject *py_ue_get_player_pawn(ue_PyUObject *self, PyObject * args) { ue_py_check(self); int controller_id = 0; if (!PyArg_ParseTuple(args, "|i:get_player_pawn", &controller_id)) { return NULL; } UWorld *world = ue_get_uworld(self); if (!world) return PyErr_Format(PyExc_Exception, "unable to retrieve UWorld from uobject"); APlayerController *controller = UGameplayStatics::GetPlayerController(world, controller_id); if (!controller) return PyErr_Format(PyExc_Exception, "unable to retrieve controller %d", controller_id); // the controller could not have a pawn if (!controller->GetPawn()) Py_RETURN_NONE; Py_RETURN_UOBJECT(controller->GetPawn()); }
void AGameplayDebuggerReplicator::SelectTargetToDebug() { #if ENABLED_GAMEPLAY_DEBUGGER APlayerController* MyPC = DebugCameraController.IsValid() ? DebugCameraController.Get() : GetLocalPlayerOwner(); if (MyPC) { float bestAim = 0; FVector CamLocation; FRotator CamRotation; check(MyPC->PlayerCameraManager != nullptr); MyPC->PlayerCameraManager->GetCameraViewPoint(CamLocation, CamRotation); FVector FireDir = CamRotation.Vector(); UWorld* World = MyPC->GetWorld(); check(World); APawn* PossibleTarget = nullptr; for (FConstPawnIterator Iterator = World->GetPawnIterator(); Iterator; ++Iterator) { APawn* NewTarget = *Iterator; if (NewTarget == nullptr || NewTarget == MyPC->GetPawn() || (NewTarget->PlayerState != nullptr && NewTarget->PlayerState->bIsABot == false) || NewTarget->GetActorEnableCollision() == false) { continue; } if (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 = FVector::DotProduct(FireDir, AimDir); newAim = newAim / FireDist; if (newAim > bestAim) { PossibleTarget = NewTarget; bestAim = newAim; } } } } if (PossibleTarget != nullptr && PossibleTarget != LastSelectedActorToDebug) { ServerSetActorToDebug(Cast<AActor>(PossibleTarget)); } } #endif //ENABLED_GAMEPLAY_DEBUGGER }
bool AGameModeBase::SpawnPlayerFromSimulate(const FVector& NewLocation, const FRotator& NewRotation) { #if WITH_EDITOR APlayerController* PC = GetGameInstance()->GetFirstLocalPlayerController(); if (PC != nullptr) { PC->PlayerState->bOnlySpectator = false; bool bNeedsRestart = true; if (PC->GetPawn() == nullptr) { // Use the "auto-possess" pawn in the world, if there is one. for (FConstPawnIterator Iterator = GetWorld()->GetPawnIterator(); Iterator; ++Iterator) { APawn* Pawn = *Iterator; if (Pawn && Pawn->AutoPossessPlayer == EAutoReceiveInput::Player0) { if (Pawn->Controller == nullptr) { PC->Possess(Pawn); bNeedsRestart = false; } break; } } } if (bNeedsRestart) { RestartPlayer(PC); if (PC->GetPawn()) { // If there was no player start, then try to place the pawn where the camera was. if (PC->StartSpot == nullptr || Cast<AWorldSettings>(PC->StartSpot.Get())) { const FVector Location = NewLocation; const FRotator Rotation = NewRotation; PC->SetControlRotation(Rotation); PC->GetPawn()->TeleportTo(Location, Rotation); } } } } #endif return true; }
void AFunctionalTest::GoToObservationPoint() { if (ObservationPoint == NULL) { return; } UWorld* World = GetWorld(); if (World) { APlayerController* PC = World->GetFirstPlayerController(); if (PC && PC->GetPawn()) { PC->GetPawn()->TeleportTo(ObservationPoint->GetActorLocation(), ObservationPoint->GetActorRotation(), /*bIsATest=*/false, /*bNoCheck=*/true); PC->SetControlRotation(ObservationPoint->GetActorRotation()); } } }
AActor* AGunLockGameMode::ChoosePlayerStart(AController* Player) { // Find a player start that is furthest from other players APawn* PawnToFit = DefaultPawnClass ? DefaultPawnClass->GetDefaultObject<APawn>() : NULL; APlayerStart* BestPlayerStart = NULL; float MaxPlayerDistance = 0.0f; for (int32 PlayerStartIndex = 0; PlayerStartIndex < PlayerStarts.Num(); ++PlayerStartIndex) { APlayerStart* PlayerStart = PlayerStarts[PlayerStartIndex]; if (PlayerStart != NULL) { // Always prefer the first "Play from Here" PlayerStart, if we find one while in PIE mode if (Cast<APlayerStartPIE>(PlayerStart) != NULL) return PlayerStart; // Find the minimum distance to other players float MinPlayerDistance = HALF_WORLD_MAX; FVector SpawnLocation = PlayerStart->GetActorLocation(); const FRotator SpawnRotation = PlayerStart->GetActorRotation(); for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator) { APlayerController* PlayerController = *Iterator; if (Player != PlayerController && PlayerController->GetPawn()) { MinPlayerDistance = FMath::Min(MinPlayerDistance, (SpawnLocation - PlayerController->GetPawn()->GetActorLocation()).Size()); } } // Choose the spawn that is furtherest from all other players, to give them a fighting chance! if (MinPlayerDistance > MaxPlayerDistance) { MaxPlayerDistance = MinPlayerDistance; BestPlayerStart = PlayerStart; } } } //If we couldn't find any suitable spawns, pick a random one! if (BestPlayerStart == NULL && PlayerStarts.Num() > 0) { return PlayerStarts[FMath::RandRange(0, PlayerStarts.Num() - 1)]; } return BestPlayerStart; }
void USoundNodeLocalPlayer::ParseNodes(FAudioDevice* AudioDevice, const UPTRINT NodeWaveInstanceHash, FActiveSound& ActiveSound, const FSoundParseParameters& ParseParams, TArray<FWaveInstance*>& WaveInstances) { // The accesses to the Pawn will be unsafe once we thread audio, deal with this at that point check(IsInGameThread()); AActor* SoundOwner = ActiveSound.AudioComponent.IsValid() ? ActiveSound.AudioComponent->GetOwner() : NULL; APlayerController* PCOwner = Cast<APlayerController>(SoundOwner); APawn* PawnOwner = (PCOwner ? PCOwner->GetPawn() : Cast<APawn>(SoundOwner)); const bool bLocallyControlled = PawnOwner && PawnOwner->IsLocallyControlled() && Cast<APlayerController>(PawnOwner->Controller); const int32 PlayIndex = bLocallyControlled ? 0 : 1; if (PlayIndex < ChildNodes.Num() && ChildNodes[PlayIndex]) { ChildNodes[PlayIndex]->ParseNodes(AudioDevice, GetNodeWaveInstanceHash(NodeWaveInstanceHash, ChildNodes[PlayIndex], PlayIndex), ActiveSound, ParseParams, WaveInstances); } }
void APlayerCameraManager::PlayWorldCameraShake(UWorld* InWorld, TSubclassOf<class UCameraShake> Shake, FVector Epicenter, float InnerRadius, float OuterRadius, float Falloff, bool bOrientShakeTowardsEpicenter ) { for( FConstPlayerControllerIterator Iterator = InWorld->GetPlayerControllerIterator(); Iterator; ++Iterator ) { APlayerController* PlayerController = *Iterator; if (PlayerController && PlayerController->PlayerCameraManager != NULL) { float ShakeScale = CalcRadialShakeScale(PlayerController->PlayerCameraManager, Epicenter, InnerRadius, OuterRadius, Falloff); if (bOrientShakeTowardsEpicenter && PlayerController->GetPawn() != NULL) { FVector CamLoc; FRotator CamRot; PlayerController->PlayerCameraManager->GetCameraViewPoint(CamLoc, CamRot); PlayerController->ClientPlayCameraShake(Shake, ShakeScale, ECameraAnimPlaySpace::UserDefined, (Epicenter - CamLoc).Rotation()); } else { PlayerController->ClientPlayCameraShake(Shake, ShakeScale); } } } }
void UCheatManager::TickCollisionDebug() { // If we are debugging capsule tracing if(bDebugCapsuleSweep) { APlayerController* PC = GetOuterAPlayerController(); if(PC) { // Get view location to act as start point FVector ViewLoc; FRotator ViewRot; PC->GetPlayerViewPoint(ViewLoc, ViewRot); FVector ViewDir = ViewRot.Vector(); FVector End = ViewLoc + (DebugTraceDistance * ViewDir); // Fill in params and do trace static const FName TickCollisionDebugName(TEXT("TickCollisionDebug")); FCollisionQueryParams CapsuleParams(TickCollisionDebugName, false, PC->GetPawn()); CapsuleParams.bTraceComplex = bDebugCapsuleTraceComplex; if (bDebugCapsuleSweep) { // If we get a hit, draw the capsule FHitResult Result; bool bHit = GetWorld()->SweepSingle(Result, ViewLoc, End, FQuat::Identity, DebugTraceChannel, FCollisionShape::MakeCapsule(DebugCapsuleRadius, DebugCapsuleHalfHeight), CapsuleParams); if(bHit) { AddCapsuleSweepDebugInfo(ViewLoc, End, Result.ImpactPoint, Result.Normal, Result.ImpactNormal, Result.Location, DebugCapsuleHalfHeight, DebugCapsuleRadius, false, (Result.bStartPenetrating && Result.bBlockingHit)? true: false); UE_LOG(LogCollision, Log, TEXT("Collision component (%s) : Actor (%s)"), *GetNameSafe(Result.Component.Get()), *GetNameSafe(Result.GetActor())); } } } } // draw for (int32 TraceIdx=0; TraceIdx < DebugTraceInfoList.Num(); ++TraceIdx) { FDebugTraceInfo & TraceInfo = DebugTraceInfoList[TraceIdx]; DrawDebugDirectionalArrow(GetWorld(), TraceInfo.LineTraceStart, TraceInfo.LineTraceEnd, 10.f, FColor::White, SDPG_World); // if it's current trace index, use highlight color if (CurrentTraceIndex == TraceIdx) { if (TraceInfo.bInsideOfObject) { DrawDebugCapsule(GetWorld(), TraceInfo.HitLocation, TraceInfo.CapsuleHalfHeight, TraceInfo.CapsuleRadius, FQuat::Identity, FColor(255,100,64)); } else { DrawDebugCapsule(GetWorld(), TraceInfo.HitLocation, TraceInfo.CapsuleHalfHeight, TraceInfo.CapsuleRadius, FQuat::Identity, FColor(255,200,128)); } } else { if (TraceInfo.bInsideOfObject) { DrawDebugCapsule(GetWorld(), TraceInfo.HitLocation, TraceInfo.CapsuleHalfHeight, TraceInfo.CapsuleRadius, FQuat::Identity, FColor(64,100,255)); } else { DrawDebugCapsule(GetWorld(), TraceInfo.HitLocation, TraceInfo.CapsuleHalfHeight, TraceInfo.CapsuleRadius, FQuat::Identity, FColor(128,200,255)); } } DrawDebugDirectionalArrow(GetWorld(), TraceInfo.HitNormalStart, TraceInfo.HitNormalEnd, 5, FColor(255,64,64), SDPG_World); DrawDebugDirectionalArrow(GetWorld(), TraceInfo.HitNormalStart, TraceInfo.HitImpactNormalEnd, 5, FColor(64,64,255), SDPG_World); } FLinearColor CurrentColor(255.f/255.f,96.f/255.f,96/255.f); FLinearColor DeltaColor = (FLinearColor(1.0f, 1.0f, 1.0f, 1.0f) - CurrentColor)*0.1f; int32 TotalCount=0; if ( DebugTracePawnInfoList.Num() > 0 ) { // the latest will draw very red-ish to whiter color as it gets older. for (int32 TraceIdx=CurrentTracePawnIndex; TotalCount<10; TraceIdx=SAFE_TRACEINDEX_DECREASE(TraceIdx), CurrentColor+=DeltaColor, ++TotalCount) { FDebugTraceInfo & TraceInfo = DebugTracePawnInfoList[TraceIdx]; DrawDebugDirectionalArrow(GetWorld(), TraceInfo.LineTraceStart, TraceInfo.LineTraceEnd, 10.f, FColor(200,200,100), SDPG_World); if (TraceInfo.bInsideOfObject) { DrawDebugCapsule(GetWorld(), TraceInfo.HitLocation, TraceInfo.CapsuleHalfHeight, TraceInfo.CapsuleRadius, FQuat::Identity, FColor(64, 64, 255)); } else { DrawDebugCapsule(GetWorld(), TraceInfo.HitLocation, TraceInfo.CapsuleHalfHeight, TraceInfo.CapsuleRadius, FQuat::Identity, CurrentColor.Quantize()); } DrawDebugDirectionalArrow(GetWorld(), TraceInfo.HitNormalStart, TraceInfo.HitNormalEnd, 5.f, FColor(255,64,64), SDPG_World); } } }
void UHUDBlueprintLibrary::FindScreenLocationForWorldLocation(UObject* WorldContextObject, const FVector& InLocation, const float EdgePercent, FVector2D& OutScreenPosition, float& OutRotationAngleDegrees, bool &bIsOnScreen) { bIsOnScreen = false; OutRotationAngleDegrees = 0.f; FVector2D *ScreenPosition = new FVector2D(); UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject); if (!World->IsValidLowLevel()) return; if (GEngine->GameViewport == NULL) return; if (GEngine->GameViewport->Viewport == NULL) return; const FVector2D ViewportSize = FVector2D(GEngine->GameViewport->Viewport->GetSizeXY()); const FVector2D ViewportCenter = FVector2D(ViewportSize.X/2, ViewportSize.Y/2); APlayerController* PlayerController = (WorldContextObject ? UGameplayStatics::GetPlayerController(WorldContextObject, 0) : NULL); ACharacter *PlayerCharacter = static_cast<ACharacter *> (PlayerController->GetPawn()); if (!PlayerCharacter) return; FVector Forward = PlayerCharacter->GetActorForwardVector(); FVector Offset = (InLocation - PlayerCharacter->GetActorLocation()).GetSafeNormal(); float DotProduct = FVector::DotProduct(Forward, Offset); bool bLocationIsBehindCamera = (DotProduct < 0); if (bLocationIsBehindCamera) { // For behind the camera situation, we cheat a little to put the // marker at the bottom of the screen so that it moves smoothly // as you turn around. Could stand some refinement, but results // are decent enough for most purposes. FVector DiffVector = InLocation - PlayerCharacter->GetActorLocation(); FVector Inverted = DiffVector * -1.f; FVector NewInLocation = PlayerCharacter->GetActorLocation() * Inverted; NewInLocation.Z -= 5000; PlayerController->ProjectWorldLocationToScreen(NewInLocation, *ScreenPosition); ScreenPosition->Y = (EdgePercent * ViewportCenter.X) * 2.f; ScreenPosition->X = -ViewportCenter.X - ScreenPosition->X; } PlayerController->ProjectWorldLocationToScreen(InLocation, *ScreenPosition); // Check to see if it's on screen. If it is, ProjectWorldLocationToScreen is all we need, return it. if (ScreenPosition->X >= 0.f && ScreenPosition->X <= ViewportSize.X && ScreenPosition->Y >= 0.f && ScreenPosition->Y <= ViewportSize.Y) { OutScreenPosition = *ScreenPosition; bIsOnScreen = true; return; } *ScreenPosition -= ViewportCenter; float AngleRadians = FMath::Atan2(ScreenPosition->Y, ScreenPosition->X); AngleRadians -= FMath::DegreesToRadians(90.f); OutRotationAngleDegrees = FMath::RadiansToDegrees(AngleRadians) + 180.f; float Cos = cosf(AngleRadians); float Sin = -sinf(AngleRadians); ScreenPosition = new FVector2D(ViewportCenter.X + (Sin * 150.f), ViewportCenter.Y + Cos * 150.f); float m = Cos / Sin; FVector2D ScreenBounds = ViewportCenter * EdgePercent; if (Cos > 0) { ScreenPosition = new FVector2D(ScreenBounds.Y/m, ScreenBounds.Y); } else { ScreenPosition = new FVector2D(-ScreenBounds.Y/m, -ScreenBounds.Y); } if (ScreenPosition->X > ScreenBounds.X) { ScreenPosition = new FVector2D(ScreenBounds.X, ScreenBounds.X*m); } else if (ScreenPosition->X < -ScreenBounds.X) { ScreenPosition = new FVector2D(-ScreenBounds.X, -ScreenBounds.X*m); } *ScreenPosition += ViewportCenter; OutScreenPosition = *ScreenPosition; }
/** This will set the StreamingLevels TMap with the current Streaming Level Status and also set which level the player is in **/ void GetLevelStreamingStatus( UWorld* World, TMap<FName,int32>& StreamingLevels, FString& LevelPlayerIsInName ) { FWorldContext &Context = GEngine->WorldContextFromWorld(World); // Iterate over the world info's level streaming objects to find and see whether levels are loaded, visible or neither. for( int32 LevelIndex=0; LevelIndex<World->StreamingLevels.Num(); LevelIndex++ ) { ULevelStreaming* LevelStreaming = World->StreamingLevels[LevelIndex]; if( LevelStreaming && LevelStreaming->PackageName != NAME_None && LevelStreaming->PackageName != World->GetOutermost()->GetFName() ) { ULevel* Level = LevelStreaming->GetLoadedLevel(); if( Level != NULL ) { if( World->ContainsLevel( Level ) == true ) { if( World->CurrentLevelPendingVisibility == Level ) { StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_MakingVisible ); } else { StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_Visible ); } } else { StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_Loaded ); } } else { // See whether the level's world object is still around. UPackage* LevelPackage = Cast<UPackage>(StaticFindObjectFast( UPackage::StaticClass(), NULL, LevelStreaming->PackageName )); UWorld* LevelWorld = NULL; if( LevelPackage ) { LevelWorld = UWorld::FindWorldInPackage(LevelPackage); } if( LevelWorld ) { StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_UnloadedButStillAround ); } else if( GetAsyncLoadPercentage( *LevelStreaming->PackageName.ToString() ) >= 0 ) { StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_Loading ); } else { StreamingLevels.Add( LevelStreaming->PackageName, LEVEL_Unloaded ); } } } } // toss in the levels being loaded by PrepareMapChange for( int32 LevelIndex=0; LevelIndex < Context.LevelsToLoadForPendingMapChange.Num(); LevelIndex++ ) { const FName LevelName = Context.LevelsToLoadForPendingMapChange[LevelIndex]; StreamingLevels.Add(LevelName, LEVEL_Preloading); } ULevel* LevelPlayerIsIn = NULL; for( FConstPlayerControllerIterator Iterator = World->GetPlayerControllerIterator(); Iterator; ++Iterator ) { APlayerController* PlayerController = *Iterator; if( PlayerController->GetPawn() != NULL ) { // need to do a trace down here //TraceActor = Trace( out_HitLocation, out_HitNormal, TraceDest, TraceStart, false, TraceExtent, HitInfo, true ); FHitResult Hit(1.f); // this will not work for flying around :-( static FName NAME_FindLevel = FName(TEXT("FindLevel"), true); PlayerController->GetWorld()->LineTraceSingle(Hit,PlayerController->GetPawn()->GetActorLocation(), (PlayerController->GetPawn()->GetActorLocation()-FVector(0.f, 0.f, 256.f)), FCollisionQueryParams(NAME_FindLevel, true, PlayerController->GetPawn()), FCollisionObjectQueryParams(ECC_WorldStatic)); /** @todo UE4 FIXME if( Hit.Level != NULL ) { LevelPlayerIsIn = Hit.Level; } else */ if( Hit.GetActor() != NULL ) { LevelPlayerIsIn = Hit.GetActor()->GetLevel(); } else if( Hit.Component != NULL && Hit.Component->GetOwner() != NULL ) { AActor* Owner = Hit.Component->GetOwner(); if (Owner) { LevelPlayerIsIn = Owner->GetLevel(); } else { // This happens for BSP where the ModelComponent's outer is the level LevelPlayerIsIn = Hit.Component->GetTypedOuter<ULevel>(); } } } } // this no longer seems to be getting the correct level name :-( LevelPlayerIsInName = LevelPlayerIsIn != NULL ? LevelPlayerIsIn->GetOutermost()->GetName() : TEXT("None"); }
/** * Exec handler, parsing the passed in command * * @param InWorld World Context * @param Cmd Command to parse * @param Ar output device used for logging */ bool FDebugToolExec::Exec( UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar ) { // these commands are only allowed in standalone games #if UE_BUILD_SHIPPING || UE_BUILD_TEST if (GEngine->GetNetMode(InWorld) != NM_Standalone || (GEngine->GetWorldContextFromWorldChecked(InWorld).PendingNetGame != NULL)) { return 0; } // Edits the class defaults. else #endif if( FParse::Command(&Cmd,TEXT("EDITDEFAULT")) ) { // not allowed in the editor as this command can have far reaching effects such as impacting serialization if (!GIsEditor) { UClass* Class = NULL; if( ParseObject<UClass>( Cmd, TEXT("CLASS="), Class, ANY_PACKAGE ) == false ) { TCHAR ClassName[256]; if ( FParse::Token(Cmd,ClassName,ARRAY_COUNT(ClassName), 1) ) { Class = FindObject<UClass>( ANY_PACKAGE, ClassName); } } if (Class) { EditObject(Class->GetDefaultObject(), true); } else { Ar.Logf( TEXT("Missing class") ); } } return 1; } else if (FParse::Command(&Cmd,TEXT("EDITOBJECT"))) { UClass* searchClass = NULL; UObject* foundObj = NULL; // Search by class. if (ParseObject<UClass>(Cmd, TEXT("CLASS="), searchClass, ANY_PACKAGE)) { // pick the first valid object for (FObjectIterator It(searchClass); It && foundObj == NULL; ++It) { if (!It->IsPendingKill() && !It->IsTemplate()) { foundObj = *It; } } } // Search by name. else { FName searchName; FString SearchPathName; if ( FParse::Value(Cmd, TEXT("NAME="), searchName) ) { // Look for actor by name. for( TObjectIterator<UObject> It; It && foundObj == NULL; ++It ) { if (It->GetFName() == searchName) { foundObj = *It; } } } else if ( FParse::Token(Cmd,SearchPathName, true) ) { foundObj = FindObject<UObject>(ANY_PACKAGE,*SearchPathName); } } // Bring up an property editing window for the found object. if (foundObj != NULL) { // not allowed in the editor unless it is a PIE object as this command can have far reaching effects such as impacting serialization if (!GIsEditor || ((!foundObj->IsTemplate() && (foundObj->GetOutermost()->PackageFlags & PKG_PlayInEditor)))) { EditObject(foundObj, true); } } else { Ar.Logf(TEXT("Target not found")); } return 1; } else if (FParse::Command(&Cmd,TEXT("EDITARCHETYPE"))) { UObject* foundObj = NULL; // require fully qualified path name FString SearchPathName; if (FParse::Token(Cmd, SearchPathName, true)) { foundObj = FindObject<UObject>(ANY_PACKAGE,*SearchPathName); } // Bring up an property editing window for the found object. if (foundObj != NULL) { // not allowed in the editor unless it is a PIE object as this command can have far reaching effects such as impacting serialization if (!GIsEditor || ((!foundObj->IsTemplate() && (foundObj->GetOutermost()->PackageFlags & PKG_PlayInEditor)))) { EditObject(foundObj, false); } } else { Ar.Logf(TEXT("Target not found")); } return 1; } // Edits an objects properties or copies them to the clipboard. else if( FParse::Command(&Cmd,TEXT("EDITACTOR")) ) { UClass* Class = NULL; AActor* Found = NULL; if (FParse::Command(&Cmd, TEXT("TRACE"))) { APlayerController* PlayerController = InWorld->GetFirstPlayerController(); if (PlayerController != NULL) { // Do a trace in the player's facing direction and edit anything that's hit. FVector PlayerLocation; FRotator PlayerRotation; PlayerController->GetPlayerViewPoint(PlayerLocation, PlayerRotation); FHitResult Hit(1.0f); PlayerController->GetWorld()->LineTraceSingle(Hit, PlayerLocation, PlayerLocation + PlayerRotation.Vector() * 10000.f, ECC_Pawn, FCollisionQueryParams(NAME_None, true, PlayerController->GetPawn())); Found = Hit.GetActor(); } } // Search by class. else if( ParseObject<UClass>( Cmd, TEXT("CLASS="), Class, ANY_PACKAGE ) && Class->IsChildOf(AActor::StaticClass()) ) { UGameEngine* GameEngine = Cast<UGameEngine>(GEngine); // Look for the closest actor of this class to the player. FVector PlayerLocation(0.0f); APlayerController* PlayerController = InWorld->GetFirstPlayerController(); if (PlayerController != NULL) { FRotator DummyRotation; PlayerController->GetPlayerViewPoint(PlayerLocation, DummyRotation); } float MinDist = FLT_MAX; for( TActorIterator<AActor> It(InWorld, Class); It; ++It ) { if ( !It->IsPendingKill() ) { float const Dist = (PlayerController && It->GetRootComponent()) ? FVector::Dist(It->GetActorLocation(), PlayerLocation) : 0.f; if (Dist < MinDist) { MinDist = Dist; Found = *It; } } } } // Search by name. else { FName ActorName; if( FParse::Value( Cmd, TEXT("NAME="), ActorName ) ) { // Look for actor by name. for( FActorIterator It(InWorld); It; ++It ) { if( It->GetFName() == ActorName ) { Found = *It; break; } } } } // Bring up an property editing window for the found object. if( Found ) { // not allowed in the editor unless it is a PIE object as this command can have far reaching effects such as impacting serialization if (!GIsEditor || ((!Found->IsTemplate() && (Found->GetOutermost()->PackageFlags & PKG_PlayInEditor)))) { EditObject(Found, true); } } else { Ar.Logf( TEXT("Target not found") ); } return 1; } else { return 0; } }
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) }