So i recently tried to make a function inside an interface pure, and i was informed about the fact that interface cannot contain pure functions and i am wondering if anyone from epic could find a second to elaborate as to why its impossible.
Also i was going to make an interface with getters mostly and pures seemed to be a natural option. Now i will make them callable but i am wondering if there is some other way of doing this? Maybe not using interface at all?
I guess you mean BlueprintPure rather than C++ (=0) pure?
I haven’t tested this, but I’d imagine it’s related to the fact that BP pure means it won’t alter the object, but an interface is not really a UObject, so maybe it’s not possible to make this connection. Still, it certainly seems like something that it would make sense to be able to do.
To be honest I’ve pretty much stayed away from using UE4 interfaces so far as they seem to be lacking in some pretty big ways. I’m really hoping they’ll get some more love and documentation soon.
It’s still not clear whether you mean BlueprintPure or pure virtual.
The latter isn’t supported for UClasses simply because of the extra generated code instantiating the class for its CDO. The Abstract qualifier takes care of enforcing abstract classes at a runtime engine level instead of C++'s built-in mechanic.
As for BlueprintPure, it’s just the way Blueprint works – “overriding” a function in blueprint isn’t done through BlueprintCallable UFunctions but through BlueprintEvents, whether Native or Implementable. The resulting functionality is rather finnicky but it’s a decent compromise.
Interfaces are a bit of a pain for me in UE4… My inner software engineer dislikes the limitations on them greatly…
C++ UInterface classes composed of Pure Virtual Functions are possible and can be implemented by your objects Only in C++
C++ UInterface classes are only accessible in the interface via blueprints if they are NOT composed of pure virtual functions and must be marked as "CannotImplementInterfaceInBlueprint in the UInterface meta declaration e.g. UINTERFACE(Blueprintable, meta=(CannotImplementInterfaceInBlueprint))
I do not believe C++ UInterface functions can be BlueprintPure (I may be wrong but it I think it has to do with the fact they exist as “some form” of blueprint library node like thing). So blueprint functions can only be BlueprintCallable. I also do not think you can use BlueprintNativeEvent or BlueprintImplementableEvent either on the interface itself.
Honestly my biggest irritation on this whole system is that the interface cannot be implementable in blueprints… though I’ve never tried to see if it won’t let me… (these are all coming from my own pains as I have asked lots of questions on the subject of Interfaces on AnswerHUB and a bit of trial and error. Cannot cast to C++ Interface in blueprints)
Not only you can, but if you want to be able to implement the interface in blueprint, you must. A BlueprintCallable UFunction will be callable from a blueprint using that interface, but if you want a blueprint to implement the interface from a blueprint, the mechanic for overriding functions is Blueprint***Events.
A quick example:
UINTERFACE()
class UHasProbabilityCurveInterface : public UInterface
{
GENERATED_UINTERFACE_BODY()
};
class IHasProbabilityCurveInterface
{
GENERATED_IINTERFACE_BODY()
UFUNCTION( BlueprintNativeEvent )
UCurveFloat* GetProbabilityCurve();
};
If this weren’t clumsy enough, you can’t directly invoke blueprint native events on interfaces – an extra thunk is generated that you have to go through (though the generated code is kind enough to let you know if you fail to do so):
(disregard the InterfaceCast, we’re still on 4.5.)
As to your last concern in that linked AnswerHub question, yes, you need a C++ base class to do anything with a blueprint in C++. But since you’re using interfaces anyway, you can just use UObject as your base class.
I believe I’m right in saying that your second line there is superfluous. This cast will, I think, actually fail in the case that the interface is implemented purely in your blueprint (as opposed to your blueprint deriving from a native class which itself implements the interface). However, even if that happens and Probability is set to NULL, the final line will still work as expected because Execute_*** is a static generated method, and the C++ compiler just ignores the fact that you tried to call it on an object pointer. So I think you can replace the final two lines with:
I’m starting to think that perhaps UE4 interfaces aren’t quite so limited as I’d thought (though they might be even more ugly). The idea that it was impossible to get an interface pointer for an object if it was a blueprint-only implementation of the interface was kind of a deal breaker. However, it seems the idea is you essentially just use a UObject pointer as a placeholder any time you want to store or pass around an interface-conforming entity, and call the ugly thunk to invoke the methods. I guess it means you can’t have an interface which can be implemented by UObjects and non-UObjects, which is a pity, but I guess it’s not too big of a deal.
You’re absolutely right. But using it in this fashion makes the calling method more consistent with non-Event function calls. In fact, it started out this way until I hit the check telling me to use the Execute thunk:
In this particular context, I am not null checking the result of the interface cast because the blueprint getter I am using is guaranteed to return a blueprint class that implements that interface. It is, in essence, a tacky way of doing multiple inheritance for a highly modular blueprint base.
Yeah I had meant to amend that, It had been a while since I posted that question to AnswerHUB and it has been a while now since I implemented my interfaces. I had forgotten that test had worked but it was not the exact outcome I was hoping for.
Agreed there. I was very aggravated with how Interfaces are done in UE4 but as I work with how UE4 does them I am starting to figure out how to do the things I am used to doing with them… someone should make a documentation on it :).
cmartel you seem highly knowledgeable all around I thank you on the many posts I have made with your aid to them.