Get all actors of class vs Get all actors with tag

This.

If the question is regarding Interface vs casting: They are not the same. Interfaces are usually use when communication is needed across many differente classes. Casting is to know the reference you have is of a specific type or inherited from to do stuff with.

In both cases a reference is still needed to either check if it implements an interface (a type of casting if you will) and to check if its of a specific type (cast).

Using any of the Get nodes no matter how often won’t prevent anything from getting destroyed. It just doesn’t work like that.

This post explains hard references better than I ever could: Blueprints can develop a hard reference dependancy chain, but C++ derived classes do not? - #10 by Ari_Epic



Please feel free to ask anything else.

2 Likes

Yes, this is what I don’t understand. Many people suggest using interfaces over casting, because supposedly it’s better, but if you require an object reference for BOTH of these methods, then how are interfaces any less taxing on the memory? Especially since you have to search for, and load a bunch of actors into memory in order to reference them.

This is the specific thing that I am trying to understand. @ClockworkOcean said that it depends on what is done with the actors when they are gotten back. So what exactly does this mean? Does it mean that when I plug the actors I’ve found into that message pin, that it uses hard references to message to all of those actors, or are these just pointers that do not fully load in the actor?

Im just trying to understand what the benefit to using interfaces is, over the casting.

1 Like

Actor references don’t matter. They are an engine primitive.

If you get that array of actors, and loop down it, trying to figure out the type of each actor by casting, every type you compare against is permanently loaded as part of this code, and all those types are loaded as part of any level using the code. Even if you never actually run the code.

If, you loop down that list of actors, and talk to them with an interface, there is no overhead. Because you haven’t loaded any other classes.

So that’s a major benefit of interfaces.

The other major benefit, is you don’t need to know the class to make the call. And you can code hundreds of classes to understand the meaning of the interface call ‘execute’, because it can mean a different thing to each class.

A door BP: Open ( close )
A car BP: Start ( stop )
A button BP: Press
A Gun: Fire ( or reload )
and so on…

All with one interface call.

2 Likes

@pezzott1 @ClockworkOcean Thank you so much for the help and taking the time to explain all of this stuff to me!

1 Like

And I’ts the same thing that applies to Get All Actors With Tag so long as it’s being used with an interface like I did in my example image, right?

1 Like

Any kind of actor variables are fine :slight_smile:

A good example is overlap or line trace. They stock Epic nodes always just give you an actor. You can then immediately communicate using an interface. No casting needed.

Casting actually only has one real use, and that is determining the type of an actor ( and possibly reinterpreting the type in the hierarchy ). The rest of the use you see everywhere is a sort of ‘stabilizer wheels’ for new coders :slight_smile:

1 Like

Hey @ClockworkOcean based on everything I’ve gathered from you and @pezzott1, It sounds like you’re saying that because the actors are already getting loaded into the world anyway at Runtime, the Get All Actors With Interface is simply acting as a scanner, searching for those actors that already exist (not really loading in the actors a second time) and creating pointers to those Actor objects. This is so that the message system (The Interface in this case) can know exactly where to locate those actors and send messages to them.

So it’s more like getting an address or creating a pathway so that these objects can be accessed for communication. I’m not exactly sure what Pezzott1 meant by “Weak Pointers”, but it does seem as though we are able to continue sending messages to an actor after it is returned from an array and stored (promoted) to a variable. It means that these references are not being garbage collected after some time and exist forever. But if it’s what you said, and that these are only simply acting as pointers, serving as an address to something that already exists within the world, then it shouldn’t have to be unloaded or garbage collected since it isn’t adding extra to the memory.

I understand that when using the Clear node, it’s not actually the actors that are being removed, but instead the references to those actors. Which again, according to what you have explained here, isn’t creating any overhead at all, no additional strain on the memory.

So if the Arrays are only storing a list of information, not really the object itself, isn’t it possible to grab a specific Actor from that array list so that I could narrow down the search? I would like to be able to know which index number the actor is associated with AND the name of the actor itself.

It also made me wonder if it’s possible to create an object reference from scratch to tell the game to directly search for that actor without having to search the entire world for it.

1 Like

It seems that you’re very hooked up on ‘get all actor’ nodes.

If you only want blueprint A to talk to actor B, then give blueprint A a variable which points to actor B. Why go searching through arrays?

Maybe if you can give an example of what you actually want to do, I can show you a good way to do it, and a terrible way?

