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; } } } } }
AEyeXActorBase* AEyeXPlayerController::FindBySweep(FHitResult& OutHit, const FSceneView* const View, const FVector2D& GazePoint, const FCollisionObjectQueryParams& ObjectParams, const FCollisionQueryParams& TraceParams) { if (SweepIntervals <= 1) { UE_LOG(LogEyeX, Warning, TEXT("Invalid value for SweepIntervals: %i. Must be greater than 0."), SweepIntervals); return nullptr; } UWorld* World = GetWorld(); if (!World) return nullptr; FVector Start, Direction; View->DeprojectFVector2D(GazePoint, Start, Direction); const float TanFOVScaled = GetTanOfFOVAngleScaled(); // Perform sweeps const float DeltaDistance = MaxDistance / SweepIntervals; const FVector DeltaDirection = DeltaDistance * Direction; float CurrentDistance = DeltaDistance / 2; FCollisionShape Shape; AEyeXActorBase* EyeXActor = nullptr; for (int i = 0; i < SweepIntervals; ++i) { const FVector End = Start + DeltaDirection; const float Radius = (i == 0) ? 0.0f : TanFOVScaled * CurrentDistance; // Depends on the view frustrum, size of the screen and the distance. Shape.SetSphere(Radius); if (World->SweepSingleByObjectType(OutHit, Start, End, FQuat::Identity, ObjectParams, Shape, TraceParams)) { EyeXActor = Cast<AEyeXActorBase>(OutHit.GetActor()); break; } Start = End; CurrentDistance += DeltaDistance; } VisualizeHit(bVisualizeDetection, World, OutHit, Shape.GetSphereRadius()); VisualizeGazePoint(bVisualizeDetection, World, Start); return EyeXActor; }
EBTNodeResult::Type UBTTask_Escape::ExecuteTask(UBehaviorTreeComponent& OwnedTree, uint8* Node) { AWolfAIController* Controller = Cast<AWolfAIController>(OwnedTree.GetAIOwner()); if (!Controller) { GLog->Log("Controller fail"); return EBTNodeResult::Failed; } FName SensedTargetKey = "SensedTarget"; AMyCharacter_FirstTry* Caveman = Cast<AMyCharacter_FirstTry>(OwnedTree.GetBlackboardComponent()->GetValueAsObject(SensedTargetKey)); if (Caveman) { TArray<FHitResult> HitResults; //Start and End Location of the capsule FVector StartLocation = Caveman->GetActorLocation(); FVector EndLocation = StartLocation; EndLocation.Z += Caveman->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight() / 2; //Collision Channel ECollisionChannel ECC = ECollisionChannel::ECC_WorldDynamic; //Collision Shape FCollisionShape CollisionShape; //Making Collision in sphere CollisionShape.ShapeType = ECollisionShape::Sphere; CollisionShape.SetSphere(350); //Sweeping for possible escape nodes if (Caveman->GetWorld()->SweepMultiByChannel(HitResults, StartLocation, EndLocation, FQuat::FQuat(), ECC, CollisionShape)) { //DrawDebugSphere(Caveman->GetWorld(), ((EndLocation - StartLocation) / 2) + StartLocation, CollisionShape.GetSphereRadius(), 100, FColor::Green, true); TArray<AActor*> AllPathNodes; UGameplayStatics::GetAllActorsOfClass(Caveman->GetWorld(), APathNode::StaticClass(), AllPathNodes); APathNode* NextNode; NextNode = Cast<APathNode>(AllPathNodes[FMath::RandRange(0, AllPathNodes.Num() - 1)]); //Finding next possible node while (NextNode->bIsCurrentlyOccupied && AllPathNodes.Contains(NextNode)) { NextNode = Cast<APathNode>(AllPathNodes[FMath::RandRange(0, AllPathNodes.Num() - 1)]); GLog->Log("Fear success"); } //Occupy the node NextNode->bIsCurrentlyOccupied = true; //Set the new node in the blackboard OwnedTree.GetBlackboardComponent()->SetValue<UBlackboardKeyType_Object>(BlackboardKey.GetSelectedKeyID(), NextNode); //OwnedTree.GetBlackboardComponent()->SetValue<UBlackboardKeyType_Object>(Bl) GLog->Log("Success after while"); return EBTNodeResult::Succeeded; } } GLog->Log("General Fail"); return EBTNodeResult::Failed; }