Interfaces, Blueprint Library and RPC calls.

Hello I am working on a interface that will handle all networked related stuff.
For sound and particles and i meet a little snag.

When writing this code i felt sort of clever, lol. :stuck_out_tongue:
But i am failing with the inheritance of the interface to other gameplay classes like Items.

Now i made the interface like this.
// SoundAndParticleInterface.h


UINTERFACE(meta = (CannotImplementInterfaceInBlueprint))
class MYGAME_API USoundAndParticleInterface : public UInterface
{
	GENERATED_UINTERFACE_BODY()
	
};

class ISoundAndParticleInterface
{
	GENERATED_IINTERFACE_BODY()

	/* Called from client to server to call the multicast RPC method. */
	UFUNCTION(Server, Unreliable, WithValidation)
		virtual void SERVER_PlaySoundForEveryoneAtLocation(AActor* ParentActor, USoundCue* SoundToPlay, const FVector & LocationToPlayAt, FName AttachName, bool bFollow, float VolumeMultiplier, float PitchMultiplier);

	/* Server calls this method and all clients currently connected. */
	UFUNCTION(NetMulticast, Unreliable, WithValidation)
		virtual void MULTI_PlaySoundForEveryoneAtLocation(AActor* ParentActor, USoundCue* SoundToPlay, const FVector & LocationToPlayAt, FName AttachName, bool bFollow, float VolumeMultiplier, float PitchMultiplier);

};

And then i have the Blueprint Function Library like this.
// PlaySoundAndParticlesLibrary.h


UCLASS(Blueprintable)
class MYGAME_API UPlaySoundAndParticlesLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
public:

	/* Play Sound For Everyone at provided location.
	 * Handels replication using ISoundAndParticleInterface::.
	 * And will only be played on a actor with this interface.
	 *	-------------------------------------------------------------------------------
	 *	@Param: The actor that plays this sound in the world (player, door, weapon, ..)
	 *	@Param: The Sound Cue to Play at the given location.
	 *	@Param: The Vector location to play the given sound.
	 *	@Param: Attach name of socket.
	 *	@Param: If TRUE the sounds follows the parent in the world.
	 *	@Param: Volume multiplier for this sound.
	 *	@Param: Volume pitch Multiplier for this sound.
	 */
	UFUNCTION(BlueprintCallable, Category = "MP Play Sound And Effects")
		static void PlaySoundForEveryoneAtLocation(AActor* ParentActor, USoundCue* SoundToPlay, const FVector & LocationToPlayAt, FName AttachName, bool bFollow, float VolumeMultiplier, float PitchMultiplier);

};


So this compiles fine until i go and try to add it to a class.


UCLASS()
class MYGAME_API AMyGameBaseItem : public AActor, public ISoundAndParticleInterface
{
	GENERATED_UCLASS_BODY()

public:
..
};

And compiler gives me this error.


error C2259: 'AMyGameBaseItem' : cannot instantiate abstract class

