Member Variable Declaration not allowed in Interfaces?

Any idea why I can’t have a UPROPERTY as part of my interface? Full details on Answerhub here: https://answers.unrealengine.com/questions/150414/c-interface-member-declation-not-allowed-here.html

Essentially, I want all of my classes that have this interface to have an instance of the Struct, rather than duplicating functions and variables all over my code and having to do a tonne of conditional checks whenever I want to get the values from another class.

3 Likes

Because that is simply not what an interface is made for. An interface is essentially a contract saying “I will provide the functionality described by this interface, regardless of how I handle it internally”. The second part is important because that is the main distinction from an abstract base class. The abstract base class can choose to provide some or all of the functionality itself, but the interface must not provide functionality.

The distinction is important in languages like C# that do not allow multiple inheritance. C++ supports multiple inheritance, but Epic opted not to allow it for UObjects. The reason for this is the same as C#, which is that multiple inheritance complicates RTTI by a lot. On the other hand, since interfaces are guaranteed not to come with details such as member variables, you can add as many as you like without complicating the inheritance tree. It’s a rather intricate topic and an oft discussed one, I recommend reading through Scott Meyers’ Effective C++ if you want to learn more about it.

But with UE4, your best bet would be to either provide this functionality as part of an actual base class or, in the case of an actor, create an actor component.

3 Likes

As mentioned you cant store data in an interface,

However in my own project I use C++ interfaces quite extensively and I do have a solution for your overall goal!

You can make a pure virtual getter that returns by reference, and because it is pure virtual every class is required to implement it, and they can provide their own stored version of your data structure, which is exposed to BP as you want it to be!



//.h
virtual FYourDataStruct& GetDataStruct() = 0;


Because the function is returning by reference, you are able to manipulate the data!

Any classes wanting to manipulate the data that is common to the interface can use the function too!

This gives you a way to write code to get as well as manipulate member variables that are common to all implementers of an interface!

:heart:

Rama

PS:

More info at your answerhub

2 Likes

Wouldn’t you implement that as a component then rather than an interface? I did read in the docs the other day that there’s a sort of “lightweight component” but I can’t remember what it was called.

Normally if you want methods + data but have it be run-time composable, I’d recommend using a component system. Although UE4 has for some weird reason chosen to half-*** the component thing a bit (the fact that BP can’t remove C++ components for example).

In my own case I needed an interface for components :slight_smile:

To unite a custom SkeletalMeshComponent and a custom StaticMeshComponent that have shared functionality based on my game’s unique mechanics involving actor components that can be made and placed at runtime, and saved to disk.

I am not sure exactly what Jamsh’s needs are, but what I am presenting is a way that you can interact with member variables that are common to several classes that have different class inheritance structures and putting the functionality into a single component is not an option.

Putting a bunch of common member variable data into a component is a great idea though! Depends on the exact use case :slight_smile:

Only Mr. Jamsh can tell us what way is best for him :slight_smile:

:slight_smile:

Rama

You guys are all awesome, thanks for the good feedback and the further reading! I’ll be sure to check those out!

So after posting this I went and made an ActorComponent; and realised that I could just do a check to see if an Actor has that component in my other classes that want to manipulate values or get values from it (which skips doing checks like, is it this, or is it this, or is it this? So on and so forth). This seems like the quickest and most foolproof solution (and certainly the easiest for me to understand).

The idea was that I wanted to Append properties to certain classes, such as a Vehicle that can be built (in-game) from a building. The vehicle would have properties such as build time, build cost, health etc, but would inherit from APawn so that I could easily update my code to the latest version of Unreal at the time and avoid any changes to source code. Sometimes however I might want to build an actor or some other class, but with those same properties. Being able to specify which types of actors had these properties and being able to manipulate them all universally without a LOT of conditional checks and casting was the plan. Of course, I wanted to make Blueprints of the basic ‘Vehicle’ class for different vehicles, all with different values for those same properties.

Team Number is another one I would have wanted to store as well, I looked at UT’s source code where they use an interface to allow classes to get a TeamNumber from something, but I admit I didn’t fully understand the code written there. Thanks for giving a better description of how interfaces work, it makes much more sense now :slight_smile:

(Hope this post makes sense, still not quite awake ;))

I just Got this to work. In your interface class, remove ALL UPROPERTY() Macros from your properties because they wont work. Then in the classes inheritting or implementing the interface, create getter functions and/or setter functions for each of the property you wish to edit from the blueprint. Make Sure you decorate the getter and Setter functions with UFUNCTION(BlueprintCallable) for them to be visible in the blueprint. :slight_smile:

1 Like