Ive been coding a USE system for my game, and im trying to make a interface to use with multiple inheritance and casting.
Ive tried the UINTERFACE macro(like UCLASS), but is giving me a lot of problems and i cant find proper explanation on how to set it up correctly in the documentation.
Dear Victor,
You are in luck!
I wrote an entire tutorial on using UE4 C++ Interfaces!
UE4 C++ Interfaces are awesome!
What I display below is my own research, without any assistance from Epic, so I can’t proclaim it is optimal but it works great for me
#My tutorial on UE4 C++ Interfaces
Here’s a code sample from the tutorial:
#.h
// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "ToStringInterface.generated.h"
/** Class needed to support InterfaceCast(Object) */
UINTERFACE(MinimalAPI)
class UToStringInterface : public UInterface
{
GENERATED_UINTERFACE_BODY()
};
class IToStringInterface
{
GENERATED_IINTERFACE_BODY()
virtual FString ToString();
};
#.cpp
// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
#include "VictoryGame.h"
//////////////////////////////////////////////////////////////////////////
// ToStringInterface
UToStringInterface::UToStringInterface(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
}
//This is required for compiling, would also let you know if somehow you called
//the base event/function rather than the over-rided version
FString IToStringInterface::ToString()
{
return "IToStringInterface::ToString()";
}
#Class using Interface Via Multiple Inheritance
UCLASS(placeable)
class AFlower : public ASkeletalMeshActor, public IToStringInterface
{
GENERATED_UCLASS_BODY()
FLinearColor FlowerColor;
FVector FlowerScale3D;
void OpenBlossom();
void CloseUpForTheNight();
//IToStringInterface
public:
virtual FString ToString() OVERRIDE;
};
#Flower.cpp
//other flower code
//IToStringInterface
FString AFlower::ToString()
{
return "Flower!";
}
#Interface Cast
//Check Flower
TheInterface = InterfaceCast(MyFlower);
if(TheInterface)
{
ClientMessage("Flower Uses Interface");
ClientMessage(TheInterface->ToString());
}
Thanks a lot, , this was just what i needed.
Just thought I’d add a few points.
1 - If you make the interface methods ‘pure virtual’ like so:
virtual FString ToString() = 0;
You won’t need to supply an implementation, and it will throw a compile error when you don’t implement it in a deriving class. This is much safer than providing a default implementation that logs a run-time message.
2 - If you want to make your methods BlueprintCallable UFUNCTION’s, you need to mark the UINTERFACE like so:
UINTERFACE(meta=(CannotImplementInterfaceInBlueprint))
3 - Also, your interface types cannot be UPROPERTY’s, because the system has no way to serialize a reference to the type (they don’t derive UObject). This greatly reduces their usefulness for anything other than cast-checking or method parameters.
Edit: Just on that last point, there is an engine type (TInterfaceType<> I think?) that can allow you to pass interface types as UFUNCTION parameters. I haven’t experimented with it much, so I don’t know its limitations, but it may even let you serialize one as a UPROPERTY somehow? I don’t know, but if you really need that functionality, you could investigate it.
"1 - If you make the interface methods ‘pure virtual’ like so:
virtual FString ToString() = 0;
You won’t need to supply an implementation, and it will throw a compile error when you don’t implement it in a deriving class. This is much safer than providing a default implementation that logs a run-time message."
Wow this is a great tip! Thanks Andrew!
Finally managed to do the interface properly, my USE system works flawless now. Ill go pack it a bit better and release the snippets in the forum
Glad you got it all figured out Victor!
Did you create the interface file from the editor or manually through the VS project? I tried doing from the editor but I can’t find the “Interface” class, should I use “Object” ?
Never mind, I created them from the editor and changed them in VS. Thanks everyone.
Hello @jdavid82. It is good to see that you appear to have solved the issue you were experiencing. I will be closing this post due to its age. If you need any additional help with this, please feel free to post a new question.
Have a great day.