void AZombieCharacter::Attack() { //This function is used only when it's permitted by the zombie's animation instance //It creates a raycast in a sphere shape and checks for possible hits //If the hits contain our player it makes sure it applies damage to him //Setting up the start and end location of the raycast FVector StartLocation = GetMesh()->GetSocketLocation(FName("MeleeStartSocket")); FVector EndLocation = GetMesh()->GetSocketLocation(FName("MeleeEndSocket")); //Raycasting in a sphere to detect collisions TArray<FHitResult> HitResults; //Setting up the shape of the raycast FCollisionShape CollisionShape; CollisionShape.ShapeType = ECollisionShape::Sphere; CollisionShape.SetSphere(AttackRaycastRadius); //Object query parameters FCollisionObjectQueryParams ObjectQueryParams; ObjectQueryParams.AllDynamicObjects; //Handling ignored actors FCollisionQueryParams QueryParams; QueryParams.AddIgnoredActor(this); UWorld* World = GetWorld(); if (World && ZAnimInstance->bEligibleForAttack) { //Raycasting... bool bHit = World->SweepMultiByObjectType(HitResults, StartLocation, EndLocation, FQuat::Identity, ObjectQueryParams, CollisionShape, QueryParams); //Raycast visualization /*FVector Center = ((EndLocation - StartLocation) / 2) + StartLocation; DrawDebugSphere(World, Center, AttackRaycastRadius, 20, FColor::Green, false, 2.f);*/ //Checking for possible hits if (bHit) { for (auto It = HitResults.CreateIterator(); It; It++) { ARoguelikeChar* Char = Cast<ARoguelikeChar>(It->GetActor()); if (Char && ZAnimInstance && GetCharacterMovement()) { //Calling the attack function from character Char->TakeDamageFromZombie(Damage); //Closing the flag which checks for the attack function ZAnimInstance->bEligibleForAttack = false; //Updating with new movement speed GetCharacterMovement()->MaxWalkSpeed = InitialMaxWalkSpeed; ZAnimInstance->Speed = InitialMaxWalkSpeed; break; } } } } }
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 AKIMCharacter::Interact() { if (IsInRoationState && PickedUpItem) { ((AKIMInteractionActor*)PickedUpItem)->LayBack(this); return; } FHitResult outHit; FCollisionQueryParams params; params.AddIgnoredActor(this); params.AddIgnoredActor(PickedUpItem); FVector TraceStart = CameraComponent->GetComponentLocation(); FVector TraceEnd = TraceStart + (CameraComponent->GetForwardVector() * InteractionDistance); GetWorld()->LineTraceSingleByChannel(outHit, TraceStart, TraceEnd, ECollisionChannel::ECC_PhysicsBody, params); if (outHit.GetActor() != NULL && outHit.GetActor()->GetClass()->IsChildOf(AKIMInteractionActor::StaticClass())) { AKIMInteractionActor* InteractionActor = ((AKIMInteractionActor*)outHit.GetActor()); InteractionActor->Interacted(this, outHit.GetComponent()); UE_LOG(LogClass, Warning, TEXT("Interacted with %s"), *outHit.GetActor()->GetName()); UE_LOG(LogClass, Warning, TEXT("(%s)"), *outHit.GetComponent()->GetName()); } else if (outHit.GetActor() == NULL && PickedUpItem) { PickedUpItem->DetachRootComponentFromParent(true); ((AKIMInteractionActor*)PickedUpItem)->Droped(); ((AKIMInteractionActor*)PickedUpItem)->InteractionType = EKIMInteractionTypes::OnPickUp; UE_LOG(LogClass, Warning, TEXT("Droped %s"), *PickedUpItem->GetName()); PickedUpItem = NULL; } }
void UMWBotWeaponComponent::Fire() { if (!CanFire()) { return; } // cast a line FHitResult hit; FCollisionQueryParams traceParams; traceParams.AddIgnoredActor(GetOwner()); const int32 randSeed = FMath::Rand(); FRandomStream randStream(randSeed); const FVector traceStart = GetComponentLocation(); const FVector aimDir = GetComponentRotation().Vector(); const FVector shotDir = randStream.VRandCone(aimDir, FMath::DegreesToRadians(Spread)); const FVector traceEnd = traceStart + shotDir * 1e5; GetWorld()->LineTraceSingle(hit, traceStart, traceEnd, ECollisionChannel::ECC_Visibility, traceParams); ProcessHit(hit); // temporary draw if (hit.bBlockingHit) { DrawDebugLine(GetWorld(), traceStart, hit.ImpactPoint, FColor::Red, false, -1.f, 0, 10); } else { DrawDebugLine(GetWorld(), traceStart, traceEnd, FColor::Red, false, -1.f, 0, 10); } }
bool UMWBotSensorComponent::CheckLOS(const AActor* Actor, bool& OutCanHear) const { if (!Actor/* || bCrazy*/) { return false; } bool canSee = false; float dist = (GetComponentLocation() - Actor->GetActorLocation()).Size(); if (dist < SeeDistance) { FHitResult hit; FCollisionQueryParams params; params.AddIgnoredActor(GetOwner()); GetWorld()->LineTraceSingle(hit, GetComponentLocation(), Actor->GetActorLocation(), ECollisionChannel::ECC_Visibility, params); canSee = hit.bBlockingHit && (Actor == hit.Actor); } OutCanHear = canSee && (dist < HearDistance); return canSee; }
/* * Spawns the hitbox and processes the actors within it */ void AHero::AttackTrace() { //Actors that overlap the box stored in this array TArray<struct FOverlapResult> OutOverlaps; //Orient the box in the direction of the character FQuat Rotation = Instigator->GetTransform().GetRotation(); FVector Start = Instigator->GetTransform().GetLocation() + Rotation.Rotator().Vector() * 100.0f; FCollisionShape CollisionHitShape; FCollisionQueryParams CollisionParams; //Have the hitbox ignore the player CollisionParams.AddIgnoredActor(Instigator); //Set what will respond to the collision FCollisionObjectQueryParams CollisionObjectTypes; CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_PhysicsBody); CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_Pawn); CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_WorldStatic); //Create the hitbox and get the actors within CollisionHitShape = FCollisionShape::MakeBox(FVector(100.0f, 60.0f, 0.5f)); GetWorld()->OverlapMulti(OutOverlaps, Start, Rotation, CollisionHitShape, CollisionParams, CollisionObjectTypes); //Process all hit actors for (int i = 0; i < OutOverlaps.Num(); i++) { if (OutOverlaps[i].GetActor() && !HitActors.Contains(OutOverlaps[i].GetActor())) { //Check if hit registered GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("hit")); //Now call the function that does something to our unfortunate actor... ProcessHitActor(OutOverlaps[i].GetActor()); } } }
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 ATP_TopDownCharacter::Tick(float DeltaSeconds) { if (CursorToWorld != nullptr) { if (UHeadMountedDisplayFunctionLibrary::IsHeadMountedDisplayEnabled()) { if (UWorld* World = GetWorld()) { FHitResult HitResult; FCollisionQueryParams Params; FVector StartLocation = TopDownCameraComponent->GetComponentLocation(); FVector EndLocation = TopDownCameraComponent->GetComponentRotation().Vector() * 2000.0f; Params.AddIgnoredActor(this); World->LineTraceSingleByChannel(HitResult, StartLocation, EndLocation, ECC_Visibility, Params); FQuat SurfaceRotation = HitResult.ImpactNormal.ToOrientationRotator().Quaternion(); CursorToWorld->SetWorldLocationAndRotation(HitResult.Location, SurfaceRotation); } } else if (APlayerController* PC = Cast<APlayerController>(GetController())) { FHitResult TraceHitResult; PC->GetHitResultUnderCursor(ECC_Visibility, true, TraceHitResult); FVector CursorFV = TraceHitResult.ImpactNormal; FRotator CursorR = CursorFV.Rotation(); CursorToWorld->SetWorldLocation(TraceHitResult.Location); CursorToWorld->SetWorldRotation(CursorR); } } }
void AStealthArea::CalculateVisibility(AGameCharacter* calculatingUnit, TArray<AGameCharacter*>& sightList, TArray<AGameCharacter*>& availableUnits) { if (!IsValid(calculatingUnit)) return; //first get visible units on the outside based on increased radial area TArray<AActor*> ignoreList; for (AGameCharacter* gc : availableUnits) ignoreList.AddUnique(gc); for (AGameCharacter* gc : availableUnits) { if (occupyingUnits.Contains(gc)) //don't account for units in this area yet continue; if (gc->GetTeamIndex() == calculatingUnit->GetTeamIndex()) { sightList.AddUnique(gc); continue; } FVector start = GetActorLocation(); FVector end = gc->GetActorLocation(); if ((start - end).SizeSquared2D() <= FMath::Square(calculatingUnit->sightRadius * 1.15f)) { FHitResult hit; FCollisionQueryParams collisionParams; TArray<AActor*> ignoredActors = ignoreList; ignoredActors.Remove(gc); collisionParams.AddIgnoredActors(ignoredActors); collisionParams.AddIgnoredActor(this); GetWorld()->LineTraceSingleByChannel(hit, start, end, ECC_Visibility, collisionParams); if (hit.GetActor() == gc) { if (!IsValid(gc->currentStealthArea)) sightList.AddUnique(gc); } } } //finally add all of the units that are currently in the area for (AGameCharacter* gc : occupyingUnits) { if (IsValid(gc)) sightList.AddUnique(gc); else sightList.Remove(gc); } }
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())); } } } } } }
void ABaseCharacter::CheckAttackOverlap(){ //Overlapping actors for each box spawned will be stored here TArray<struct FOverlapResult> OutActorOverlaps; //Hit other actors only once TArray<AActor*> ProcessedActors; //The initial rotation of our box is the same as our character rotation FQuat Rotation = GetTransform().GetRotation(); FVector Start = GetTransform().GetLocation() + Rotation.Rotator().Vector() * 100.0f; FCollisionShape CollisionHitShape; FCollisionQueryParams CollisionParams; //We do not want the character to hit itself, don't store this character in the array, to ignore it's collision CollisionParams.AddIgnoredActor(this); //Set the channels that will respond to the collision FCollisionObjectQueryParams CollisionObjectTypes; CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_PhysicsBody); CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_Pawn); //CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_WorldStatic); // uncomment to enable bashing objects //Create the box and get the overlapping actors CollisionHitShape = FCollisionShape::MakeBox(AttackBox); GetWorld()->OverlapMulti(OutActorOverlaps, Start, Rotation, CollisionHitShape, CollisionParams, CollisionObjectTypes); AActor* ActorToProcess; //Process all hit actors for (int i = 0; i < OutActorOverlaps.Num(); ++i) { ActorToProcess = OutActorOverlaps[i].GetActor(); //We process each actor only once per Attack execution if (ActorToProcess && !ProcessedActors.Contains(ActorToProcess)) { //Add this actor to the array because we are spawning one box per tick and we don't want to hit the same actor twice during the same attack animation ProcessedActors.AddUnique(ActorToProcess); if ( dynamic_cast<APatrollingEnemyCharacter*>(ActorToProcess) ){ APatrollingEnemyCharacter* ennemy = (APatrollingEnemyCharacter*)ActorToProcess; ennemy->OnHit(this); } } } }
bool ADKBarrel::GetFloor(FHitResult& out) { FHitResult outResults; FVector StartLocation = GetActorLocation() + FVector(0, TraceStartDistance,0); FVector EndLocation = StartLocation + (FVector(0, 0, -1) * 100); FCollisionQueryParams Params; Params.AddIgnoredActor(this); FCollisionObjectQueryParams objParams; bool hit = GetWorld()->LineTraceSingle(outResults, StartLocation, EndLocation, Params, objParams); out = outResults; return hit; }
int32 UTB_AimComponent::CoverModifier(ATB_Character *Target) { UWorld *World = GetWorld(); // Ignore collisions with the aiming character and its weapon FCollisionQueryParams Params; Params.bTraceComplex = true; Params.AddIgnoredActor(Character); if (Weapon) { Params.AddIgnoredActor(Weapon); } if (Target->Weapon) { Params.AddIgnoredActor(Target->Weapon); } // uncomment to draw debug lines /* FName TraceTag("CoverTrace"); World->DebugDrawTraceTag = TraceTag; Params.TraceTag = TraceTag; */ FCollisionObjectQueryParams ObjectParams; FHitResult HitResult; TArray<FVector> HitLocations; Target->GetHitLocations(HitLocations); FVector StartLocation = GetComponentLocation(); int Hidden = 0; for (auto HitLocation : HitLocations) { bool HitSomething = World->LineTraceSingle(HitResult, StartLocation, HitLocation, Params, ObjectParams); if (HitSomething && Target->GetUniqueID() != HitResult.Actor->GetUniqueID()) { Hidden++; } } if (Hidden < HitLocations.Num()) { // reduce cover by half if we can see the enemy at all // a penalty above 60 makes an enemy virtually impossible to hit Hidden -= (Hidden / 3); } return (Hidden * -100) / std::max(HitLocations.Num(), 1); }
void AShaderPluginDemoCharacter::OnFire() { //Try to set a texture to the object we hit! FHitResult HitResult; FVector StartLocation = FirstPersonCameraComponent->GetComponentLocation(); FRotator Direction = FirstPersonCameraComponent->GetComponentRotation(); FVector EndLocation = StartLocation + Direction.Vector() * 10000; FCollisionQueryParams QueryParams; QueryParams.AddIgnoredActor(this); if (GetWorld()->LineTraceSingleByChannel(HitResult, StartLocation, EndLocation, ECC_Visibility, QueryParams)) { TArray<UStaticMeshComponent*> StaticMeshComponents = TArray<UStaticMeshComponent*>(); AActor* HitActor = HitResult.GetActor(); if (NULL != HitActor) { HitActor->GetComponents<UStaticMeshComponent>(StaticMeshComponents); for (int32 i = 0; i < StaticMeshComponents.Num(); i++) { UStaticMeshComponent* CurrentStaticMeshPtr = StaticMeshComponents[i]; CurrentStaticMeshPtr->SetMaterial(0, MaterialToApplyToClickedObject); UMaterialInstanceDynamic* MID = CurrentStaticMeshPtr->CreateAndSetMaterialInstanceDynamic(0); UTexture* CastedRenderTarget = Cast<UTexture>(RenderTarget); MID->SetTextureParameterValue("InputTexture", CastedRenderTarget); } } } // try and play the sound if specified if (FireSound != NULL) { UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation()); } // try and play a firing animation if specified if (FireAnimation != NULL) { // Get the animation object for the arms mesh UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance(); if (AnimInstance != NULL) { AnimInstance->Montage_Play(FireAnimation, 1.f); } } }
void UTB_AimComponent::InitCollisionQueryParams(FCollisionQueryParams &Params) { // remember to set the physical material in phat for skeletal meshes // (the collision channels for the character might also need to be tuned) Params.bTraceComplex = true; Params.bReturnPhysicalMaterial = true; // Ignore collisions with the aiming character and its weapon Params.AddIgnoredActor(Character); if (Weapon) { Params.AddIgnoredActor(Weapon); } if (EnemyTarget->Weapon) { Params.AddIgnoredActor(EnemyTarget->Weapon); } }
void UGISInventoryBaseComponent::DropItemFromInventory(const FGISSlotInfo& DropItemInfoIn) { if (GetOwnerRole() < ROLE_Authority) { ServerDropItemFromInventory(DropItemInfoIn); } else { if (!DropItemInfoIn.IsValid()) return; UGISItemData* tempItem = DropItemInfoIn.GetItemData(); if (tempItem)// && tempItem->ItemLootActorClass) { FVector CurrentLocation = PCOwner->GetPawn()->GetActorLocation(); FVector ForwardVector = PCOwner->GetPawn()->GetActorRotation().Vector(); //find floor infront of character FHitResult HitOut; FVector Start = CurrentLocation + ForwardVector * 150; FVector End = Start + FVector(0, 0, -1) * 300; FCollisionQueryParams Params; Params.AddIgnoredActor(PCOwner->GetPawn()); bool bHit = GetWorld()->LineTraceSingle(HitOut, Start, End, ECollisionChannel::ECC_WorldStatic, Params); if (bHit) { FActorSpawnParameters SpawnParams; SpawnParams.bNoCollisionFail = true; AGISPickupActor* pickup = GetWorld()->SpawnActor<AGISPickupActor>(PickupActor, HitOut.Location, FRotator(0, 0, 0), SpawnParams); if (pickup) { UGISItemData* duplicatedItem = ConstructObject<UGISItemData>(tempItem->GetClass(), pickup, NAME_Name, EObjectFlags::RF_NoFlags, tempItem); pickup->ItemToLoot.Add(duplicatedItem); } } RemoveItem(DropItemInfoIn); tempItem->OnDropFromInventory(); } } }
void AMyCharacter_FirstTry::SetNewTrapLocation() { if (TrapToBePlaced) { FVector SpawnLocation = GetActorLocation() + (GetActorForwardVector() * SpawnDistance); SpawnLocation.Y -= TrapToBePlaced->TrapCollider->GetUnscaledBoxExtent().Y; FVector EndLocation = SpawnLocation; //We want a vertical vector in order to raycast on landscape EndLocation.Z = 0; FHitResult Hit; FCollisionQueryParams CollisionQueryParams; CollisionQueryParams.AddIgnoredActor(TrapToBePlaced); //Sweep in order to find the landscape impact point (the trap must always be placed into the ground) GetWorld()->SweepSingleByChannel(Hit, SpawnLocation, EndLocation, FQuat::Identity, ECollisionChannel::ECC_WorldStatic, FCollisionShape::FCollisionShape(), CollisionQueryParams); TrapToBePlaced->SetActorLocation(Hit.ImpactPoint); } }
void AKIMCharacter::Interact() { FHitResult outHit; FCollisionQueryParams params; params.AddIgnoredActor(this); params.AddIgnoredActor(PickedUpItem); FVector TraceStart = CameraComponent->GetComponentLocation(); FVector TraceEnd = TraceStart + (CameraComponent->GetForwardVector() * 250); GetWorld()->LineTraceSingleByChannel(outHit, TraceStart, TraceEnd, ECollisionChannel::ECC_WorldDynamic, params); GetWorld()->GetNavigationSystem()->SimpleMoveToLocation(GetController(), outHit.Location); if (outHit.GetActor() != NULL && outHit.GetActor()->GetClass()->IsChildOf(AKIMInteractionActor::StaticClass())) { AKIMInteractionActor* InteractionActor = ((AKIMInteractionActor*)outHit.GetActor()); InteractionActor->Interacted(this); UE_LOG(LogClass, Warning, TEXT("Interacted with %s"), *outHit.GetActor()->GetName()); } else if (outHit.GetActor() == NULL && PickedUpItem) { PickedUpItem->DetachRootComponentFromParent(true); UE_LOG(LogClass, Warning, TEXT("Droped %s"), *PickedUpItem->GetName()); PickedUpItem = NULL; } }
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 ACSCameraActor::UpdateCamera(const float DeltaTime, const FVector& Origin, const FRotator& ControlRotation) { { const FCSHeightInfo& Info = HeightInfos[(int32)HeightState.GetValue()]; FRotator FocusOffsetRotation(0, ControlRotation.Yaw, 0); FVector WorldFocusOffset = FocusOffsetRotation.RotateVector(Info.Focus); SetActorLocation(Origin + WorldFocusOffset); Root->SetRelativeRotation(FRotator(ControlRotation.Pitch, ControlRotation.Yaw, 0)); // Simulate Spring Arm. Because it has some bugs. const FVector RayStart = Root->GetComponentLocation(); const FVector RayDirection = Root->GetComponentRotation().RotateVector(-FVector::ForwardVector); const FVector RayEnd = RayStart + (RayDirection * Info.Distance); FVector TargetLocation; FCollisionQueryParams Params; Params.AddIgnoredActor(this); Params.AddIgnoredActor(PlayerCharacterBase); FHitResult Result; if (GetWorld()->LineTraceSingle(Result, RayStart, RayEnd, ECollisionChannel::ECC_Camera, Params)) { TargetLocation = Result.Location; if (bDebugTrace) { UE_LOG(CSLog, Log, TEXT("Actor: [%s] Comp: [%s] Loc: [%f, %f, %f]"), *Result.Actor->GetName(), *Result.Component->GetName(), Result.Location.X, Result.Location.Y, Result.Location.Z); } } else { TargetLocation = RayEnd; } Camera->SetWorldLocation(FMath::VInterpTo(Camera->GetComponentLocation(), TargetLocation, DeltaTime, HeightLerpSpeed)); } { // Do FOV Anim. const FCSZoomInfo& Info = ZoomInfos[(int32)ZoomState.GetValue()]; Camera->FieldOfView = FMath::FInterpTo(Camera->FieldOfView, Info.FOV, DeltaTime, FOVLerpSpeed); } }
FVector ASkill::GetGroundLocationBeneathPoint(FVector point) { FHitResult hit; FVector start = point; FVector end = start; end.Z -= 100000.f; //get all game characters and projectiles currently in the world so we can ignore them later TArray<AActor*> ignoredActors; for (TActorIterator<AGameCharacter> chr(GetWorld()); chr; ++chr) ignoredActors.AddUnique(*chr); for (TActorIterator<AProjectile> pro(GetWorld()); pro; ++pro) ignoredActors.AddUnique(*pro); FCollisionQueryParams collisionParams; collisionParams.AddIgnoredActors(ignoredActors); if (GetWorld()->LineTraceSingleByChannel(hit, start, end, ECC_WorldStatic, collisionParams)) return hit.ImpactPoint; else return point; }
void AFPSHorrorCharacter::OnFire() { // LINE TRACE STUFF FCollisionQueryParams Traceparam; FCollisionObjectQueryParams CollisionObjectParams; FVector Start = FirstPersonCameraComponent->GetComponentLocation(); //FVector Start = FirstPersonCameraComponent FVector End = Start + FirstPersonCameraComponent->GetForwardVector() * range; FHitResult HitData(ForceInit); //ignore collision with player AFPSHorrorCharacter* myCharacter = Cast<AFPSHorrorCharacter>(this); Traceparam.AddIgnoredActor(myCharacter); GetWorld()->LineTraceSingle(HitData, Start, End, Traceparam, CollisionObjectParams); //Check the target's hit by the line trace if (HitData.GetActor() != NULL) { AGuard* newGuard = Cast<AGuard>(HitData.GetActor()); if (newGuard) { newGuard->Health -= Damage; if (newGuard->Health <= 0)//increase the power meter if the guard is dead { CurrentPower += 10; IncreaseCurrentHealth(); CheckPower(); } } } }
void ADonkeyKongCharacter::InputLookForLadder() { if (!bIsClimbing) { FVector StartTrace = GetActorLocation() + FVector(150, 0, 0); FVector EndTrace = StartTrace + FVector(-1, 0, 0) * 100; FCollisionQueryParams Params; Params.AddIgnoredActor(this); FHitResult hit; GetWorld()->LineTraceSingle(hit, StartTrace, EndTrace, Params, LadderPrams); if (hit.Actor.IsValid()) { if (ADKLadder* Ladder = Cast<ADKLadder>(hit.Actor.Get())) { SetActorLocation(hit.Location); bIsClimbing = true; GetCharacterMovement()->SetMovementMode(EMovementMode::MOVE_None); CurrentLadder = Ladder; } } } }
void UShardsMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); FHitResult HitResult; FHitResult ShapeTraceResult; FCollisionShape shape = FCollisionShape::MakeBox(FVector(0.72f*playerradius, 0.72f*playerradius,10.0f)); FCollisionQueryParams Params; Params.bFindInitialOverlaps = true; Params.AddIgnoredActor(UpdatedComponent->GetAttachmentRootActor()); // Telepads don't count. for (TActorIterator<ATelePad> ActorItr(GetWorld()); ActorItr; ++ActorItr) { Params.AddIgnoredActor(ActorItr.operator->()); } // Neither do destructibles. for (TActorIterator<ADestructibleBox> ActorItr(GetWorld()); ActorItr; ++ActorItr) { // When they're broken, that is. if (ActorItr->fadetimer >= 0.0f) { Params.AddIgnoredActor(ActorItr.operator->()); } } if (isclimbing) { return; } TArray<FHitResult> results; if (forceregiondirection.Z == 0.0f) { GetWorld()->SweepMultiByChannel(results, UpdatedComponent->GetComponentLocation() - 0.0f*45.0f*FVector::UpVector, UpdatedComponent->GetComponentLocation() - 1000.0f*FVector::UpVector, FQuat::Identity, ECC_Visibility, shape, Params); //100 for (FHitResult r : results) { if (r.Normal.Z > 0.6f) { ShapeTraceResult = r; break; } } if (!ShapeTraceResult.IsValidBlockingHit()) { GetWorld()->LineTraceSingleByChannel(ShapeTraceResult, UpdatedComponent->GetComponentLocation(), UpdatedComponent->GetComponentLocation() - 1000.0f*FVector::UpVector, ECC_Visibility, Params); } } FVector PlayerCapsuleBottom = UpdatedComponent->GetComponentLocation() - 45.0f * FVector::UpVector; // 50 float RequiredDistance = (onground ? 50.0f*grounddetecttfudgefactor : 10.0f)*FMath::Pow(playerhalfheight / 90.0f,4.0f) + playerhalfheight/2.0f; //50,1 DistanceFromImpact = (PlayerCapsuleBottom - ShapeTraceResult.ImpactPoint).Z; overground = ShapeTraceResult.IsValidBlockingHit(); FHitResult groundhitresult; GetWorld()->LineTraceSingleByChannel(groundhitresult, UpdatedComponent->GetComponentLocation(), UpdatedComponent->GetComponentLocation() - 10000.0f*FVector::UpVector, ECC_Visibility, Params); groundtracehit = groundhitresult.ImpactPoint; if (!onground) { offGroundTime += DeltaTime; } toosteep = false; if (enforcementtimer >= 0.0f) { enforcementtimer += DeltaTime; toosteep = true; } wasonground = onground; onground = false; prevgroundvelocity = groundvelocity; groundvelocity = FVector::ZeroVector; platformangularfrequency = 0.0f; platformspindir = 1; FloorNormal = FVector::ZeroVector; if ((enforcementtimer < timerlimit && ShapeTraceResult.Normal.Z>0.6f) && DistanceFromImpact < RequiredDistance && !justjumped) { // (PlayerVelocity.Z <= 0.0f || wasonground) if (ShapeTraceResult.Normal.Z < minnormalz) { if (enforcementtimer == -1.0f) { enforcementtimer = 0.0f; } } else { enforcementtimer = -1.0f; } FVector pvel; // Handle moving platforms. if (ShapeTraceResult.GetActor() != nullptr && ShapeTraceResult.GetComponent() != nullptr && ShapeTraceResult.GetComponent()->IsA(UStaticMeshComponent::StaticClass())) { // The motion of a point on a rigid body is the combination of its motion about the center of mass... FVector angvel = FMath::DegreesToRadians((((UStaticMeshComponent*)ShapeTraceResult.GetComponent())->GetPhysicsAngularVelocity())); FVector rr = GetActorLocation() - (((UStaticMeshComponent*)ShapeTraceResult.GetComponent())->GetComponentLocation()); FVector rvel = FVector::CrossProduct(angvel, rr); // ...and the motion of the center of mass itself. FVector cmvel = (((UStaticMeshComponent*)ShapeTraceResult.GetComponent())->GetPhysicsLinearVelocity()); groundvelocity = rvel + cmvel; platformangularfrequency = -angvel.Z; } if ((PlayerVelocity.Z <= groundvelocity.Z || wasonground)) { onground = true; offGroundTime = 0.0f; } } justjumped = false; bool TraceBlocked; FVector newlocation = UpdatedComponent->GetComponentLocation(); FHitResult TraceHitResult; TraceBlocked = GetWorld()->LineTraceSingleByChannel(TraceHitResult, ShapeTraceResult.ImpactPoint + 1.0f*FVector::UpVector, ShapeTraceResult.ImpactPoint - 10.0f*FVector::UpVector, ECC_Visibility,Params); if (TraceHitResult.Normal.Z > minnormalz) { enforcementtimer = -1.0f; } if (onground) { if (TraceBlocked) { newlocation.Z = TraceHitResult.ImpactPoint.Z + playerhalfheight; // 50 GetWorld()->LineTraceSingleByChannel(TraceHitResult, ShapeTraceResult.ImpactPoint + 1.0f*FVector::UpVector, ShapeTraceResult.ImpactPoint - 10.0f*FVector::UpVector, ECC_Visibility,Params); FloorNormal = TraceHitResult.ImpactNormal; } SafeMoveUpdatedComponent(newlocation - UpdatedComponent->GetComponentLocation(), UpdatedComponent->GetComponentRotation(), true, HitResult); SlideAlongSurface(newlocation - UpdatedComponent->GetComponentLocation(), 1.0 - HitResult.Time, HitResult.Normal, HitResult); } };
void AEnemy::ChangeDir() { //Check which sides are clear FCollisionQueryParams Params; Params.AddIgnoredActor(this); //Debug draw lines //const FName TraceTag("MyTraceTag"); //GetWorld()->DebugDrawTraceTag = TraceTag; //Params.TraceTag = TraceTag; FHitResult HitF; FHitResult HitL; FHitResult HitR; float range = 150.0f; GetForward(); FVector Start = StaticMesh->GetComponentLocation(); FVector EndF = Start + forward*range/3.0f; FVector EndL = Start + forward.RotateAngleAxis(90.0f, FVector::UpVector)*range; FVector EndR = Start + forward.RotateAngleAxis(-90.0f, FVector::UpVector)*range; bool bHitF = GetWorld()->LineTraceSingleByChannel(HitF, Start, EndF, ECC_WorldStatic, Params); bool bHitL = GetWorld()->LineTraceSingleByChannel(HitL, Start, EndL, ECC_WorldStatic, Params); bool bHitR = GetWorld()->LineTraceSingleByChannel(HitR, Start, EndR, ECC_WorldStatic, Params); //Make sure hit results from level objects if (bHitF) { bHitF = HitF.GetActor()->ActorHasTag(TEXT("level")); } if (bHitL) { bHitL = HitL.GetActor()->ActorHasTag(TEXT("level")); } if (bHitR) { bHitR = HitR.GetActor()->ActorHasTag(TEXT("level")); } TArray<int> dummy; dummy.Add(0); if (!bHitL) { dummy.Add(1); } if (!bHitR) { dummy.Add(2); } int randInt = FMath::Trunc(FMath::RandRange(0.0f, (float)dummy.Num())); if (randInt > dummy.Num() - 1) { randInt = dummy.Num() - 1; } int randResult = dummy[randInt]; switch (randResult) { case 0: if (bHitF) { ufoVelocity = -forward*velMultiplier; } break; case 1: ufoVelocity = forward.RotateAngleAxis(90.0f, FVector::UpVector)*velMultiplier; break; case 2: ufoVelocity = forward.RotateAngleAxis(-90.0f, FVector::UpVector)*velMultiplier; break; } GetForward(); }
void ALaser::checkLaserCollisions(float dt) { FHitResult hit; FCollisionQueryParams queryParam; queryParam.bFindInitialOverlaps = false; queryParam.bReturnFaceIndex = true; FCollisionObjectQueryParams objectParam = objectParam.DefaultObjectQueryParam; if ( !canHitBall ) queryParam.AddIgnoredActor( GetWorld()->GetGameState<AProjectTapGameState>()->GetPlayer() ); auto pos = GetActorLocation(); auto rayStart = pos + dir * 5.0f; auto laserVector = dir * length; auto laserEmitter = laserParticle->EmitterInstances[0]; //ray cast to see if laser hits anything GetWorld()->LineTraceSingleByObjectType(hit,rayStart, pos + laserVector, objectParam,queryParam); auto hitActor = hit.Actor.Get(); if (hitActor != nullptr) { currHitPoint = hit.ImpactPoint; if(!laserSparkParticle->bIsActive) laserSparkParticle->ActivateSystem(); //kills ball if laser hits it auto ball = Cast<ABallPawn>(hitActor); if (ball != nullptr) { ball->Kill(); laserEmitter->SetBeamTargetPoint(hit.ImpactPoint, 0); KillSubLaser(); } else { //if not set laser end point laserEmitter->SetBeamTargetPoint(hit.ImpactPoint, 0); bool typeFound = false; //if hits deflective tile then spawn a new laser object auto tile = Cast<ADeflectiveTile>(hitActor); bool isFrame = false; if (tile != nullptr) { typeFound = true; TArray<USceneComponent*> Children; tile->frameCollisionsComponent->GetChildrenComponents(true, Children); for(int i = 0; i < Children.Num() && typeFound ; ++i) { // printonscreen(hit.Component.Get()->GetName()); // printonscreen(Children[i]->GetName()); if(hit.Component.Get() == Children[i]) { typeFound = false; isFrame = true; } } //cut the laser length to make sure new sub laser start doesn't hit the same object if (typeFound && CanSpawnSubLaser()) SpawnSubLaser(hit.ImpactPoint + hit.ImpactNormal * 10.0f, hit.ImpactNormal); } //if sub laser already exists then keep updating its rotation and position auto subLaserExistsHitDeflectiveTile = currentDepth < MAX_DEPTH && nextLaser != nullptr && tile != nullptr; if (subLaserExistsHitDeflectiveTile) { auto incomingVector = hit.ImpactPoint - GetActorLocation(); //if the incoming vector's angle is too small then kill sublasers to avoid laser flickering auto dot = FVector::DotProduct(-incomingVector.GetSafeNormal(), hit.ImpactNormal); auto angle = FMath::RadiansToDegrees(FMath::Acos(dot)); if (angle < 70.0f) { auto newDir = FMath::GetReflectionVector(incomingVector, hit.ImpactNormal); auto start = hit.ImpactPoint + newDir * 2.0f; nextLaser->SetActorLocation(hit.ImpactPoint); nextLaser->dir = newDir.IsNormalized() ? newDir : newDir.GetSafeNormal(); nextLaser->laserParticle->EmitterInstances[0]->SetBeamSourcePoint(hit.ImpactPoint, 0); nextLaser->laserParticle->EmitterInstances[0]->SetBeamTargetPoint(start + newDir * length, 0); } else { KillSubLaser(); } } //if the laser hits turret then kills it if (!typeFound) { auto turret = Cast<ATurretPawn>(hitActor); if (turret != nullptr) { typeFound = true; turret->Damage(2.0f); } } APortalTile* portal = nullptr; if (!typeFound) { portal = Cast<APortalTile>(hitActor); if (CanSpawnSubLaser() && portal != nullptr) { typeFound = true; auto relativePos = hit.ImpactPoint - hit.GetComponent()->GetComponentLocation(); currHitPoint = relativePos + portal->GetActorLocation(); SpawnSubLaser(currHitPoint, hit.ImpactNormal); } } auto subLaserExistsHitPortalTile = currentDepth < MAX_DEPTH && nextLaser != nullptr && portal != nullptr; if (subLaserExistsHitPortalTile) { FVector newSourcePos; portal->GetLaserPortalTransportedLocation(hit.GetComponent(), nextLaser->dir, newSourcePos); nextLaser->SetActorLocation(newSourcePos); nextLaser->laserParticle->EmitterInstances[0]->SetBeamSourcePoint(newSourcePos, 0); nextLaser->laserParticle->EmitterInstances[0]->SetBeamTargetPoint(newSourcePos + nextLaser->dir * length, 0); } bool notHitDeflectiveTile = tile == nullptr || isFrame; bool notHitPortal = portal == nullptr; if (notHitDeflectiveTile && notHitPortal) { KillSubLaser(); } } laserSparkParticle->SetWorldLocation(currHitPoint); laserSparkParticle->SetWorldRotation(FVector(currHitPoint - GetActorLocation()).GetSafeNormal().Rotation().Quaternion()); } else { currHitPoint = laserVector; laserEmitter->SetBeamTargetPoint(pos + currHitPoint, 0); laserSparkParticle->SetWorldLocation( pos + currHitPoint ); laserSparkParticle->SetWorldRotation( FVector( (pos + currHitPoint) - GetActorLocation() ).GetSafeNormal().Rotation().Quaternion() ); KillSubLaser(); } //only root laser can have an emitter mesh if (currentDepth != 0) { //update laser emitter rotation mesh->SetVisibility(false); } else { mesh->SetWorldRotation(dir.Rotation()); } }
// Check for bullet collisions void AMurphysLawCharacter::ComputeBulletCollisions() { // Only look for pawns FCollisionObjectQueryParams CollisionObjectQueryParams; CollisionObjectQueryParams.AddObjectTypesToQuery(ECollisionChannel::ECC_PhysicsBody); CollisionObjectQueryParams.AddObjectTypesToQuery(ECollisionChannel::ECC_Destructible); CollisionObjectQueryParams.AddObjectTypesToQuery(ECollisionChannel::ECC_WorldStatic); // Remove self from query potential results since we are the first to collide with the ray FCollisionQueryParams RayQueryParams; RayQueryParams.AddIgnoredActor(this); // Ray starting coordinates const FVector CollisionRayStart = GetFirstPersonCameraComponent()->GetComponentLocation(); const FVector CollisionRayInitialDirection = GetFirstPersonCameraComponent()->GetComponentTransform().GetRotation().GetAxisX(); // Group damage of touched objects together const float MaxFragmentDeviationRadian = FMath::DegreesToRadians(GetEquippedWeapon()->GetMaxFragmentDeviationAngle(IsCharacterAiming)); bool AtLeastOneHit = false; // Trace lines to detect pawn for (int32 i = 0; i < GetEquippedWeapon()->GetNumberOfEmittedFragments(); ++i) { // Ray ending coordinates const FVector CollisionRayAngledDirection = FMath::VRandCone(CollisionRayInitialDirection, MaxFragmentDeviationRadian); const FVector CollisionRayEnd = CollisionRayStart + (CollisionRayAngledDirection * GetEquippedWeapon()->GetMaxTravelDistanceOfBullet()); FHitResult CollisionResult; bool HasHit = GetWorld()->LineTraceSingleByObjectType(CollisionResult, CollisionRayStart, CollisionRayEnd, CollisionObjectQueryParams, RayQueryParams); if (HasHit) { // Simple damage amount considering the distance to the target depending on the bone hit float DeliveredDamage = GetDeliveredDamage(CollisionResult); FPointDamageEvent CollisionDamageEvent(DeliveredDamage, CollisionResult, CollisionRayAngledDirection, UDamageType::StaticClass()); // If the actor we hit is a hittable actor and an enemy, we have at least one hit so we'll show the Hit Marker if (IsHittableActor(CollisionResult.GetActor()) && !MurphysLawUtils::IsInSameTeam(CollisionResult.GetActor(), this)) { AtLeastOneHit = true; } if (Role == ROLE_Authority) { CollisionResult.GetActor()->TakeDamage(DeliveredDamage, CollisionDamageEvent, GetController(), this); } else { Server_TransferDamage(CollisionResult.GetActor(), DeliveredDamage, CollisionDamageEvent, GetController(), this); } } } // If there was at least one hit, we show the HitMarker if (AtLeastOneHit) { auto MyController = Cast<AMurphysLawPlayerController>(GetController()); if (MyController != nullptr && MyController->GetHUDInstance() != nullptr) { MyController->GetHUDInstance()->ShowHitMarker(); } } }
//Verifie le lineOfSight entre le point d'origine de la lumiere et la cible bool ABaseLight::CheckEnemyLineOfSight(AActor* actor){ const FName LightTraceDebug("LightTrace"); GetWorld()->DebugDrawTraceTag = LightTraceDebug; FVector start = this->GetActorLocation(); FVector finish = actor->GetActorLocation(); FHitResult hitResult; FCollisionQueryParams queryParams; FCollisionResponseParams responseParams; queryParams.AddIgnoredActors(ArrayOfActorsExclusion); // EFFECTUE LES TRACES DANS LE JEU (DEBUG) //queryParams.TraceTag = LightTraceDebug; //On otient l'origine du mesh l'ennemi dans le monde et ses points max/mins du mesh dans box extent ANightmare_BaseClass* enemy = Cast<ANightmare_BaseClass>(actor); if (enemy!=NULL) { FVector BoxExtent = enemy->GetMesh()->Bounds.BoxExtent; FVector Origin = enemy->GetMesh()->Bounds.Origin; //Point du mesh dans le monde à l'extrémité haut et bas FVector finishUp = Origin + FVector(0.0f, 0.0f, BoxExtent.Z); FVector finishDown = Origin + FVector(0.0f, 0.0f, -BoxExtent.Z); //Point du mesh dans le monde à l'extrémité avant et derrière FVector finishForward = Origin + FVector(-BoxExtent.X, 0.0f, 0.0f); FVector finishBackward = Origin + FVector(BoxExtent.X, 0.0f, 0.0f); //Point du mesh dans le monde à l'extrémité gauche et droite FVector finishLeft = Origin + FVector(0.0f, -BoxExtent.Y, 0.0f); FVector finishRight = Origin + FVector(0.0f, BoxExtent.Y, 0.0f); //Raycast vers l'origine bool isOriginBlocked = GetWorld()->LineTraceSingleByChannel(hitResult, start, Origin, ECC_WorldStatic, queryParams, responseParams); //Raycast vers le dessus du mesh et le bas du mesh bool isUpBlocked = GetWorld()->LineTraceSingleByChannel(hitResult, start, finishUp, ECC_WorldStatic, queryParams, responseParams); bool isDownBlocked = GetWorld()->LineTraceSingleByChannel(hitResult, start, finishDown, ECC_WorldStatic, queryParams, responseParams); //Raycast vers l'avant du mesh et l'arrière bool isForwardBlocked = GetWorld()->LineTraceSingleByChannel(hitResult, start, finishForward, ECC_WorldStatic, queryParams, responseParams); bool isBackWardBlocked = GetWorld()->LineTraceSingleByChannel(hitResult, start, finishBackward, ECC_WorldStatic, queryParams, responseParams); //Raycast vers la gauche et la droite du mesh bool isLeftBlocked = GetWorld()->LineTraceSingleByChannel(hitResult, start, finishLeft, ECC_WorldStatic, queryParams, responseParams); bool isRightBlocked = GetWorld()->LineTraceSingleByChannel(hitResult, start, finishRight, ECC_WorldStatic, queryParams, responseParams); //Si un des raycasts n'est pas bloqué, alors on fait des dégâts if (!isOriginBlocked || !isUpBlocked || !isDownBlocked || !isForwardBlocked || !isBackWardBlocked || !isLeftBlocked || !isRightBlocked){ //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Ray Passed!")); return true; } else{ //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, TEXT("Ray Blocked!")); return false; } } return false; }
void ASCharacter::DropWeapon() { if (Role < ROLE_Authority) { ServerDropWeapon(); return; } if (CurrentWeapon) { FVector CamLoc; FRotator CamRot; if (Controller == nullptr) { return; } /* Find a location to drop the item, slightly in front of the player. Perform ray trace to check for blocking objects or walls and to make sure we don't drop any item through the level mesh */ Controller->GetPlayerViewPoint(CamLoc, CamRot); FVector SpawnLocation; FRotator SpawnRotation = CamRot; const FVector Direction = CamRot.Vector(); const FVector TraceStart = GetActorLocation(); const FVector TraceEnd = GetActorLocation() + (Direction * DropWeaponMaxDistance); /* Setup the trace params, we are only interested in finding a valid drop position */ FCollisionQueryParams TraceParams; TraceParams.bTraceComplex = false; TraceParams.bReturnPhysicalMaterial = false; TraceParams.AddIgnoredActor(this); FHitResult Hit; GetWorld()->LineTraceSingleByChannel(Hit, TraceStart, TraceEnd, ECC_WorldDynamic, TraceParams); /* Find farthest valid spawn location */ if (Hit.bBlockingHit) { /* Slightly move away from impacted object */ SpawnLocation = Hit.ImpactPoint + (Hit.ImpactNormal * 20); } else { SpawnLocation = TraceEnd; } /* Spawn the "dropped" weapon */ FActorSpawnParameters SpawnInfo; SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; ASWeaponPickup* NewWeaponPickup = GetWorld()->SpawnActor<ASWeaponPickup>(CurrentWeapon->WeaponPickupClass, SpawnLocation, FRotator::ZeroRotator, SpawnInfo); if (NewWeaponPickup) { /* Apply torque to make it spin when dropped. */ UStaticMeshComponent* MeshComp = NewWeaponPickup->GetMeshComponent(); if (MeshComp) { MeshComp->SetSimulatePhysics(true); MeshComp->AddTorque(FVector(1, 1, 1) * 4000000); } } RemoveWeapon(CurrentWeapon, true); } }
void AKIMCharacter::CheckTraceDistance() { if (IsInRoationState) { return; } FHitResult outHit; FCollisionQueryParams params; params.AddIgnoredActor(this); params.AddIgnoredActor(PickedUpItem); FVector TraceStart = CameraComponent->GetComponentLocation(); FVector TraceEnd = TraceStart + (CameraComponent->GetForwardVector() * InteractionDistance); GetWorld()->LineTraceSingleByChannel(outHit, TraceStart, TraceEnd, ECollisionChannel::ECC_PhysicsBody, params); if (outHit.GetActor() != NULL && outHit.GetActor()->GetClass()->IsChildOf(AKIMInteractionActor::StaticClass())) { if (((AKIMInteractionActor*)outHit.GetActor())->InteractionType != StoredType){ StoredType = ((AKIMInteractionActor*)outHit.GetActor())->InteractionType; SwitchIconState(StoredType); } } else { if (StoredType != EKIMInteractionTypes::NONE) { StoredType = EKIMInteractionTypes::NONE; SwitchIconState(StoredType); } } }