@ClockworkOcean Well, based on the advice given here, I have come up with this:

The game first searches for all the actors using the “TEST” Interface, which are only 4 in this situation. Then, after it confirms that, the system then goes on to store these references within a variable so that they can later be accessed within the BP to send messages.

The reason why I run this check and compare it against the amount of actors within the world is because Get All Actors With Interface tends to return True Or Valid on Begin Play, even if none or only some of the actors are fully loaded. I think this happens because when you first load the game, it still takes time for the assets to become available to this node before they can be retrieved.

So GAAWI needs some time to repeat this process just in case. I couldn’t think of any other way to do this, since there is no other way to halt the execution of this node until the maximum number of actors are stored into the Array.

Aside from Get All Actors With Tag, Trying to specify an actor or widget directly to send a message to would obviously mean that I have to use a hard reference, something I am trying to avoid. Get All Actors With Tag also would not help with me with widgets.

What do you mean by “none or only some are are fully loaded”?

@pezzott1 So when I have used this node before with begin play, it will fully complete its execution even though it hasn’t first found all the actors in the game.

Here is the new set-up so that you can see what I’m talking about:

If the return is Valid (meaning the proper amount of actors returned is correct) then it will print the exact number of Actors, however if the return is invalid (in this case the value simply being lower than it should be) it will fail the execution and then return to the loop cycle until it retrieves the correct value. In my case, this thing fails 2 ticks before it finally gets the proper information:

Example 4

Now, it’s important to note that this example file is incredibly small, only using the default assets in Unreal. This isn’t some crazy big file where there is a ton of stuff to load in runtime. Despite that, the execution still happens before this node can retrieve all the information.

Edit: One solution I have done in the past is to put a delay node BEFORE the GAAWI node. But it’s much better I think to have a definitive value as opposed to guessing how long it should take for the process to get everything.

This would only make sense if the actors are streamed in or being spawned by another actor.

Before frame 1 all actors in the level should be initialized even if their BeginPlay() hasn’t run yet. it certainly does not take several frames for them to be added.


Also that Delay with 0.0 is being called twice in a single frame. :face_with_diagonal_mouth:

No it doesn’t, because you use an ACTOR reference :smiley:

1 Like

Yes, you are right. I have actors that get streamed into the level. I guess it all makes sense now based on what you’re saying. So is there any way to have this GAAWI node return the actors that haven’t yet been loaded into the world? You used the term “Initialized” so is there any way to force this so that I can get around the node delay problem?

Not that I know of, but async tasks should have a callback that can be used for this.

I apologize for that, I should have provided a separate example of what I was talking about.

Here I have two objects, one is a Cube and the other is a Sphere (Obviously):

They both implement the “TEST” Interface that I have created:

Interface Test

Now, I would like to send a message directly to the Sphere from the Cube, without having to use something like Get All Actors With Tag etc., so in this case I get a direct reference to the Sphere by creating an Actor Object variable like so:

With this approach, I am now able to plug it directly into the message to create a link between the two Actors.

However, as you can see here:

In doing so, I have just created a Hard Reference. This is what I was talking about before.

Based on your response, I can only assume that you meant that I should have used THIS instead:

But there is no way to insert an object into the slot, as it is completely greyed out here. Also, I am wondering what is the major difference between using both of these things? Even if I could get something plugged into there, wouldn’t it still result in the very same thing happening? A Hard ref?

YES, the second :smiley:

You set this variable on the cube blueprint IN THE LEVEL. How could you possibly set it before ( ie in the blueprint ), because there is no instance of the other blueprint at that moment.

Make the variable instance editable by clicking the eye icon, then you can set it in the level, by pointing with the dropper.

If there sphere doesn’t exist when the level starts ( is spawned for example ), then of course you can’t do this, and will need something like ‘get actors with tag’ etc.

If you only use actor types and interfaces, there will never be a hard reference between objects.

If you still can’t get it working, say so, and I will do an example, tomorrow, as I’m not at a machine rn.

@ClockworkOcean Alright, what you explained worked for me. However, before you responded back, I discovered something else. Apparently, if you use Soft Reference Actor type, you DO gain the ability to set an object within the Class itself.

Check this out:

Now this still technically being an Actor type, do I get all the same benefits doing it like this, as it would be me doing it through the level editor?

Edit: Also thank you again!

1 Like

Right, but you still have to set it to an instance at run time, you’ve only set a type there… :slight_smile:

1 Like