x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

Closest Enemy Targeting

Hello! I currently am making a game with UE4 where i have AI players as well as 1 local player. I'm trying to make a Team Deathmatch gamemode. I've got everything done but i have one problem. I need my AIController class to target the nearest 'enemy' (the enemy pawns have teams on them) so basically the closest actor of my pawn class that isn't on the AiController's team. What is an elegant way of implementing this?

What i do so far is spawn all controllers and pawns in the gamemode class and store references to those on every spawned pawn. Then once one dies a delegate fires off removing the killed pawn reference from all the pawns that are still alive. Vice versa for re-spawning. Then each tick (which is Totally gross and i know this is wrong) all the pawns iterate through their respective enemy pawn references and get the distance to the referenced pawns and return whatever pawn had the closest distance.

Before asking this here. I did a lot of searches on the web for solutions to this problem but the closest i could get is a tab targeting system you can buy on in the workshop.

I'm fairly new to the entirety of developing games (started studying C++ and UE4 2 months ago). So if there is a obvious solution, I am very sorry.

Looking forward from hearing form you, thanks in advance Ruben Versavel

Edit:

I've taken a new approach. I iterate through all objects of class ATank every frame and get their distance and compare it to the previous calculated distance. when its a smaller distance it sets the new pending target. This does it fine. The problem is when a tank's hp reaches 0 it is destroyed

 ATank* ATankAIController::GetClosestEnemyTank()
 {
     ATank* PendingTarget = TargetTank;
     for (TObjectIterator<ATank> Itr; Itr; ++Itr) //for all tanks in the world
     {
         if (Itr->GetTeam() != Team)
         {
             if (PendingTarget == nullptr) { PendingTarget = *Itr; continue; }
             if (Itr->GetDistanceTo(PossessedTank) < PendingTarget->GetDistanceTo(PossessedTank))
             {
                 PendingTarget = *Itr;
             }
         }
     }
     return PendingTarget;
 }
 
 
 float ATank::TakeDamage(float DamageAmount, FDamageEvent const & DamageEvent, AController * EventInstigator, AActor * DamageCauser)
 {
     int32 DamagePoints = FPlatformMath::RoundToInt(DamageAmount);
     int32 DamageToApply = FMath::Clamp<int32>(DamagePoints, 0, TankCurrentHealth);
 
     TankCurrentHealth -= DamageToApply;
 
     if (TankCurrentHealth == 0) 
     { 
         OnTankDeathEvent.Broadcast(this); 
     }
     return DamageToApply;
 }
 
 void ATankAIController::OnTankDeath(AActor* TankThatDied)
 {
     UnPossess();
     Spawnpoint->bInUse = false;
     Cast<ATeamDeatmatchGameMode>(GetWorld()->GetAuthGameMode())->OnRespawnRequestEvent.Broadcast(this);
     TankThatDied->Destroy();
 }

The problem is there are 12 tanks in total. When one dies at that split moment where in the iteration the distance gets calculated i get an exception and the game crashes. At least that's what i think it is...

Here are the catches of the exception by Visual Studio and crash report of Unreal.

VSError1 VSError2

Access violation - code c0000005 (first/second chance not available)

UE4Editor_Engine!AActor::GetDistanceTo() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\actor.cpp:4413] UE4Editor_BattleTank_727!ATankAIController::GetClosestEnemyTank() [f:\unreal projects\battle-tank\battletank\source\battletank\private\tankaicontroller.cpp:70] UE4Editor_BattleTank_727!ATankAIController::Tick() [f:\unreal projects\battle-tank\battletank\source\battletank\private\tankaicontroller.cpp:37] UE4Editor_Engine!AController::TickActor() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\leveltick.cpp:408] UE4Editor_Engine!FActorTickFunction::ExecuteTick() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\actor.cpp:134] UE4Editor_Engine!FTickFunctionTask::DoTask() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\ticktaskmanager.cpp:273] UE4Editor_Engine!TGraphTask::ExecuteTask() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\core\public\async\taskgraphinterfaces.h:829] UE4Editor_Core!FNamedTaskThread::ProcessTasksNamedThread() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\core\private\async\taskgraph.cpp:665] UE4Editor_Core!FNamedTaskThread::ProcessTasksUntilQuit() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\core\private\async\taskgraph.cpp:574] UE4Editor_Core!FTaskGraphImplementation::WaitUntilTasksComplete() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\core\private\async\taskgraph.cpp:1355] UE4Editor_Engine!FTickTaskSequencer::ReleaseTickGroup() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\ticktaskmanager.cpp:542] UE4Editor_Engine!FTickTaskManager::RunTickGroup() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\ticktaskmanager.cpp:1449] UE4Editor_Engine!UWorld::RunTickGroup() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\leveltick.cpp:770] UE4Editor_Engine!UWorld::Tick() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\engine\private\leveltick.cpp:1429] UE4Editor_UnrealEd!UEditorEngine::Tick() [d:\build++ue4+release-4.19+compile\sync\engine\source\editor\unrealed\private\editorengine.cpp:1693] UE4Editor_UnrealEd!UUnrealEdEngine::Tick() [d:\build++ue4+release-4.19+compile\sync\engine\source\editor\unrealed\private\unrealedengine.cpp:401] UE4Editor!FEngineLoop::Tick() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\launch\private\launchengineloop.cpp:3339] UE4Editor!GuardedMain() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\launch\private\launch.cpp:166] UE4Editor!GuardedMainWrapper() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:144] UE4Editor!WinMain() [d:\build++ue4+release-4.19+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:223] UE4Editor!__scrt_common_main_seh() [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:253] kernel32 ntdll

Product Version: UE 4.19
Tags:
more ▼

asked Jul 29 '18 at 01:54 PM in C++ Programming

avatar image

PurrPaw
43 3 4

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

If you are looking for the most "elegant" way I would strongly suggest you go with the already provided AI infrastructure in UE4. Namely Behavior Trees and Blackboards. You can also find a ton of resources on Youtube and in Documentation regarding these.

They are very flexible and highly* optimized. Keep in mind that even if you want to go "Your way" it would be greatly beneficial to check the code for these classes as that will provide insight on how they hook up to controllers and movement components.

*They are sometimes slower if you need something small and trivial.

more ▼

answered Jul 30 '18 at 10:04 AM

avatar image

dZh0
1.3k 6 5 9

avatar image PurrPaw Jul 30 '18 at 02:59 PM

Thank you a lot for your response! I will make sure i look into this and at the moment i get the problem solved i will mark this as the correct answer.

avatar image PurrPaw Oct 25 '18 at 08:03 AM

Hey this might be late marked as the correct answer but i did my research into the AI infractructure that UE4 Offers like you said and i managed to get it working. The crash does not happen anymore since the behaviour trees have this passive try-catch thing going on. For those with a similar issue: I made a custom behaviour node from code and then added it inside my behaviour tree. For the closest target i used world Querying then sorting it by distance.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

For your crash problem:

Can you please try using Actor Iterator instead of Object Iterator and say how it went. Actor terators are supposed to be safe.

 for (TActorIterator<ATank> Itr(GetWorld()); Itr; ++Itr){...};

Happy coding :)

more ▼

answered Aug 01 '18 at 03:46 PM

avatar image

dZh0
1.3k 6 5 9

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question