Download

How to exchange datas between actor c++ class

Hello, I’m in my project code and I’ve several AActor subclasses for my actors.
But How may I exchange data between them ?
In other words, is there a way to get, from an AActor subclass, the list of all AActor instances in the game. By the name, I will then be able to get the instance I’m searching for and call a method.

Thank you very much !!

From what I’ve seen before, this functionality is not present in UE4 by default. What you can do is iterate through the list of the actors in a level and retrieve the ones you need. Another option would be to add the actors which you spawn to your own list, hence, you can easily access them when needed.

OK, thank you.
So I need to find the current ULevel instance.
I found in the source code of UE4 :

  • How to get the WorldList with WorldList = GEngine->GetWorldContexts();
  • And after I can scan all the UWorld instances to find the AActor instance i need.

Is there a more elegant way to directly get the current ULevel instance ?

You want the actor iterators. Once again, Rama to the rescue!

:slight_smile:
“actor iterators” smells good !!

Nice! Allows quick template specification - filtering - as well! Had no idea, thanks for sharing :slight_smile:

Just a small note, if you are considering iterating often, to make things a little more efficient, here is what I recommend:

On the constructor - or better yet, on the initializer/spawn function - make a call to a function - probably store it in the current Game mode - which adds your actor to a map. Something like this :



static const TMap<FString, TMap<FString, UObject*>> ActiveObjectListing;

static void AddObject(UObject* add)
{
 FString className = add->GetClass()->GetName();

 if(!ActiveObjectListing.Get(className))
   ActiveObjectListing.Add(className,new TMap<FString, UObject*>);
 ActiveObjectListing.Get(className).Add(handler, add);


Something like that - that wasn’t tested at all, just wrote it here so there might be problems.

Just keep in mind you’ll have to cleanup (delete) the initialized TMaps - second-level TMaps.

The handlers are optional, if you want to manipulate/ know exactly which instance is there, you just add the instance name where the handler is. Or if you don’t want manipulation, just make it a TArray (the second-level TMap).

Lastly, don’t forget to remove them from the map when they unspawn :slight_smile:

Do you mean exchange data locally or via networking?

If we assume it’s locally:
If the data exchanges happen sporadically throughout running the game, iterating through all actors of the world each time isn’t very efficient.
Why not, when your actors have been instantiated, you give them an ID?
Say for example you make a class UActorIDHandler.

UActorIDHandler has lists of references to your actors:



TArray<AActorSubclassTypeA> aTypeAActors;
...
TArray<AActorSubclassTypeZ*> aTypeZActors;


Function for storing and assigning an ID to an actor:



uint32 RegisterActorTypeA(AActorSubclassTypeA* ActorReference) {
aTypeAActors.Add(ActorReference);
return aTypeAActors.Num() -1 ;
}


aTypeAActors.Num()-1 will be the index of the array in which the reference to the actors resides.

In the constructor of a new actor you can just get an ID by calling the ActorIDHandler with



uint32 MyID = RegisterTypeXActor(this);


You can also get the reference of another actor by simply retreiving it from the array with his ID



ATypeBActor* MyFriendTheTypeBActor = ActorIDHandler->aTypeBActors[MyFriendsID];


Edit: This is just a naive solution, UE MOST likely already has a solution for this. But I’m pretty new to the engine. You might wanna check out Tags or FNames though.

Same concept as mine, you should check Mpalacio’s implementation, might make more sense for you :slight_smile:

Ah sorry, you were practically proposing the same thing :slight_smile:

Oh please not a problem! Its good to see different implementations of the same concept, there is always room for learning and improving from others! :slight_smile: