x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

[Closed] RPC from actor which is owned by player controller

Hey guys,

I need your help. I can't quite get my head wrapped around the whole replication thing, so please bear with me.

I have created an actor which inherits directly from AActor. Let's call it node. The node is an actor which has already been placed in the map and has bReplicates and bNetLoadOnClient set to true. The node has the following methods defined:

node.h

 UFUNCTION(BlueprintCallable, Category = "Node")
 void DoStuff(APawn* character);
 
 UFUNCTION(Reliable, Server, WithValidation)
 void ServerDoStuff(APawn* character);
 virtual void ServerDoStuff_Implementation(APawn* character);
 virtual bool ServerDoStuff_Validate(APawn* character);

the node implements the following:

node.cpp

 void ANode::DoStuff(APawn* character){
     if (Role != ROLE_Authority)
     {
         ServerDoStuff(character);
     }
     else if(Role == ROLE_Authority){
         SetOwner(character);
         //spawn another actor which replicates
         SetOwner(nullptr);
     }
 }
 
 void ANode::ServerDoStuff_Implementation(APawn* character) {
     DoStuff(character);
 }
 
 bool ANode::ServerDoStuff_Validate(APawn* character) {
     return true;
 }

Now the thing is, when I trigger the execution of that code on the server. everything works just fine. A new actor will be spawned on the server which replicates to the client.

If I call the code from a client, DoStuff will be called and the code branches correctly into ServerDoStuff, however nothing will be called after that. I set breakpoints into ServerDoStuff_Implementation, ServerDoStuff_Validate and DoStuff but the code in there will never be called.

The APawn Pointer is a "this" reference from within the executing character which inherits directly from ACharacter. Might that be an issue?

character.cpp

 node->DoStuff(this);

At first I did not set the owner, which resulted in a console message which told me that the RPC will be ignored since no owner has been set. Now that I have set the owner, no more errors or messages are displayed. Just nothing happens.

If I change the method to "Multicast" all methods will be called and executed as expected. But I don't want a multicast here, since the client would create its own instance of the spawned actor, right?

Any idea as to why nothing happens, or what I did wrong?

Thanks for your help!

Cheers Edregol

Product Version: UE 4.14
Tags:
more ▼

asked Jan 08 '17 at 06:37 PM in C++ Programming

avatar image

Edregol
169 13 15 26

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

The question has been closed Jul 01 '17 at 01:48 PM by Edregol for the following reason:

The question is answered, right answer was accepted


1 answer: sort voted first

Hi,

I have had actually ran into this problem myself.

Your problem here is that as Server RPCs will only be run if it is called from the "Owning client", whereas Multicast will run on the client even if it's not the owning client. I'm sure you've found this out. But, you are setting the owner if Role == ROLE_Authority, but if you call DoStuff not with ROLE_Authority, it won't run the if statement code for setting owner. The problem then is that you can't set the owner from the client, because it doesn't have authority.

Solution

If your "node" variable is a "private" variable, meaning only one character have reference to it, then all you have to do is to attach the actor to your actor in the constructor, thus having your character owning it.

However, if your "node" is a public Actor that all clients can use, then it is very messy. Basically you need the RPC functions inside your character class (or I prefer the playercontroller class because it has less things). Then when you call Node->DoStuff(Player) on the client, the Node will call Player->ServerDoStuff(...), which then calls the Node's DoStuff, but this time the call will be on the server.

I hope this helps, if you don't understand my explanation then I can give a few examples.

: )

more ▼

answered Jan 11 '17 at 04:33 AM

avatar image

Xternalhardrive
31 2 2 2

avatar image Edregol Jan 11 '17 at 06:47 PM

Thank you! That makes sense. However is kinda counter intuitive to transfer the logic from the node into the player controller to call RPCs on the server to call the node's method on the server side, to then replicate stuff to the client again. I bet you can tell my node is a "public" actor. :D I was hoping there is another "cleaner" way to accomplish what I wanted to do.

However, thank you for your clarification!

Cheers, Edregol

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question