void ARoguelikeChar::GenerateLaserBeam() { FHitResult Hit; FCollisionQueryParams ColParams = FCollisionQueryParams(FName("Tsirla"), false, GetOwner()); ColParams.AddIgnoredActor(GetOwner()); ColParams.AddIgnoredActor(this); FVector Origin = LaserSource->GetComponentLocation(); FVector ForwardVector = PlayerCamera->GetForwardVector(); FVector Destination = Origin + (ForwardVector * 5000); if (GetWorld()->LineTraceSingleByChannel(Hit, Origin, Destination, ECollisionChannel::ECC_WorldDynamic, ColParams)) { LaserTargetLocation = Hit.Location; } else { LaserTargetLocation = Destination; } PlayerLaser->SetBeamSourcePoint(0, Origin, 0); PlayerLaser->SetBeamTargetPoint(0, LaserTargetLocation, 0); LaserTarget->SetWorldLocation(LaserTargetLocation - LaserTarget->GetForwardVector()); }
void ACVehicleSpawner::OnTimer() { FTimerHandle Handle; if (!Active || Paused) { GetWorld()->GetTimerManager().SetTimer(Handle, this, &ACVehicleSpawner::OnTimer, GetTimeWait(), false); return; } if (Bucket.Num() == 0) { GEngine->AddOnScreenDebugMessage(-1, 15.f, FColor::Red, TEXT("You need to add Vehicle Types to the Vehicle Spawner")); } FVector StartTrace = GetActorLocation() - GetActorForwardVector() * 400 + FVector(0, 0, 100); FVector EndTrace = GetActorLocation() + GetActorForwardVector() * 400 + FVector(0, 0, 100); if (GetWorld()->LineTraceTest( StartTrace, EndTrace, ECollisionChannel::ECC_Vehicle, FCollisionQueryParams(), FCollisionResponseParams() )) { GetWorld()->GetTimerManager().SetTimer(Handle, this, &ACVehicleSpawner::OnTimer, 0.1f, false); return; } FActorSpawnParameters spawnParameters; spawnParameters.bNoCollisionFail = true; spawnParameters.Owner = this; spawnParameters.Instigator = NULL; spawnParameters.bDeferConstruction = false; int32 BucketIndex = FMath::RandRange(0, Bucket.Num() - 1); EVehicleType VehicleType = Bucket[BucketIndex]; Bucket.RemoveAtSwap(BucketIndex); if (Bucket.Num() == 0) { TurnBucket(); } TSubclassOf<class AFlockingVehicle> Type = VehicleTypeClass[(uint8)VehicleType]; AFlockingVehicle* NewVehicle = GetWorld()->SpawnActor<AFlockingVehicle>(Type, GetActorLocation(), GetActorRotation(), spawnParameters); NewVehicle->SetFlockingState(FlockingState); NewVehicle->SpawnDefaultController(); NewVehicle->GetMesh()->SetAllPhysicsLinearVelocity(GetActorForwardVector() * StartSpeed / 0.036); if (NewVehicle->VehicleType != VehicleType) { GEngine->AddOnScreenDebugMessage(-1, 15.f, FColor::Red, TEXT("Vehicle Type is not correct.")); } GetWorld()->GetTimerManager().SetTimer(Handle, this, &ACVehicleSpawner::OnTimer, GetTimeWait(), false); if (VehicleTypeMaterials.Contains((uint8)VehicleType)) { auto Materials = VehicleTypeMaterials[(uint8)VehicleType]; int32 Index = FMath::RandRange(0, Materials.Num() - 1); UMaterial* Material = Materials[Index]; NewVehicle->GetMesh()->SetMaterial(2, Material); NewVehicle->ColorMaterialIndex = Index; } }
// Called every frame void ACart::Tick( float DeltaTime ) { Super::Tick( DeltaTime ); auto World = GetWorld(); for (int32 i = 0; i < 4; i++) { FHitResult HitResult(ForceInit); FCollisionQueryParams Params = FCollisionQueryParams(FName(TEXT("Trace")), true, this); Params.bTraceComplex = true; //Params.bTraceAsyncScene = true; Params.bReturnPhysicalMaterial = true; const FName TraceTag("MyTraceTag"); World->DebugDrawTraceTag = TraceTag; Params.TraceTag = TraceTag; bool Hit = World->LineTraceSingleByChannel(HitResult, Arrows[i]->GetComponentLocation(), Arrows[i]->GetComponentLocation() + Arrows[i]->GetForwardVector() * (SpringLength + WheelRadius), ECC_PhysicsBody, Params); if (Hit) { FVector Force = HitResult.ImpactNormal * SpringStrength * BodyMesh->GetMass() * (1 - HitResult.Distance / (SpringLength + WheelRadius)); BodyMesh->AddForceAtLocation(Force, Arrows[i]->GetComponentLocation()); Wheels[i]->SetWorldLocation(HitResult.Location - (Arrows[i]->GetForwardVector() * WheelRadius)); } else { Wheels[i]->SetWorldLocation(Arrows[i]->GetComponentLocation() + Arrows[i]->GetForwardVector() * SpringLength); } } }
AWeaponBase::AWeaponBase(){ WeaponMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("WeaponMesh")); WeaponMesh->AttachTo(RootComponent); TraceParams = FCollisionQueryParams(FName(TEXT("HitscanTrace")), true, this); //TraceParams.TraceTag = FName("HitscanTrace"); }
FVector ABaseController::GetNewWanderPosition() { FNavLocation Location; UNavigationSystem* NavSys = World->GetNavigationSystem(); FHitResult hit(ForceInit); FCollisionQueryParams traceParams = FCollisionQueryParams(FName(TEXT("RV_Trace")), true, Self); traceParams.bTraceComplex = true; traceParams.bTraceAsyncScene = true; int times = 0; float minimuimDist = Self->MinimuimDistanceBetweenWanderLocations; do{ if (times >= 50) { times = 0; minimuimDist -= 500.f; } times++; NavSys->GetRandomPointInNavigableRadius(Self->GetActorLocation(), Self->SightRange, Location); } while (FVector::Dist(Location.Location, Self->GetActorLocation()) < minimuimDist); bool bHit = World->LineTraceSingleByChannel(hit, Self->EyeLocation, Location.Location, ECC_Visibility, traceParams); return Location.Location; }
//ENTER void FVictoryEdAlignMode::Enter() { //FEdMode::Enter(); //~~~~~~~~ //Victory Title Appears VictoryTitleAppears(); ReEntering = true; //Clear Snap Key! SnapKeyPressed = false; //Clear keys MinusIsDown = false; PlusIsDown = false; ShiftDown = false; //Get an actor, not sure if this matters //TObjectIterator< AActor> ActorItr; //Trace RV_TraceParams = FCollisionQueryParams(FName(TEXT("HUDRMBDown")), true, NULL); //~~~~~~~~~~~~~~~~ }
//INIT void FVictoryEdAlignMode::JoyInit(UVictoryEdEngine* EnginePtr) { //ID = FName("VictoryEditorMode"); //Always Initialize Your Pointers! SelectedVertexBuffer = nullptr; HighlightedVertexBuffer = nullptr; //VictoryEngine VictoryEngine = EnginePtr; //Victory Buttons RefreshVictoryButtons(); //Enable Realtime ReEntering = true; //~~~ UsingMouseInstantMove = false; //~~~ //Get an actor, not sure if this matters //TObjectIterator< AActor> ActorItr; //Traces RV_TraceParams = FCollisionQueryParams(FName(TEXT("HUDRMBDown")), true, NULL); RV_TraceParams.bTraceComplex = true; //RV_TraceParams.bTraceAsyncScene = true; RV_TraceParams.bReturnPhysicalMaterial = false; }
void APawnWithCamera::DoTrace() { FVector Loc = CameraOne->GetActorLocation(); UE_LOG(LogClass, Error, TEXT("Loc is %s"), *Loc.ToString()); FRotator Rot = CameraOne->GetActorRotation(); UE_LOG(LogClass, Error, TEXT("Rot is %s"), *Rot.ToString()); FVector Start = Loc; UE_LOG(LogClass, Error, TEXT("Start is %s"), *Start.ToString()); FVector End = Loc + (Rot.Vector() * Distance); UE_LOG(LogClass, Error, TEXT("End is %s"), *End.ToString()); TempActor->SetActorLocation(End); FCollisionQueryParams TraceParam = FCollisionQueryParams(FName(TEXT("Trace")), true, this); TraceParam.bTraceComplex = true; TraceParam.bTraceAsyncScene = true; TraceParam.bReturnPhysicalMaterial = false; TraceParam.AddIgnoredActor(this); FHitResult Hit(ForceInit); GetWorld()->LineTraceSingle(Hit, Start, End, ECC_Pawn, TraceParam); DrawDebugLine(GetWorld(), Start, End, FColor(255, 0, 0), false, -1, 0, 12.33f); if (Hit.bBlockingHit) { UE_LOG(LogClass, Error, TEXT("Hit Something")); } else { UE_LOG(LogClass, Error, TEXT("No Hit")); } }
void USimpleCodeHoverComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { // This function is called every tick. It is equivalent to the "Event Tick" // event in the Blueprint version of this component. Super::TickComponent(DeltaTime, TickType, ThisTickFunction); // If we don't have a valid primitive component then nothing needs to be done. // This is equivalent to the gray 'Primitive Check' block in the Blueprint. if (PrimitiveComponent == nullptr) { return; } // Let's replicate the BP code that performs the line trace each tick. First, we // have to calculate the start and end position for the trace. The SceneComponent // super class has a field called 'ComponentToWorld' which is a transformation // matrix that contains the component's location and orientation. This is equivalent // to the 'GetWorldLocation' call in the Blueprint. The trace end point is simply // underneath the component's location. const FVector Start = ComponentToWorld.GetLocation(); const FVector End = FVector(Start.X, Start.Y, Start.Z - MaxHoverForceDistance); // Now we are ready to perform the actual trace. The result of a trace operation // will be returned in a so called HitResult that contains information about if // and where the trace hit anything. FHitResult HitResult; // There are many ways to do traces in the Engine, such as using a line or a volume, // whether the trace should stop as soon as it hits something or return all hits, // and you can also specify what types of objects should be considered for collisions. // The following line is equivalent to the LineTraceByChannel call in the Blueprint. if (World->LineTraceSingleByChannel(HitResult, Start, End, ECC_WorldDynamic, FCollisionQueryParams(TEXT("HoverComponentTrace")))) { // We can now calculate the hover force that should be applied to the parent // component. The following lines are equivalent to the yellow BP sub-graph. const float Distance = (Start - HitResult.ImpactPoint).Size(); const float Ratio = FMath::Clamp(Distance / MaxHoverForceDistance, 0.0f, 1.0f); const FVector Force = (1.0f - Ratio) * MaxHoverForce * HitResult.ImpactNormal; // Finally, we apply the calculated force to the component. PrimitiveComponent->AddForce(Force, NAME_None, false); // The BP node for the line trace has an option to draw a red debug line for the, // trace and a red point for the hit point. We can implement this in C++ using the // helper functions in DrawDebugHelpers.h ::DrawDebugLine(World, Start, HitResult.ImpactPoint, FColor::Red, false, 0.0f); ::DrawDebugPoint(World, HitResult.ImpactPoint, 16.0f, FColor::Red, false, 0.0f); } }
const FHitResult UGrabber::GetFirstPhysicsBodyInReach() { /// Raycast to reach distance FHitResult HitResult; GetWorld()->LineTraceSingleByObjectType( OUT HitResult, GetReachLineStart(), GetReachLineEnd(), FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody), FCollisionQueryParams(FName(TEXT("")), false, GetOwner()) ); return HitResult; }
void AdeezProjectile::OnHit(UPrimitiveComponent* ThisComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) { if ((OtherActor != NULL) && (OtherActor != this) && (OtherComp != NULL)) { // spawn FX AImpactFX* FX = GetWorld()->SpawnActorDeferred<AImpactFX>(ImpactTemplate, FTransform(Hit.Normal.Rotation(), Hit.Location), nullptr, Instigator, ESpawnActorCollisionHandlingMethod::AlwaysSpawn); if (FX) { FCollisionQueryParams Params = FCollisionQueryParams(FName(TEXT("RV_Trace")), true, this); Params.bTraceComplex = true; Params.bTraceAsyncScene = true; Params.bReturnPhysicalMaterial = true; FHitResult secondHit(ForceInit); FVector StartTrace; FVector EndTrace; StartTrace = GetActorLocation() - GetActorRotation().Vector() * 50; EndTrace = GetActorLocation() + GetActorRotation().Vector() * 200; GetWorld()->LineTraceSingleByChannel(secondHit, StartTrace, EndTrace, COLLISION_Weapon, Params); FPointDamageEvent PointDmg; //PointDmg.DamageTypeClass = DamageType; PointDmg.HitInfo = secondHit; PointDmg.ShotDirection = this->GetActorForwardVector(); PointDmg.Damage = Damage; if (this->GetOwner() && this->GetOwner()->GetInstigatorController()) { OtherActor->TakeDamage(Damage, PointDmg, this->GetOwner()->GetInstigatorController(), this->GetOwner()); } if (secondHit.bBlockingHit) { FX->SurfaceHit = secondHit; UGameplayStatics::FinishSpawningActor(FX, FTransform(FX->SurfaceHit.Normal.Rotation(), FX->SurfaceHit.Location)); } // simulate impact if (OtherComp->IsSimulatingPhysics()) { OtherComp->AddImpulseAtLocation(GetProjectileMovement()->Velocity * MassMultiplier, GetActorLocation()); } } } Destroy(); }
void AMMO_Character::MeleeAttackRaycasts() { FVector BaseSocketLoc = Player_SkeletalMeshComponent->GetSocketLocation(FName("Sword_joint")); FVector TipSocketLoc = Player_SkeletalMeshComponent->GetSocketLocation(FName("Sword_Edge")); const int sub = 32; float curLength = (BaseSocketLoc - TipSocketLoc).Size() * 2; float prevLength = (prevBase - prevTip).Size(); for (int i = 1; i < sub; i++) { FVector tmpBase = FMath::Lerp(BaseSocketLoc, prevBase, i / float(sub)); FVector tmpTip = FMath::Lerp(TipSocketLoc, prevTip, i / float(sub)); FVector tmpOff = (tmpTip - tmpBase); tmpOff.Normalize(); } prevBase = BaseSocketLoc; prevTip = TipSocketLoc; FHitResult Hit; FCollisionQueryParams ColParams = FCollisionQueryParams(FName("NoName"), false, GetOwner()); ColParams.AddIgnoredActor(GetOwner()); ColParams.AddIgnoredActor(this); if (GetWorld()->LineTraceSingleByChannel(Hit, BaseSocketLoc, TipSocketLoc, ECollisionChannel::ECC_WorldDynamic, ColParams)) { if (Hit.Actor != GetOwner() && AnimInstance->bCanDamageMelee) { if (Cast<AMMO_Mob_Character>(Hit.Actor.Get())) { if (!Cast<AMMO_Mob_Character>(Hit.Actor.Get())->bIsDead && !Cast<AMMO_Mob_Character>(Hit.Actor.Get())->bIsImmunized) { if (Role < ROLE_Authority) { AnimInstance->bCanDamageMelee = false; GetDamage(BaseAttack, AttackBonusMin, AttackBonusMax, Cast<AMMO_Mob_Character>(Hit.Actor.Get())); } } } else if (Cast<ABoss>(Hit.Actor.Get())) { if (!Cast<ABoss>(Hit.Actor.Get())->bIsDead) { if (Role < ROLE_Authority) { AnimInstance->bCanDamageMelee = false; GetDamage_Boss(BaseAttack, AttackBonusMin, AttackBonusMax, Cast<ABoss>(Hit.Actor.Get())); } } } } } }
bool ATankPlayerController::LineTrace(FVector Start, FVector Direction, TArray<FHitResult> &HitResults) const { FVector End = Start + Direction * RayCastDistance; FCollisionQueryParams RV_TraceParams = FCollisionQueryParams(FName(TEXT("RV_Trace")), true, this); RV_TraceParams.bTraceComplex = true; RV_TraceParams.bTraceAsyncScene = true; RV_TraceParams.bReturnPhysicalMaterial = true; RV_TraceParams.AddIgnoredActor(GetControlledTank()); //do the line trace return GetWorld()->LineTraceMultiByChannel( HitResults, //result Start, //start End, //end ECC_Visibility, //collision channel RV_TraceParams ); }
ABrainInteractiveObject* ABrainCharacter::CheckForInteractiveObjects() { FCollisionQueryParams traceParams = FCollisionQueryParams(FName(TEXT("Trace")), true, this); traceParams.bTraceComplex = true; traceParams.bTraceAsyncScene = true; traceParams.bReturnPhysicalMaterial = true; FHitResult hit(ForceInit); UWorld* world = GetWorld(); FVector startLocation = GetActorLocation() + FVector(0, 0, 64); // tweak pour prendre en compte la position de la camera. FVector endLocation = startLocation + (GetActorRotation().Vector() * _maxDistanceInteraction); world->SweepSingleByChannel(hit, startLocation, endLocation, FQuat::Identity, INTERACTIVE_OBJECT, FCollisionShape::MakeSphere(12.0f), traceParams); return Cast<ABrainInteractiveObject>(hit.GetActor()); }
//Line trace FHitResult AMyCharacter::LookForObject(float TraceRange, ECollisionChannel CollisionType) { FVector Location; FRotator Rotation; Controller->GetPlayerViewPoint(Location, Rotation); const FVector Start = Location; const FVector Direction = Rotation.Vector(); const FVector End = Start + (Direction * TraceRange); FCollisionQueryParams Params = FCollisionQueryParams(FName(TEXT("Trace")), true, this); FHitResult Hit(ForceInit); GetWorld()->LineTraceSingleByChannel(Hit, Start, End, CollisionType, Params); return Hit; }
AActor* UWeaponComponent::PlotHitLine(float LineLength, AController* Instigator, TSubclassOf<UDamageType> DamageType, UGameplaySystemComponent* GameplaySystem) { if (this->GetOwner() == nullptr) return nullptr; AController* OwnerAsController = dynamic_cast<AController*>(this->GetOwner()); if (OwnerAsController == nullptr) return nullptr; if (OwnerAsController->GetPawn() == nullptr) return nullptr; FVector TraceStart = OwnerAsController->GetPawn()->GetActorLocation(); FVector TraceEnd = OwnerAsController->GetPawn()->GetActorLocation(); { FRotator Rotation = OwnerAsController->GetControlRotation(); TraceEnd += Rotation.RotateVector(FVector(LineLength, 0, 0)); } // Setup the trace query FCollisionQueryParams TraceParams = FCollisionQueryParams(); TraceParams.AddIgnoredActor(OwnerAsController->GetPawn()); TraceParams.bTraceAsyncScene = true; FCollisionResponseParams CollisionParams = FCollisionResponseParams(); FHitResult HitResult; if (this->GetWorld()->LineTraceSingleByChannel(HitResult, TraceStart, TraceEnd, ECC_GameTraceChannel1, TraceParams, CollisionParams)) { if (GameplaySystem == nullptr) return nullptr; APawn* TargetAsPawn = dynamic_cast<APawn*>(HitResult.Actor.Get()); if (TargetAsPawn) { TargetAsPawn->GetController()->TakeDamage(GameplaySystem->GetInfightAttackPoints(), FDamageEvent(DamageType), Instigator, Instigator->GetPawn()); } return HitResult.GetActor(); } else { return nullptr; } }
void AUModCharacter::HandleUse() { FCollisionQueryParams RV_TraceParams = FCollisionQueryParams(FName(TEXT("RV_Trace")), true, this); RV_TraceParams.bTraceComplex = true; RV_TraceParams.bTraceAsyncScene = true; RV_TraceParams.bReturnPhysicalMaterial = false; FHitResult result(ForceInit); FVector p = PlayerCamera->GetComponentLocation(); FVector rot = PlayerCamera->GetComponentRotation().Vector(); bool hit = GetWorld()->LineTraceSingleByChannel(result, p, p + (rot * 2000), ECC_Pawn, RV_TraceParams); if (hit) { AActor *act = result.GetActor(); FString str = act->GetClass()->GetName(); if (str.Find(TEXT("_C"), ESearchCase::Type::CaseSensitive, ESearchDir::Type::FromStart, 0)) { FString realName = str.Replace(TEXT("_C"), TEXT(""), ESearchCase::Type::CaseSensitive); UE_LOG(UMod_Game, Warning, TEXT("BEntity : %s"), *realName); } else { UE_LOG(UMod_Game, Warning, TEXT("CEntity : %s"), *str); } } }
void ARoguelikeChar::ShootABullet() { FHitResult Hit; FCollisionQueryParams ColParams = FCollisionQueryParams(FName("Tsirla"), false, GetOwner()); ColParams.AddIgnoredActor(GetOwner()); ColParams.AddIgnoredActor(this); FVector Origin = LaserSource->GetComponentLocation(); FVector ForwardVector = PlayerCamera->GetForwardVector(); FVector Destination = Origin + (ForwardVector * 5000); PlayerController->ClientPlayCameraShake(OurShake, ShakePower); if (GetWorld()->LineTraceSingleByChannel(Hit, Origin, Destination, ECollisionChannel::ECC_WorldDynamic, ColParams)) { AZombieCharacter* Zombie = Cast<AZombieCharacter>(Hit.GetActor()); if (Zombie) { TSubclassOf<UDamageType> const ValidDamageTypeClass = TSubclassOf<UDamageType>(UPlayerDamageType::StaticClass()); //Determine the effect that will be applied to the zombie based on currently equipped ammo UPlayerDamageType* DamageType = Cast<UPlayerDamageType>(ValidDamageTypeClass.GetDefaultObject()); switch (CurrentBulletEquipped) { case 1: { DamageType->PlayerDamageType = EPlayerDamageType::Dot; break; } case 2: { DamageType->PlayerDamageType = EPlayerDamageType::Slow; break; } default: { DamageType->PlayerDamageType = EPlayerDamageType::Standard; break; } } FDamageEvent DamageEvent(ValidDamageTypeClass); float DamageAmount = CalculateBulletDamage(CurrentBulletEquipped); Zombie->TakeDamage(DamageAmount, DamageEvent, Zombie->GetController(), this); /*if (Zombie->IsDead()) { Kills++; PlayerController->UpdateUI(); }*/ } //if (Hit.Actor != GetOwner()) //{ // if (Hit.Component->ComponentHasTag("Zombie")) // { // TArray<USkeletalMeshComponent*> SkeletalMeshes; // Hit.GetActor()->GetComponents<USkeletalMeshComponent>(SkeletalMeshes); // UZombieAnimInstance* EnemyAnimInstance = Cast<UZombieAnimInstance>(SkeletalMeshes[0]->GetAnimInstance()); // if (!EnemyAnimInstance->bIsDead) // { // float DamageToDo = CalculateBulletDamage(CurrentBulletEquipped); // // TO BE REMOVED AFTER ORFEUS COMPLETES ZOMBIE CRAP. // TestHits++; // if (TestHits > 3) // { // EnemyAnimInstance->bIsDead = true; // Kills++; // PlayerController->UpdateUI(); // } // else // { // EnemyAnimInstance->GetHurt(); // } // } // } //} } switch (CurrentBulletEquipped) { case 0: if (BulletsLeft_A > 0) { BulletsLeft_A--; } break; case 1: if (BulletsLeft_B > 0) { BulletsLeft_B--; } break; case 2: if (BulletsLeft_C > 0) { BulletsLeft_C--; } break; default: break; } if (BulletsLeft_A == 0 && CurrentBulletEquipped == 0) { PlayerAnimationInstance->bCanShoot = false; } else if (BulletsLeft_B == 0 && CurrentBulletEquipped == 1) { PlayerAnimationInstance->bCanShoot = false; } else if (BulletsLeft_C == 0 && CurrentBulletEquipped == 2) { PlayerAnimationInstance->bCanShoot = false; } PlayerController->UpdateUI(); }
///CODE_SNIPPET_START: AActor::GetActorLocation AActor::GetActorRotation void AShooterProjectile::OnRep_Exploded() { FVector ProjDirection = GetActorForwardVector(); const FVector StartTrace = GetActorLocation() - ProjDirection * 200; const FVector EndTrace = GetActorLocation() + ProjDirection * 150; FHitResult Impact; if (!GetWorld()->LineTraceSingleByChannel(Impact, StartTrace, EndTrace, COLLISION_PROJECTILE, FCollisionQueryParams(TEXT("ProjClient"), true, Instigator))) { // failsafe Impact.ImpactPoint = GetActorLocation(); Impact.ImpactNormal = -ProjDirection; } Explode(Impact); }
void ANavigationObjectBase::Validate() { if ( ShouldBeBased() && (GoodSprite || BadSprite) ) { FVector OrigLocation = GetActorLocation(); const float Radius = CapsuleComponent->GetScaledCapsuleRadius(); FVector const Slice(Radius, Radius, 1.f); bool bResult = true; // Check for adjustment FHitResult Hit(ForceInit); const FVector TraceStart = GetActorLocation(); const FVector TraceEnd = GetActorLocation() - FVector(0.f,0.f, 4.f * CapsuleComponent->GetScaledCapsuleHalfHeight()); GetWorld()->SweepSingleByChannel(Hit, TraceStart, TraceEnd, FQuat::Identity, ECC_Pawn, FCollisionShape::MakeBox(Slice), FCollisionQueryParams(NAME_None, false, this)); if( Hit.bBlockingHit ) { const FVector HitLocation = TraceStart + (TraceEnd - TraceStart) * Hit.Time; FVector Dest = HitLocation + FVector(0.f,0.f,CapsuleComponent->GetScaledCapsuleHalfHeight()-2.f); // Move actor (TEST ONLY) to see if navigation point moves TeleportTo( Dest, GetActorRotation(), false, true ); // If only adjustment was down towards the floor, then it is a valid placement FVector NewLocation = GetActorLocation(); bResult = ( NewLocation.X == OrigLocation.X && NewLocation.Y == OrigLocation.Y && NewLocation.Z <= OrigLocation.Z ); // Move actor back to original position TeleportTo( OrigLocation, GetActorRotation(), false, true ); } // Update sprites by result if( GoodSprite ) { GoodSprite->SetVisibility(bResult); } if( BadSprite ) { BadSprite->SetVisibility(!bResult); } } // Force update of icon MarkComponentsRenderStateDirty(); }
void ANavigationObjectBase::FindBase() { if ( GetWorld()->HasBegunPlay() ) { return; } if( ShouldBeBased() ) { // not using find base, because don't want to fail if LD has navigationpoint slightly interpenetrating floor FHitResult Hit(1.f); const float Radius = CapsuleComponent->GetScaledCapsuleRadius(); FVector const CollisionSlice(Radius, Radius, 1.f); // check for placement const FVector TraceStart = GetActorLocation(); const FVector TraceEnd = GetActorLocation() - FVector(0.f,0.f, 4.f * CapsuleComponent->GetScaledCapsuleHalfHeight()); static FName NAME_NavFindBase = FName(TEXT("NavFindBase")); GetWorld()->SweepSingleByObjectType( Hit, TraceStart, TraceEnd, FQuat::Identity, FCollisionObjectQueryParams(ECC_WorldStatic), FCollisionShape::MakeBox(CollisionSlice), FCollisionQueryParams(NAME_NavFindBase, false)); // @fixme, ensure object is on the navmesh? // if( Hit.Actor != NULL ) // { // if (Hit.Normal.Z > Scout->WalkableFloorZ) // { // const FVector HitLocation = TraceStart + (TraceEnd - TraceStart) * Hit.Time; // TeleportTo(HitLocation + FVector(0.f,0.f,CapsuleComponent->GetScaledCapsuleHalfHeight()-2.f), GetActorRotation(), false, true); // } // else // { // Hit.Actor = NULL; // } // } if (GoodSprite) { GoodSprite->SetVisibility(true); } if (BadSprite) { BadSprite->SetVisibility(false); } } }
// Called every frame void ASpaceShip::Tick(float DeltaTime) { Super::Tick(DeltaTime); FHitResult hit; FVector direction = this->GetActorLocation() + this->GetActorUpVector() * -1 * this->groundDistance; DrawDebugLine(this->GetWorld(), this->GetActorLocation(), direction, FColor::Red, false, 2.0f); if (this->ActorLineTraceSingle(hit, this->GetActorLocation(), direction, ECollisionChannel::ECC_Visibility, FCollisionQueryParams())){ //isgrounded this->grounded = true; GEngine->AddOnScreenDebugMessage(-1, 0.2f, FColor::Green, TEXT("Grounded")); } else{ this->grounded = false; GEngine->AddOnScreenDebugMessage(-1, 0.2f, FColor::Green, TEXT("Flying")); } }
bool USoundBase::IsAudible( const FVector &SourceLocation, const FVector &ListenerLocation, AActor* SourceActor, bool& bIsOccluded, bool bCheckOcclusion ) { //@fixme - naive implementation, needs to be optimized // for now, check max audible distance, and also if looping check( SourceActor ); // Account for any portals const FVector ModifiedSourceLocation = SourceLocation; const float MaxDist = GetMaxAudibleDistance(); if( MaxDist * MaxDist >= ( ListenerLocation - ModifiedSourceLocation ).SizeSquared() ) { // Can't line check through portals if( bCheckOcclusion && ( MaxDist != WORLD_MAX ) && ( ModifiedSourceLocation == SourceLocation ) ) { static FName NAME_IsAudible(TEXT("IsAudible")); // simple trace occlusion check - reduce max audible distance if occluded bIsOccluded = SourceActor->GetWorld()->LineTraceTest(ModifiedSourceLocation, ListenerLocation, ECC_Visibility, FCollisionQueryParams(NAME_IsAudible, true, SourceActor)); } return true; } else { return false; } }
float UAISense_Sight::Update() { static const FName NAME_AILineOfSight = FName(TEXT("AILineOfSight")); SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight); const UWorld* World = GEngine->GetWorldFromContextObject(GetPerceptionSystem()->GetOuter()); if (World == NULL) { return SuspendNextUpdate; } int32 TracesCount = 0; static const int32 InitialInvalidItemsSize = 16; TArray<int32> InvalidQueries; TArray<FAISightTarget::FTargetId> InvalidTargets; InvalidQueries.Reserve(InitialInvalidItemsSize); InvalidTargets.Reserve(InitialInvalidItemsSize); AIPerception::FListenerMap& ListenersMap = *GetListeners(); FAISightQuery* SightQuery = SightQueryQueue.GetData(); for (int32 QueryIndex = 0; QueryIndex < SightQueryQueue.Num(); ++QueryIndex, ++SightQuery) { if (TracesCount < MaxTracesPerTick) { FPerceptionListener& Listener = ListenersMap[SightQuery->ObserverId]; ensure(Listener.Listener.IsValid()); FAISightTarget& Target = ObservedTargets[SightQuery->TargetId]; const bool bTargetValid = Target.Target.IsValid(); const bool bListenerValid = Listener.Listener.IsValid(); // @todo figure out what should we do if not valid if (bTargetValid && bListenerValid) { AActor* TargetActor = Target.Target.Get(); const FVector TargetLocation = TargetActor->GetActorLocation(); const FDigestedSightProperties& PropDigest = DigestedProperties[SightQuery->ObserverId]; const float SightRadiusSq = SightQuery->bLastResult ? PropDigest.LoseSightRadiusSq : PropDigest.SightRadiusSq; if (CheckIsTargetInSightPie(Listener, PropDigest, TargetLocation, SightRadiusSq)) { // UE_VLOG_SEGMENT(Listener.Listener.Get()->GetOwner(), Listener.CachedLocation, TargetLocation, FColor::Green, TEXT("%s"), *(Target.TargetId.ToString())); FVector OutSeenLocation(0.f); // do line checks if (Target.SightTargetInterface != NULL) { int32 NumberOfLoSChecksPerformed = 0; if (Target.SightTargetInterface->CanBeSeenFrom(Listener.CachedLocation, OutSeenLocation, NumberOfLoSChecksPerformed, Listener.Listener->GetBodyActor()) == true) { Listener.RegisterStimulus(TargetActor, FAIStimulus(*this, 1.f, OutSeenLocation, Listener.CachedLocation)); SightQuery->bLastResult = true; } else { // UE_VLOG_LOCATION(Listener.Listener.Get()->GetOwner(), TargetLocation, 25.f, FColor::Red, TEXT("")); Listener.RegisterStimulus(TargetActor, FAIStimulus(*this, 0.f, TargetLocation, Listener.CachedLocation, FAIStimulus::SensingFailed)); SightQuery->bLastResult = false; } TracesCount += NumberOfLoSChecksPerformed; } else { // we need to do tests ourselves /*const bool bHit = World->LineTraceTest(Listener.CachedLocation, TargetLocation , FCollisionQueryParams(NAME_AILineOfSight, true, Listener.Listener->GetBodyActor()) , FCollisionObjectQueryParams(ECC_WorldStatic));*/ FHitResult HitResult; const bool bHit = World->LineTraceSingle(HitResult, Listener.CachedLocation, TargetLocation , FCollisionQueryParams(NAME_AILineOfSight, true, Listener.Listener->GetBodyActor()) , FCollisionObjectQueryParams(ECC_WorldStatic)); ++TracesCount; if (bHit == false || (HitResult.Actor.IsValid() && HitResult.Actor->IsOwnedBy(TargetActor))) { Listener.RegisterStimulus(TargetActor, FAIStimulus(*this, 1.f, TargetLocation, Listener.CachedLocation)); SightQuery->bLastResult = true; } else { // UE_VLOG_LOCATION(Listener.Listener.Get()->GetOwner(), TargetLocation, 25.f, FColor::Red, TEXT("")); Listener.RegisterStimulus(TargetActor, FAIStimulus(*this, 0.f, TargetLocation, Listener.CachedLocation, FAIStimulus::SensingFailed)); SightQuery->bLastResult = false; } } } else { // UE_VLOG_SEGMENT(Listener.Listener.Get()->GetOwner(), Listener.CachedLocation, TargetLocation, FColor::Red, TEXT("%s"), *(Target.TargetId.ToString())); Listener.RegisterStimulus(TargetActor, FAIStimulus(*this, 0.f, TargetLocation, Listener.CachedLocation, FAIStimulus::SensingFailed)); SightQuery->bLastResult = false; } SightQuery->Importance = CalcQueryImportance(Listener, TargetLocation, SightRadiusSq); // restart query SightQuery->Age = 0.f; } else { // put this index to "to be removed" array InvalidQueries.Add(QueryIndex); if (bTargetValid == false) { InvalidTargets.AddUnique(SightQuery->TargetId); } } } else { // age unprocessed queries so that they can advance in the queue during next sort SightQuery->Age += 1.f; } SightQuery->RecalcScore(); } if (InvalidQueries.Num() > 0) { for (int32 Index = InvalidQueries.Num() - 1; Index >= 0; --Index) { // removing with swapping here, since queue is going to be sorted anyway SightQueryQueue.RemoveAtSwap(InvalidQueries[Index], 1, /*bAllowShrinking*/false); } if (InvalidTargets.Num() > 0) { for (const auto& TargetId : InvalidTargets) { // remove affected queries RemoveAllQueriesToTarget(TargetId, DontSort); // remove target itself ObservedTargets.Remove(TargetId); } // remove holes ObservedTargets.Compact(); } } // sort Sight Queries SortQueries(); //return SightQueryQueue.Num() > 0 ? 1.f/6 : FLT_MAX; return 0.f; }
void FPhATEdPreviewViewportClient::SimMousePress(FViewport* InViewport, bool bConstrainRotation, FKey Key) { bool bCtrlDown = InViewport->KeyState(EKeys::LeftControl) || InViewport->KeyState(EKeys::RightControl); bool bShiftDown = InViewport->KeyState(EKeys::LeftShift) || InViewport->KeyState(EKeys::RightShift); FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues( InViewport, GetScene(), EngineShowFlags )); FSceneView* View = CalcSceneView(&ViewFamily); const FViewportClick Click(View, this, EKeys::Invalid, IE_Released, InViewport->GetMouseX(), InViewport->GetMouseY()); #if DEBUG_CLICK_VIEWPORT SharedData->LastClickOrigin = Click.GetOrigin(); SharedData->LastClickDirection = Click.GetDirection(); #endif SharedData->LastClickPos = Click.GetClickPos(); FHitResult Result(1.f); bool bHit = SharedData->EditorSkelComp->LineTraceComponent(Result, Click.GetOrigin() - Click.GetDirection() * SimGrabCheckDistance, Click.GetOrigin() + Click.GetDirection() * SimGrabCheckDistance, FCollisionQueryParams(NAME_None,true)); if (bHit) { check(Result.Item != INDEX_NONE); FName BoneName = SharedData->PhysicsAsset->SkeletalBodySetups[Result.Item]->BoneName; //UE_LOG(LogPhysics, Warning, TEXT("Hit Bone Name (%s)"), *BoneName.ToString()); // Right mouse is for dragging things around if (Key == EKeys::RightMouseButton) { SharedData->bManipulating = true; DragX = 0.0f; DragY = 0.0f; SimGrabPush = 0.0f; // Update mouse force properties from sim options. SharedData->MouseHandle->LinearDamping = SharedData->EditorSimOptions->HandleLinearDamping; SharedData->MouseHandle->LinearStiffness = SharedData->EditorSimOptions->HandleLinearStiffness; SharedData->MouseHandle->AngularDamping = SharedData->EditorSimOptions->HandleAngularDamping; SharedData->MouseHandle->AngularStiffness = SharedData->EditorSimOptions->HandleAngularStiffness; SharedData->MouseHandle->InterpolationSpeed = SharedData->EditorSimOptions->InterpolationSpeed; // Create handle to object. SharedData->MouseHandle->GrabComponentAtLocationWithRotation(SharedData->EditorSkelComp, BoneName, Result.Location, FRotator::ZeroRotator); FMatrix InvViewMatrix = View->ViewMatrices.ViewMatrix.InverseFast(); SimGrabMinPush = SimMinHoldDistance - (Result.Time * SimGrabCheckDistance); SimGrabLocation = Result.Location; SimGrabX = InvViewMatrix.GetUnitAxis( EAxis::X ); SimGrabY = InvViewMatrix.GetUnitAxis( EAxis::Y ); SimGrabZ = InvViewMatrix.GetUnitAxis( EAxis::Z ); } // Left mouse is for poking things else if (Key == EKeys::LeftMouseButton) { SharedData->EditorSkelComp->AddImpulseAtLocation(Click.GetDirection() * SharedData->EditorSimOptions->PokeStrength, Result.Location, BoneName); } } }
// Sets default values AMyCharacter::AMyCharacter() { // Set this character to call Tick() every frame PrimaryActorTick.bCanEverTick = true; // Set this pawn to be controlled by the lowest-numbered player AutoPossessPlayer = EAutoReceiveInput::Player0; // Set size for collision capsule GetCapsuleComponent()->InitCapsuleSize(5.f, 80.0f); // Set our turn rates for input BaseTurnRate = 45.f; BaseLookUpRate = 45.f; // Create a CameraComponent MyCharacterCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("MyCharacterCamera")); MyCharacterCamera->SetupAttachment(GetCapsuleComponent()); MyCharacterCamera->RelativeLocation = FVector(0.f, 0.f, 64.f); // Position the camera MyCharacterCamera->bUsePawnControlRotation = true; //Set the value of the applied force on the handle when opening or closing drawers AppliedForce = FVector(1000, 1000, 1000); //Initialize TraceParams parameter TraceParams = FCollisionQueryParams(FName(TEXT("Trace")), true, this); TraceParams.bTraceComplex = true; TraceParams.bTraceAsyncScene = true; TraceParams.bReturnPhysicalMaterial = false; //Set the maximum grasping length (Length of the 'hands' of the character) MaxGraspLength = 200.f; //Set the pointers to the items held in hands to null at the begining of the game LeftHandSlot = nullptr; RightHandSlot = nullptr; //Set the rotations to character's LeftHandRotator = GetActorRotation(); RightHandRotator = GetActorRotation(); //By default our character will perfom actions with the right hand bRightHandSelected = true; //At the begining we don't hold an item which can be rotated bRotationModeAllowed = false; // 1 - Z axis ; 2 - X axis ; 3 - Y axis ; 0 - default rotation disabled RotationAxisIndex = 0; //Offsets for positioning the items held in hand RightZPos = 30.f; LeftZPos = 30.f; RightYPos = 20; LeftYPos = 20; //Default value for how many items can our character pick at once StackGrabLimit = 4; //Default speed multiplier CharacterSpeed = 0.4; }
/** Tick */ void UFluidSurfaceComponent::TickComponent( float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction ) { Super::TickComponent( DeltaTime, TickType, ThisTickFunction ); LastDeltaTime = DeltaTime; float SimStep = 1.f / UpdateRate; static float Time = 0.0f; #if WITH_EDITOR /* Only update if checked */ if( !UpdateComponent ) return; #endif /* If this water hasn't been rendered for a while, stop updating */ if (LastRenderTime > 0 && GetWorld()->TimeSeconds - LastRenderTime > 1) return; Time += DeltaTime; if( Time > SimStep ) { Time = 0.0f; LatestVerts = !LatestVerts; /* Add ripples for actors in the water */ TArray<struct FOverlapResult> OverlappingActors; FCollisionShape CollisionShape; CollisionShape.SetBox( FluidBoundingBox.GetExtent( ) ); /* Find overlapping actors */ GetWorld()->OverlapMultiByChannel(OverlappingActors, GetComponentLocation(), GetComponentQuat(), ECC_WorldDynamic, CollisionShape, FCollisionQueryParams(false)); // @todo: handle better /* Iterate through found overlapping actors */ for( int i = 0; i < OverlappingActors.Num( ); i++ ) { TWeakObjectPtr<AActor> Actor = OverlappingActors[ i ].Actor; /* Dont care about self and modifiers */ if( Actor != NULL && !Actor->IsA( AFluidSurfaceActor::StaticClass( ) ) && !Actor->IsA( AFluidSurfaceModifier::StaticClass( ) ) ) { FVector LocalVel = GetWorldToComponent( ).TransformVector( Actor->GetVelocity( ) ); float HorizVelMag = LocalVel.Size( ); Pling( Actor->GetActorLocation( ), RippleVelocityFactor * HorizVelMag, Actor->GetSimpleCollisionRadius( ) ); } } /* Do test ripple (moving around in a circle) */ if( GIsEditor && TestRipple ) { TestRippleAng += SimStep * MyU2Rad * TestRippleSpeed; FVector WorldRipplePos, LocalRipplePos; float RippleRadius = 0.3f * ( FluidXSize - 1 ) * FluidGridSpacing; if( FluidGridType == EFluidGridType::FGT_Hexagonal ) RippleRadius = FMath::Max( RippleRadius, 0.3f * ( FluidYSize - 1 ) * FluidGridSpacing * ROOT3OVER2 ); else RippleRadius = FMath::Max( RippleRadius, 0.3f * ( FluidYSize - 1 ) * FluidGridSpacing ); LocalRipplePos.X = ( RippleRadius * FMath::Sin( TestRippleAng ) ); LocalRipplePos.Y = ( RippleRadius * FMath::Cos( TestRippleAng ) ); LocalRipplePos.Z = 0.f; WorldRipplePos = ComponentToWorld.TransformPosition( LocalRipplePos ); Pling( WorldRipplePos, TestRippleStrength, TestRippleRadius ); } /* Add modifier effects */ for( int i = 0; i < Modifiers.Num( ); i++ ) { if( Modifiers[ i ] && Modifiers[ i ]->Active ) Modifiers[ i ]->Update( DeltaTime ); } /* Need to send new dynamic data */ MarkRenderDynamicDataDirty( ); } }
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"); } } } }
void ARPGProjectile::OnRep_Exploded() { static FName PowerTag = FName(TEXT("PowerTrace")); FCollisionQueryParams TraceParams(PowerTag, false); TraceParams.bTraceComplex = false; TraceParams.bTraceAsyncScene = false; TraceParams.bReturnPhysicalMaterial = true; FVector ProjDirection = GetActorRotation().Vector(); const FVector StartTrace = GetActorLocation() - ProjDirection * 200; const FVector EndTrace = GetActorLocation() + ProjDirection * 150; FHitResult Impact; bool hitResult = GetWorld()->LineTraceSingle(Impact, StartTrace, EndTrace, ECollisionChannel::ECC_Pawn, FCollisionQueryParams(TEXT("ProjClient"), true, Instigator)); if (!hitResult) { // failsafe Impact.ImpactPoint = GetActorLocation(); Impact.ImpactNormal = -ProjDirection; } Explode(Impact); }
/** 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"); }