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"

Returning a reference from a Thread Task

I'm multi-threading our AI to choose the closest actor. To do this I'm trying to use a task on the task graph since there can be hundreds of units doing this at once.

I created a class to house all the information for the thread. It looks like this.

 struct FUnitLocationData
 {
     FVector myLocation;
     TArray<AActor*> otherUnits;
     AController *MyAIController;
     
     FUnitLocationData()
     {
         myLocation = { 0,0,0 };
         otherUnits.Empty();        
     }
 };
 
 
 class FUnitUpdateObject
 {
 public:
     AController *AIController;
     AActor* ClosestActor;
     float distanceToActor;
     FGraphEventArray UnitUpdateThread_CompletionEvents;
 
     bool TasksCompleted();
 
     void FindClosestEnemy();
 };

My testing shows that I can't use references at all because if the unit dies and the thread continues, I get null references. All I need to do is set 2 blackboard values.

 BBComp->SetValueAsObject("ClosestTarget", UnitUpdater.ClosestActor);
 BBComp->SetValueAsFloat("DistanceToTarget", this->UnitUpdater.distanceToActor);

But because the AIController owning the thread is destroyed, The thread crashes the game. Where should I be storing variables that makes them unique to the querying unit but owned by the querying unit.

Product Version: UE 4.13
Tags:
more ▼

asked Oct 18 '16 at 07:27 PM in C++ Programming

avatar image

Justin.Dooley
2.1k 104 72 163

avatar image PasteDog Oct 19 '16 at 08:21 AM

I am not experienced in multi threading, but could you have the owner keep track if he is running a thread or not? And if he is he should wait until completion and then destroy itself.

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

1 answer: sort voted first

In UE4 all the gameplay code (including AI) is expected to live on the GameThread. You'll get yourself into a lot of trouble if you try calling functions on gamethread-bound objects outside of gamethread (unless you really, relly know what you're doing).

Ideally all the computation you'd like to do outside of game-thread should be abstracted from any UObject code. You should gather all the information you'd might want to ask off-gamethread, pack it into your tasks, and have tasks operate on that data, without any need to ask for additional information. This has lots of benefits (apart from being thread-safe) - it's a lot more efficient to ask actor X for a location, store it and reuse it than have every separate task ask X for its location (even if it was possible).

Alternatively you can create a gamethread-side model of the world and use thread shared pointers (`TSharedPtr< FYourType, ESPMode::ThreadSafe>`) or references (`TSharedRef< FYourType, ESPMode::ThreadSafe>`) to access it from threads - again, note that TSharedPtr doesn't work with UObjects, you'll need to switch over to regular C++ to make it work safely and reliably.

Cheers,

--mieszko

more ▼

answered Oct 19 '16 at 12:44 PM

avatar image

MieszkoZ STAFF
7.3k 223 57 412

avatar image Justin.Dooley Oct 19 '16 at 02:01 PM

Hi Mieszko, Your second point of gathering all the data and doing the calculations to the side is exactly what I'd like to do. The trouble is updating the actors information after the tread is complete. I'm not sure how to associate the result with the appropriate actor.

After sleeping on it maybe I can use a TMap Where the Actor Reference is never used in the thread and only there to associate LocationData with the actor when the task completes. It kind of feels like I'm flirting with the death a bit but we will see.

avatar image MieszkoZ STAFF Oct 19 '16 at 07:26 PM

Yeah, maps or array that translate index to an actor. It's not rocket science, it's just coding under constraints :)

avatar image Justin.Dooley Oct 21 '16 at 04:35 PM

Just wanted to say thanks your your assistance. I managed to shave off a very substantial 100ms from my game thread. Apparently 300 AIs fighting in an all out brawl is a bit heavy on the game thread.

(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