Array of actors which inherit an interface.

I’m trying to set up an actor that can pass messages to certain other types of object. I have a system set up like this, so I can pass objects into the array from the editor, and at runtime loop over them and execute the function.


However, when I do this, I found that the array does not accept actor references, but asset paths instead:


I suspect this is because the interface could exist on a non-actor object, but this seems like a fairly large functionality gap. I could just accept Actor references, but that gets messy and requires casting. Is there no way to specify that actors added to the array must inherit a given interface? It seems a bit of an oversight if not.

EDIT: Some more testing of this reveals that this appears to be a bug with the user interface in the editor, and not anything to do with how interfaces operate. Interfaces work exactly as expected, but they appear as a path (to an Actor in the scene) in the editor, rather than a selection box as it is for other types.

No. This is because you have an array of interfaces of the type “Disable”: You can only store interfaces in it an not actor references.

To actually call actor references you don’t need to have the interface as reference but the actor itself. To make sure every actor you use there you can either create a master class for every actor or just check if “Actor implements interface” before you add it in there or rather before you use the interface.

Remember. The array contains interfaces which is something you can slab on top of an actor. Not anything you can really work with and you will not be able to call the interface itself.

If you know java: This is pretty much the path / name which you place behind “extends” when declaring your class.

I hope this helps.

Cheers

Okay, except there are a few things wrong with this.

First, interfaces are a form of multiple inheritance, they are supposed to function similar to abstract classes, but allow no implementation of functions in order to avoid clashes when inheriting from multiple interfaces. They are type in and of themselves, so there should be no reason why object references couldn’t be stored (and there doesn’t appear to be, see below).

Secondly, my question was simple: “why can I not point to actor references, instead of having to enter the path?” As it turns out, filling in this path does appear to point to an actor reference, rather than an asset, so why is the user interface set up like this?

Thirdly, interfaces are not “something you slap on top of an actor”, they are a core component of a language allowing less code repetition and more consistency, and the ability to treat them the same as other types is a large part of that. If I were using Java, I would be able to write: new IDisable[n] just as I could write new Actor[n], and it would store object references just the same, but restrict the type to objects that implement IDisable, without having to cast later (which is ugly and unsafe - best avoided).

It appears that these paths do point to actor references (as they should, as there is a separate type for the interface class itself). The whole point of interfaces is that you can treat them as any other type, and allow similar objects to share functions. It seems this is an error in Unreal, where the wrong UI has been used for interface types.

In most uses, it is the same as a type. Even in this case - the “path” appears to allow me to pass an actor which implements the interface, it just seems to be using the wrong UI (though there also appears to be no cast to interfaces in blueprints, either, which is a pain).

But blueprint interfaces does not have that, they are kind of lossly made more like sending message to a object as icons in blueprint suggest. Also interfaces are pretty young feature of blueprint so it still might get better. I also think it should be type

Well if there no type there no need for casting. Post suggestion in feedback section of forum about it if you want

That’s just not true because even in their limited form here, interfaces are still types. I just found that there is a cast node available for interface types. I’m not sure why it wasn’t allowing me to place it earlier, but I can now.

Ok ;p either way post your ideas in feedback forum it best place to place suggetions

Alright sorry for that. There are so many different types of people here I tend to assume a very little knowledge of programming when answering any question…

Clearly wrong here. Sorry.

But it’s still not entirely correct. Sure you can implement an interface by writing new IDisable() but all this is doing is creating an anonymous class that implements the interface and instantiates that class.

You are not actually creating a new interface or working with the interface itself. And sure you can get all classes that implement the interface but the same goes for Unreal and Blueprint. You can check through all possible actors and check if they do implement the interface.

However UE does not allow those anonymous classes but rather provides you with the reference to the interface so you may add it to some actor. The same goes for images, structs, etc.

You misread me. You actually can’t write new IDisable(), because the interface has no implementation, therefore no constructor, and no purpose, so this is a useless thing to do, and disallowed by most sensible languages. What I actually wrote was new IDisable[n], which is an array type. This is instantiating an array, but populating it with null. I probably should have used this example instead: IDisable myVar;, which declares (but importantly doesn’t define) an interface type. This variable can then have any type that implements IDisable allocated to it. and can use functions declared within the interface. This is the key purpose of interfaces. It’s not quite how it works in Unreal, but Unreal does allow the same behaviour (it’s actually much less tightly bound in Unreal blueprints). At the moment, there’s no type checking on interface types in Unreal, but as far as I can see the underlying concept is the same. It seems like these interfaces are a semi-complete structure (I certainly hope so), and are working towards this robust functionality in the future.

As for iterating over all objects and checking if they implement the interface, that’s possible sure, but it’s terrible for performance. Far better to have the type checker guarantee this at compile time, rather than compute it at run time.

In any case, I think you’re overcomplicating what my question was. I was simply asking “why does the editor ask me for a path to an object reference, rather than just letting me give it an object reference?”.

The UE4 editor simply doesn’t provide a way to set interface reference properties/variables from the GUI properties editor. I don’t know why it gives you a text field as the input widget. I don’t think it does anything. (Edit: wrong, apparently you can manually type in a name and it will stay serialized). You can set the array fields in code or Blueprint directly, though. As you mentioned before, if you want to pick the actor objects from the editor, you’ll just have to store them as an array of Actor references.

(interface references aren’t serialized or network replicated, anyway, so you probably don’t want to expose them as an editable property Blueprints.)

Yes it does. It gives me a text field and, as I’ve said multiple times, that field allows me to access actors in the scene. I tested it, it works, it’s just a text field instead of an object selection dialogue.

I currently have it set up to select actor references, for ease of use, but it’s wasteful to do it this way. I’m confident this is a bug or oversight in the engine, since the functionality is all there.

I also don’t really care about network replication, since I’m not using the network, but that also seems like a rather large oversight.

Sorry about that. The last time I tried it, it didn’t work by typing in a name. TScriptInterface arrays store the offset to the interface function table in them, so I’m not sure how hard or easy it would be to make it replicate. Not to mention that it’s possible to create bugs for yourself by trying to replicate references to things which cannot be replicated anyway, which interfaces allow for.

Epic’s own stuff just casts to an interface whenever it’s needed instead of storing the references permanently as interface references. I don’t think it’s that wasteful (the dynamic invocation from Blueprints is already pretty expensive compared to a normal function invocation).

There is that.

Casting is a fairly wasteful operation. It’s far better to ensure the typing at compile time than force it at runtime. Always.