Now i never intended for these methods to be over-ridden in the other classes only call the default one.
And it seems that also can become a problem, and am not sure if i can declare the RPC methods virtual?
Am seeing these error`s under the above one.


void ISoundAndParticleInterface::SERVER_PlaySoundForEveryoneAtLocation_Implementation(AActor *,USoundCue *,const FVector &,FName,bool,float,float)' : is abstract

Any advice be much appreciate at this point.
Cheers!

So, you have your virtual functions that you don’t want to override? o.o Where did you write the base difinition of that function?
I’m not that C++ expert but as far as i know, you need an implementation of that function before creating objects from the class.

Either you implement it in your Sound and Particle Interface or you override it in your Base Item class.

Someone correct me please if i’m wrong. >.<

the resson for them beeing virtual is becuse they simply need to be.
I prefer them not to be virtual but if I try to i get the following error.


error : In SoundAndParticleInterface: Interface functions that are not BlueprintImplementableEvents must be declared 'virtual'

Base defenition is in ISoundAndParticleInterface::


void ISoundAndParticleInterface::SERVER_PlaySoundForEveryoneAtLocation_Implementation(AActor* ParentActor, USoundCue* SoundToPlay, const FVector & LocationToPlayAt, FName AttachName, bool bFollow, float VolumeMultiplier, float PitchMultiplier)
{
	// Server calls the multi cast delegate that plays the sound on server and all clients applicable.
	MULTI_PlaySoundForEveryoneAtLocation(ParentActor, SoundToPlay, LocationToPlayAt, AttachName, bFollow, VolumeMultiplier, PitchMultiplier);
}

bool ISoundAndParticleInterface::SERVER_PlaySoundForEveryoneAtLocation_Validate(AActor* ParentActor, USoundCue* SoundToPlay, const FVector & LocationToPlayAt, FName AttachName, bool bFollow, float VolumeMultiplier, float PitchMultiplier)
{
	return true;
}

Am probeboly doing something stupid, or its not meant to work by design i just like to know for sure.

If you implement the methods in your interface class, and do not intend for them to be overridden, why are you using an interface at all? That is not an interface, it’s just a base class with some functionality. The whole point of an interface is that it is just that - a list of method declarations without an implementation, which other classes can conform to and implement.

Alright, sorry. Like i said, i’m not that into the c++ UE4 yet.

EDIT: Nevermind. I confused myself xD

Oo
I don’t see implementation of declared interface functions.
In interface you have to declare virtual functions and in final class you have to define them otherwise it does not know where to look. It is the whole point of interfaces :confused:
I assume compiler treat your class as abstract because it contains only virtual functions and there is really no reason to think otherwise

So i made an atempt to adding some none virtual methods.
with and with out UFUNCTION macro and some BlueprintCallable, and BLueprintImplementableEvent.

But stile the same issue.
Am at a lose class is not tages abstract in the UCLASS ether.

To repeat, it is normal that you are getting these errors, as your ISoundAndParticleInterface should not have method implementations.
You say you don’t want the methods to be virtual, so what is your reason for using an interface?

The resson for this is that I wanted to wrap the networked stuff into a Blueprint Function linrary.
So i e.g: did not have to have a base class for all actors in my game.
Or so that i can reuse network code on several base classes with out writing them for all the classes.
For more maintainable code and so on.

At the time it looked like a good solution but now am not so sure.

What you are describing is an abstract base class. In C++ a the closest thing to a real interface is an abstract base class with all pure virtual functions. However C++ utilizes multiple inheritance, so what you are asking for is possible… but not recommend because of the inheriting multiple base classes with the same base class (such as UObject) can lead to problems. HOWEVER is my suggestion. Create your network interface as an abstract base class with pure virtual functions. You said you will not have a base class for all actors in your game. That is fine but for every actor that implements this interface they MUST have to override the interface functions. Now why do not not have a common base class for all your actors, that to me is an odd requirement. UE4 has a common set of base classes. I get not wanting to have a single base class but you can have an individual base class for various types of UE objects such as NetworkPawn, NetworkPlayerController, NetworkActor, NetworkActorInfo, etc each that implement your interface. Then when you need a new brand new object you derive your new actor/object from one of these. Yes it’s a lot of work but in my opinion it is WAY better than braving multiple inheritance with UObjects.

OR

(I think this may be WAY Easier) You create some globally accessible information object ( AInfo ) that is replicated to each user and whose functions all take an Actor object as aparameter and whose functions can execute multi-cast functions from the server related to the supplied Actor (hens why globally accessible). This will probably need to be in UWorld or ULevelScriptActor

You can override the ULevelScriptActor by following this tutorial: Solus tutorials

Hello and thanks for your replyes.
I totoly agree with you, but the resson for me doing this was to see if I could.
And if it whould work it whould leave me with the abilaty to have one class for this instead of implementing it on my base classes.

Its the recuierments/ limitations of interfaces that makes this imposible.
If the interface was not looked upon as a abstract class then this whould work fine.

And i could have used the interface on several gameplay classes with one place to maintain all that code.
And they all whould call the base method and inheritance would not be a problem.

As any method thats not over-ridden whould call the base method.
But since am forced to override them then I will just go back to a more traditonal way of doing it.

In a perfect world it should no have to be virtual at all. :slight_smile:
Its no problem tough it be realy nice if this limitation/ restriction was removed.

I’m facing the same problem, maybe you can create another static class which is only accessable from the interface, make it handle the static RPC functions, than call the RPC functions through the interface. I haven’t tried it, but I guess something like that could work