//TODO: This is still an awful way to do this and we should scrap this task or do it right. void UAbilityTask_MoveToLocation::TickTask(float DeltaTime) { if (bIsFinished) { return; } Super::TickTask(DeltaTime); AActor* MyActor = GetAvatarActor(); if (MyActor) { ACharacter* MyCharacter = Cast<ACharacter>(MyActor); if (MyCharacter) { UCharacterMovementComponent* CharMoveComp = Cast<UCharacterMovementComponent>(MyCharacter->GetMovementComponent()); if (CharMoveComp) { CharMoveComp->SetMovementMode(MOVE_Custom, 0); } } float CurrentTime = GetWorld()->GetTimeSeconds(); if (CurrentTime >= TimeMoveWillEnd) { bIsFinished = true; // Teleport in attempt to find a valid collision spot MyActor->TeleportTo(TargetLocation, MyActor->GetActorRotation()); if (!bIsSimulating) { MyActor->ForceNetUpdate(); OnTargetLocationReached.Broadcast(); EndTask(); } } else { float MoveFraction = (CurrentTime - TimeMoveStarted) / DurationOfMovement; if (LerpCurve) { MoveFraction = LerpCurve->GetFloatValue(MoveFraction); } MyActor->SetActorLocation(FMath::Lerp<FVector, float>(StartLocation, TargetLocation, MoveFraction)); } } else { bIsFinished = true; EndTask(); } }
void UMyAnimInstance::NativeUpdateAnimation(float DeltaSeconds) { Super::NativeUpdateAnimation(DeltaSeconds); ACharacter* OwningPawn = Cast<ACharacter>(TryGetPawnOwner()); //const auto MovementComp = OwningPawn->GetMovementComponent(); if (OwningPawn) { Speed = OwningPawn->GetVelocity().Size(); Jump = OwningPawn->GetVelocity().Z; isFlying = OwningPawn->CharacterMovement->IsFalling(); } }
void ABatteryCollectorGameMode::HandleCurrentState(EBatteryPlayState NewState) { switch (NewState) { case EBatteryPlayState::EPlaying: { // spawn volumes active for (ASpawnVolume* Volume : SpawnVolumeActors) { Volume->SetSpawningActive(true); } } break; case EBatteryPlayState::Ewon: { // spawn volumes inactive for (ASpawnVolume* Volume : SpawnVolumeActors) { Volume->SetSpawningActive(false); } } break; case EBatteryPlayState::EGameOver: { // spawn volumes inactive for (ASpawnVolume* Volume : SpawnVolumeActors) { Volume->SetSpawningActive(false); } // block player input APlayerController* PlayerController = UGameplayStatics::GetPlayerController(this, 0); if (PlayerController) { PlayerController->SetCinematicMode(true, false, false, true, true); } // ragdoll the character ACharacter* MyCharacter = UGameplayStatics::GetPlayerCharacter(this, 0); if (MyCharacter) { MyCharacter->GetMesh()->SetSimulatePhysics(true); MyCharacter->GetMovementComponent()->MovementState.bCanJump = false; } } break; default: case EBatteryPlayState::EUnknown: { // Do nothing } break; } }
/** * Canceling an non instanced ability is tricky. Right now this works for Jump since there is nothing that can go wrong by calling * StopJumping() if you aren't already jumping. If we had a montage playing non instanced ability, it would need to make sure the * Montage that *it* played was still playing, and if so, to cancel it. If this is something we need to support, we may need some * light weight data structure to represent 'non intanced abilities in action' with a way to cancel/end them. */ void UGameplayAbility_CharacterJump::CancelAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateCancelAbility) { if (ScopeLockCount > 0) { WaitingToExecute.Add(FPostLockDelegate::CreateUObject(this, &UGameplayAbility_CharacterJump::CancelAbility, Handle, ActorInfo, ActivationInfo, bReplicateCancelAbility)); return; } Super::CancelAbility(Handle, ActorInfo, ActivationInfo, bReplicateCancelAbility); ACharacter * Character = CastChecked<ACharacter>(ActorInfo->AvatarActor.Get()); Character->StopJumping(); }
void UGameplayAbility_CharacterJump::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo) { if (ActivationInfo.ActivationMode == EGameplayAbilityActivationMode::Authority || ActivationInfo.ActivationMode == EGameplayAbilityActivationMode::Predicting) { if (!CommitAbility(Handle, ActorInfo, ActivationInfo)) { return; } ACharacter * Character = CastChecked<ACharacter>(ActorInfo->AvatarActor.Get()); Character->Jump(); } }
void UGameplayAbility_CharacterJump::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) { if (HasAuthorityOrPredictionKey(ActorInfo, &ActivationInfo)) { if (!CommitAbility(Handle, ActorInfo, ActivationInfo)) { return; } ACharacter * Character = CastChecked<ACharacter>(ActorInfo->AvatarActor.Get()); Character->Jump(); } }
bool USkeletalMeshComponent::ShouldTickPose() const { // Characters playing Root Motion will tick pose themselves before physics. ACharacter * CharacterOwner = Cast<ACharacter>(GetOwner()); const bool bSkipBecauseOfRootMotion = CharacterOwner && CharacterOwner->IsPlayingRootMotion(); // When we stop root motion we go back to ticking after CharacterMovement. Unfortunately that means that we could tick twice that frame. // So only enforce a single tick per frame. const bool bAlreadyTickedThisFrame = (LastTickTime == GetWorld()->TimeSeconds); // Remote Clients on the Server will always tick animations as updates from the client comes in. To use Client's delta time. const bool bRemoteClientOnServer = CharacterOwner && (CharacterOwner->Role == ROLE_Authority) && CharacterOwner->Controller && !CharacterOwner->Controller->IsLocalController(); return (Super::ShouldTickPose() && IsRegistered() && AnimScriptInstance && !bPauseAnims && GetWorld()->HasBegunPlay() && !bNoSkeletonUpdate && !bSkipBecauseOfRootMotion && !bRemoteClientOnServer && !bAlreadyTickedThisFrame); }
void UCheatManager::Walk() { APawn* Pawn = GetOuterAPlayerController()->GetPawn(); if (Pawn != NULL) { ACharacter* Character = Cast<ACharacter>(Pawn); if (Character) { Character->ClientCheatWalk(); if (!Character->IsLocallyControlled()) { Character->ClientCheatWalk_Implementation(); } } } }
void UAbilityTask_ApplyRootMotionMoveToActorForce::OnDestroy(bool AbilityIsEnding) { if (MovementComponent) { MovementComponent->RemoveRootMotionSourceByID(RootMotionSourceID); if (bSetNewMovementMode) { MovementComponent->SetMovementMode(NewMovementMode); } if (VelocityOnFinishMode == ERootMotionFinishVelocityMode::SetVelocity) { FVector EndVelocity; ACharacter* Character = MovementComponent->GetCharacterOwner(); if (Character) { EndVelocity = Character->GetActorRotation().RotateVector(SetVelocityOnFinish); } else { EndVelocity = SetVelocityOnFinish; } // When we mean to SetVelocity when finishing a MoveTo, we apply a short-duration low-priority // root motion velocity override. This ensures that the velocity we set is replicated properly // and takes effect. { const FName OnFinishForceName = FName("AbilityTaskApplyRootMotionMoveToActorForce_EndForce"); FRootMotionSource_ConstantForce* ConstantForce = new FRootMotionSource_ConstantForce(); ConstantForce->InstanceName = OnFinishForceName; ConstantForce->AccumulateMode = ERootMotionAccumulateMode::Override; ConstantForce->Priority = 1; // Low priority so any other override root motion sources stomp it ConstantForce->Force = EndVelocity; ConstantForce->Duration = 0.001f; MovementComponent->ApplyRootMotionSource(ConstantForce); if (Ability) { Ability->SetMovementSyncPoint(OnFinishForceName); } } } } Super::OnDestroy(AbilityIsEnding); }
void AShooterPlayerController::OnDeathMessage(class AShooterPlayerState* KillerPlayerState, class AShooterPlayerState* KilledPlayerState, const UDamageType* KillerDamageType) { AShooterHUD* ShooterHUD = GetShooterHUD(); if (ShooterHUD) { ShooterHUD->ShowDeathMessage(KillerPlayerState, KilledPlayerState, KillerDamageType); } ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player); if (LocalPlayer && LocalPlayer->GetUniqueNetId().IsValid() && KilledPlayerState->UniqueId.IsValid()) { // if this controller is the player who died, update the hero stat. if (*LocalPlayer->GetUniqueNetId() == *KilledPlayerState->UniqueId) { const auto Events = Online::GetEventsInterface(); const auto Identity = Online::GetIdentityInterface(); if (Events.IsValid() && Identity.IsValid()) { int32 UserIndex = LocalPlayer->ControllerId; TSharedPtr<FUniqueNetId> UniqueID = Identity->GetUniquePlayerId(UserIndex); if (UniqueID.IsValid()) { ACharacter* Pawn = GetCharacter(); check(Pawn); FVector Location = Pawn->GetActorLocation(); FOnlineEventParms Params; Params.Add( TEXT( "SectionId" ), FVariantData( (int32)1 ) ); Params.Add( TEXT( "GameplayModeId" ), FVariantData( (int32)1 ) ); Params.Add( TEXT( "DifficultyLevelId" ), FVariantData( (int32)0 ) ); Params.Add( TEXT( "PlayerRoleId" ), FVariantData( (int32)0 ) ); Params.Add( TEXT( "PlayerWeaponId" ), FVariantData( (int32)0 ) ); Params.Add( TEXT( "EnemyRoleId" ), FVariantData( (int32)0 ) ); Params.Add( TEXT( "EnemyWeaponId" ), FVariantData( (int32)0 ) ); Params.Add( TEXT( "LocationX" ), FVariantData( Location.X ) ); Params.Add( TEXT( "LocationY" ), FVariantData( Location.Y ) ); Params.Add( TEXT( "LocationZ" ), FVariantData( Location.Z ) ); Events->TriggerEvent(*UniqueID, TEXT("PlayerDeath"), Params); } } } } }
void ABatteryCollectorGameMode::HandleNewState(EBatteryPlayState NewState) { switch (NewState) { case EBatteryPlayState::EPlaying: { for (ASpawnVolume* Volume : SpawnVolumeActors) { Volume->SetSpawningActive(true); } } break; case EBatteryPlayState::EGameOver: { for (ASpawnVolume* Volume : SpawnVolumeActors) { Volume->SetSpawningActive(false); } APlayerController* PlayerController = UGameplayStatics::GetPlayerController(this, 0); if (PlayerController) { PlayerController->SetCinematicMode(true, false, false, true, true); } ACharacter* MyCharacter = UGameplayStatics::GetPlayerCharacter(this, 0); if (MyCharacter) { MyCharacter->GetMesh()->SetSimulatePhysics(true); MyCharacter->GetMovementComponent()->MovementState.bCanJump = false; } } break; case EBatteryPlayState::EWon: { for (ASpawnVolume* Volume : SpawnVolumeActors) { Volume->SetSpawningActive(false); } } break; case EBatteryPlayState::EUnknown: break; default: break; } }
void UAbilityTask_MoveToLocation::OnDestroy(bool AbilityIsEnding) { AActor* MyActor = GetAvatarActor(); if (MyActor) { ACharacter* MyCharacter = Cast<ACharacter>(MyActor); if (MyCharacter) { UCharacterMovementComponent* CharMoveComp = Cast<UCharacterMovementComponent>(MyCharacter->GetMovementComponent()); if (CharMoveComp && CharMoveComp->MovementMode == MOVE_Custom) { CharMoveComp->SetMovementMode(MOVE_Falling); } } } Super::OnDestroy(AbilityIsEnding); }
void UCheatManager::Ghost() { APawn* Pawn = GetOuterAPlayerController()->GetPawn(); if (Pawn != NULL) { GetOuterAPlayerController()->ClientMessage(TEXT("You feel ethereal")); ACharacter* Character = Cast<ACharacter>(Pawn); if (Character) { Character->ClientCheatGhost(); if (!Character->IsLocallyControlled()) { Character->ClientCheatGhost_Implementation(); } } } }
void UCheatManager::ChangeSize( float F ) { APawn* Pawn = GetOuterAPlayerController()->GetPawn(); // Note: only works on characters ACharacter *Character = Cast<ACharacter>(Pawn); if (Character) { ACharacter* DefaultCharacter = Character->GetClass()->GetDefaultObject<ACharacter>(); Character->GetCapsuleComponent()->SetCapsuleSize(DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleRadius() * F, DefaultCharacter->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight() * F); if (Character->GetMesh()) { Character->GetMesh()->SetRelativeScale3D(FVector(F)); } Character->TeleportTo(Character->GetActorLocation(), Character->GetActorRotation()); } }
void AShooterPlayerController::OnKill() { UpdateAchievementProgress(ACH_FRAG_SOMEONE, 100.0f); const auto Events = Online::GetEventsInterface(); const auto Identity = Online::GetIdentityInterface(); if (Events.IsValid() && Identity.IsValid()) { ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player); if (LocalPlayer) { int32 UserIndex = LocalPlayer->ControllerId; TSharedPtr<FUniqueNetId> UniqueID = Identity->GetUniquePlayerId(UserIndex); if (UniqueID.IsValid()) { ACharacter* Pawn = GetCharacter(); // If player is dead, use location stored during pawn cleanup. FVector Location = LastDeathLocation; if (Pawn) { Pawn->GetActorLocation(); } FOnlineEventParms Params; Params.Add( TEXT( "SectionId" ), FVariantData( (int32)1 ) ); Params.Add( TEXT( "GameplayModeId" ), FVariantData( (int32)1 ) ); Params.Add( TEXT( "DifficultyLevelId" ), FVariantData( (int32)0 ) ); Params.Add( TEXT( "PlayerRoleId" ), FVariantData( (int32)0 ) ); Params.Add( TEXT( "PlayerWeaponId" ), FVariantData( (int32)0 ) ); Params.Add( TEXT( "EnemyRoleId" ), FVariantData( (int32)0 ) ); Params.Add( TEXT( "KillTypeId" ), FVariantData( (int32)0 ) ); Params.Add( TEXT( "LocationX" ), FVariantData( Location.X ) ); Params.Add( TEXT( "LocationY" ), FVariantData( Location.Y ) ); Params.Add( TEXT( "LocationZ" ), FVariantData( Location.Z ) ); Params.Add( TEXT( "EnemyWeaponId" ), FVariantData( (int32)0 ) ); Events->TriggerEvent(*UniqueID, TEXT("KillOponent"), Params); } } } }
AActor * AHunterProjectile::FindHitActor() { const FVector &thisLocation = GetActorLocation(); UFlockingDataCache *cache = UFlockingDataCache::GetCacheChecked(this); ACharacter *playerCharacter = nullptr; for (FConstControllerIterator It = GetWorld()->GetControllerIterator(); It; ++It) { AController *controller = *It; APawn *otherPawn = controller->GetPawn(); if (otherPawn == nullptr) { continue; } if (controller->IsA(APlayerController::StaticClass())) { playerCharacter = Cast<ACharacter>(controller->GetPawn()); } } const TArray<FVector> &calfLocations = cache->GetTeamData(TEAM_CALVES)->m_locations; const TArray<FVector> &playerLocations = cache->GetLocationsPlayer(); int32 targetCalf = FindHitActor(calfLocations, cache->GetTeamData(TEAM_CALVES)->m_agentRadius * 0.5f); AActor *targetActor = nullptr; if (targetCalf == INDEX_NONE) { int32 targetPlayer = FindHitActor(playerLocations, 0.5f * playerCharacter->GetCapsuleComponent()->GetScaledCapsuleRadius()); if (targetPlayer != INDEX_NONE) { targetActor = playerCharacter; } } else { targetActor = cache->GetOrCreateTeamData(TEAM_CALVES).m_agents[targetCalf]; } return targetActor; }
bool FMovieScene3DTransformSectionRecorderFactory::CanRecordObject(UObject* InObjectToRecord) const { if(USceneComponent* SceneComponent = Cast<USceneComponent>(InObjectToRecord)) { // Dont record the root component transforms as this will be taken into account by the actor transform track // Also dont record transforms of skeletal mesh components as they will be taken into account in the actor transform bool bIsCharacterSkelMesh = false; if (SceneComponent->IsA<USkeletalMeshComponent>() && SceneComponent->GetOwner()->IsA<ACharacter>()) { ACharacter* Character = CastChecked<ACharacter>(SceneComponent->GetOwner()); bIsCharacterSkelMesh = SceneComponent == Character->GetMesh(); } return (SceneComponent != SceneComponent->GetOwner()->GetRootComponent() && !bIsCharacterSkelMesh); } else { return InObjectToRecord->IsA<AActor>(); } }
void ANinjaGameModeBase::BeginRound() { UWorld* World = GetWorld(); if (World) { ClearPlayerStartTags(); for (APlayerState* CurrState : GameState->PlayerArray) { ANinjaPlayerState* State = (ANinjaPlayerState*)CurrState; if (State) { APlayerController* Cont = (APlayerController*) State->GetOwner(); GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::Blue, FString::Printf(TEXT("%s"), *Cont->GetName())); if (State->GetChosenCharacter()) { GEngine->AddOnScreenDebugMessage(-1, 1.5, FColor::Red, FString::Printf(TEXT("%s - %s"), *Cont->GetName(), *State->GetChosenCharacter()->GetName())); } if (Cont) { ACharacter* Character = Cont->GetCharacter(); APlayerStart* PS = (APlayerStart*)ChoosePlayerStart(Cont); if (PS) { PS->PlayerStartTag = FName(TEXT("Taken")); if (Character) { Character->Destroy(); } FActorSpawnParameters Params; Params.Owner = Cont; ANinjaCharacter* SpawnedChar = World->SpawnActor<ANinjaCharacter>(State->GetChosenCharacter(), PS->GetActorLocation(), PS->GetActorRotation(), Params); if (SpawnedChar) { Cont->Possess(SpawnedChar); } } } } } } }
bool ALabyrinthGameMode::IsSpawnpointPreferred(APlayerStart* SpawnPoint, AController* Player) const { ACharacter* MyPawn = Cast<ACharacter>((*DefaultPawnClass)->GetDefaultObject<ACharacter>()); // TO-DO: Add AI Controller //ALAIController* AIController = Cast<ALAIController>(Player); /*if (AIController != nullptr) { MyPawn = Cast<ACharacter>(BotPawnClass->GetDefaultObject<ACharacter>()); }*/ if (MyPawn) { const FVector SpawnLocation = SpawnPoint->GetActorLocation(); for (FConstPawnIterator It = GetWorld()->GetPawnIterator(); It; It++) { ACharacter* OtherPawn = Cast<ACharacter>(*It); if (OtherPawn && OtherPawn != MyPawn) { const float CombinedHeight = (MyPawn->GetCapsuleComponent()->GetScaledCapsuleHalfHeight() + OtherPawn->GetCapsuleComponent()->GetScaledCapsuleHalfHeight()) * 2.0f; const float CombinedRadius = (MyPawn->GetCapsuleComponent()->GetScaledCapsuleRadius() + OtherPawn->GetCapsuleComponent()->GetScaledCapsuleRadius()); const FVector OtherLocation = OtherPawn->GetActorLocation(); // Check if the player start overlaps this pawn if (FMath::Abs(SpawnLocation.Z - OtherLocation.Z) < CombinedHeight && (SpawnLocation - OtherLocation).Size2D() < CombinedRadius) { return false; } } } } else { return false; } return true; }
void ABatteryPickup::UpdateBeamTargetPoint() { ACharacter* Character = GetWorld()->GetFirstPlayerController()->GetCharacter(); FVector SocketLocation = Character->GetMesh()->GetSocketLocation("spine_02"); ParticleSystem->SetBeamTargetPoint(0, SocketLocation, 0); }
void ABatteryCollectorGameMode::HandleNewState(EBatteryPlayState NewState) { switch (NewState) { case EBatteryPlayState::EPlaying : // If the game is playing // // spawn volume active for (ASpawnVolume* Volume : SpawnVolumeActors) { Volume->SetSpawningActive(true); } break; case EBatteryPlayState::EWon : // if we won the game // // spawn volume inactive for (ASpawnVolume* Volume : SpawnVolumeActors) { Volume->SetSpawningActive(false); } break; case EBatteryPlayState::EGameOver : { // If we lost // // spawn volume inactive // block player input // ragdoll the character for (ASpawnVolume* Volume : SpawnVolumeActors) { Volume->SetSpawningActive(false); } APlayerController* PlayerController = UGameplayStatics::GetPlayerController(this, 0); if(PlayerController) { PlayerController->SetCinematicMode(true, false, false, true, true); UE_LOG(LogClass, Log, TEXT("You have set Cinematic Mode")); } else { UE_LOG(LogClass, Log, TEXT("Player Controller was invalid!!")); } // now ragdoll the character ACharacter* MyCharacter = UGameplayStatics::GetPlayerCharacter(this, 0); if(MyCharacter) { MyCharacter->GetMesh()->SetSimulatePhysics(true); MyCharacter->GetMovementComponent()->MovementState.bCanJump=false; UE_LOG(LogClass, Log, TEXT("ACharacter jump turned off and Set Simulate Physics on")); }else { UE_LOG(LogClass, Log, TEXT("ACharacter was invalid!! (EGameOver State in HandleNewState")); } } break; default : // unknown state - incase some code forgets to call // // use to help debug break; } }
void FGameplayDebuggerCategory_AI::CollectData(APlayerController* OwnerPC, AActor* DebugActor) { APawn* MyPawn = Cast<APawn>(DebugActor); ACharacter* MyChar = Cast<ACharacter>(MyPawn); DataPack.PawnName = MyPawn ? MyPawn->GetHumanReadableName() : FString(TEXT("{red}No selected pawn.")); DataPack.bIsUsingCharacter = (MyChar != nullptr); AAIController* MyController = MyPawn ? Cast<AAIController>(MyPawn->Controller) : nullptr; DataPack.bHasController = (MyController != nullptr); if (MyController) { if (MyController->IsPendingKill() == false) { DataPack.ControllerName = MyController->GetName(); } else { DataPack.ControllerName = TEXT("Controller PENDING KILL"); } } else { DataPack.ControllerName = TEXT("No Controller"); } if (MyPawn && !MyPawn->IsPendingKill()) { UCharacterMovementComponent* CharMovementComp = MyChar ? MyChar->GetCharacterMovement() : nullptr; if (CharMovementComp) { UPrimitiveComponent* FloorComponent = MyPawn->GetMovementBase(); AActor* FloorActor = FloorComponent ? FloorComponent->GetOwner() : nullptr; DataPack.MovementBaseInfo = FloorComponent ? FString::Printf(TEXT("%s.%s"), *GetNameSafe(FloorActor), *FloorComponent->GetName()) : FString(TEXT("None")); DataPack.MovementModeInfo = CharMovementComp->GetMovementName(); } UBehaviorTreeComponent* BehaviorComp = MyController ? Cast<UBehaviorTreeComponent>(MyController->BrainComponent) : nullptr; DataPack.bIsUsingBehaviorTree = (BehaviorComp != nullptr); if (BehaviorComp) { DataPack.CurrentAITask = BehaviorComp->DescribeActiveTasks(); DataPack.CurrentAIState = BehaviorComp->IsRunning() ? TEXT("Running") : BehaviorComp->IsPaused() ? TEXT("Paused") : TEXT("Inactive"); DataPack.CurrentAIAssets = BehaviorComp->DescribeActiveTrees(); } UGameplayTasksComponent* TasksComponent = MyController ? MyController->GetGameplayTasksComponent() : nullptr; DataPack.bIsUsingGameplayTasks = (TasksComponent != nullptr); if (TasksComponent) { for (FConstGameplayTaskIterator It = TasksComponent->GetTickingTaskIterator(); It; ++It) { const UGameplayTask* TaskOb = *It; if (TaskOb) { DataPack.TickingTaskInfo += DescribeTaskHelper(*TaskOb); DataPack.NumTickingTasks++; } } for (FConstGameplayTaskIterator It = TasksComponent->GetPriorityQueueIterator(); It; ++It) { const UGameplayTask* TaskOb = *It; if (TaskOb) { DataPack.TaskQueueInfo += DescribeTaskHelper(*TaskOb); DataPack.NumTasksInQueue++; } } } DataPack.MontageInfo = MyChar ? GetNameSafe(MyChar->GetCurrentMontage()) : FString(); UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(MyPawn->GetWorld()); const ANavigationData* NavData = MyController && NavSys ? NavSys->GetNavDataForProps(MyController->GetNavAgentPropertiesRef()) : nullptr; DataPack.NavDataInfo = NavData ? NavData->GetConfig().Name.ToString() : FString(); CollectPathData(MyController); } else { PathDataPack.PathCorridor.Reset(); PathDataPack.PathPoints.Reset(); } }
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; }
void ABaseController::SearchForTarget() { if (GetPawn() == NULL || StopSearching) { return; } bool canSeePlayer = false; FHitResult hit(ForceInit); FCollisionQueryParams traceParams = FCollisionQueryParams(FName(TEXT("RV_Trace")), true, Self); traceParams.bTraceComplex = true; traceParams.bTraceAsyncScene = true; FVector EnemyLocation = Self->GetActorLocation(); for (FConstPawnIterator i = World->GetPawnIterator(); i; ++i) { ACharacter* poesibleTarget = Cast<ACharacter>(*i); if (poesibleTarget != Cast<ACharacter>(Self) && poesibleTarget != NULL) { FVector possibleTargetLocation = poesibleTarget->GetActorLocation(); bool bHit = World->LineTraceSingleByChannel(hit, Self->EyeLocation, possibleTargetLocation, ECC_Visibility, traceParams); bool bPersistent = true; float LifeTime = 5.f; // @fixme, draw line with thickneES = 2.f? if (bHit && hit.bBlockingHit) { // Red up to the blocking hit, green thereafter //DrawDebugLine(World, Self->EyeLocation, hit.ImpactPoint, FColor::Red, bPersistent, LifeTime); //DrawDebugLine(World, hit.ImpactPoint, possibleTargetLocation, FColor::Green, bPersistent, LifeTime); //DrawDebugPoint(World, hit.ImpactPoint, 16.f, FColor::Red, bPersistent, LifeTime); } else { // no hit means all red //DrawDebugLine(World, Self->EyeLocation, possibleTargetLocation, FLinearColor::Red, bPersistent, LifeTime); } if (hit.GetActor() && hit.GetActor()->GetName() == poesibleTarget->GetName() && hit.bBlockingHit) { if (Self->EState != EnemyState::ES_Searching) TargetsLastKnownPosition = hit.GetActor()->GetActorLocation(); BBComp->SetValue<UBlackboardKeyType_Vector>(TargetsLastKnownPositionID, TargetsLastKnownPosition); float distanceFromPoESibleTarget = FVector::Dist(EnemyLocation, possibleTargetLocation); if (distanceFromPoESibleTarget <= Self->SightRange && distanceFromPoESibleTarget > Self->AttackRange && Self->AttackCompleted) { SetTarget(poesibleTarget, distanceFromPoESibleTarget); ResetFocusActor(); SetState(EnemyState::ES_Chasing, "Chasing"); BBComp->SetValue<UBlackboardKeyType_Bool>(MovedToLastKnownPositionID, false); } else if (distanceFromPoESibleTarget <= Self->AttackRange && Self->AttackCompleted) { Self->AttackStarted = true; Self->AttackCompleted = false; SetTarget(poesibleTarget, distanceFromPoESibleTarget); SetFocusActor(Cast<AActor>(Target)); AttackLocation = poesibleTarget->GetActorLocation(); SetState(EnemyState::ES_Attacking, "Attacking"); BBComp->SetValue<UBlackboardKeyType_Bool>(MovedToLastKnownPositionID, false); } else if (Self->AttackCompleted) { ResetFocusActor(); SetState(EnemyState::ES_Searching, "Searching"); SearchForTargetAtLastKnownPosition(); } } else if (hit.GetActor() && hit.GetActor()->GetName() != poesibleTarget->GetName() && hit.bBlockingHit) { if (Self->EState != EnemyState::ES_Searching) SearchForTargetAtLastKnownPosition(); Self->AttackStarted = false; Self->AttackCompleted = true; ResetFocusActor(); SetState(EnemyState::ES_Searching, "Searching"); } } } }