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] 4.7.4 server only function replication does not fire. (Example project included)

I'm creating a simple clickable object that can be picked up in game. The idea is that you can click it to collect it. When clicked this will call the server only function that sets the collected and "collectedRotation" variables. Both of these are replicated. This should cause them to replicate down to the clients. When performed by the server this behaves as expected but when the client clicks the item, the event is never called on the server version of the object.

I've included a example project that includes the object in question. The general order of operations should be: Project Example

  1. Client clicks object

  2. Client object registers click and performs action

  3. Calls server function to modify collected items variables

  4. Call interface function on the player controller that clicked.

  5. Player Controller implements interface call (in this case it calls collect item on the player state)

  6. Player state spawns the item for the player (and would store in an array in a proper implementation)

alt text alt text

Product Version: Not Selected
Tags:
more ▼

asked Apr 02 '15 at 11:25 PM in Blueprint Scripting

avatar image

Justin.Dooley
2.2k 104 75 164

avatar image Justin.Dooley Apr 03 '15 at 04:58 PM

So looking into this more, the only conclusion I can draw is that the collectible item does not have a NetOwner on the client and thus can not make the server only call. How should requests to the server be handled in this situation?

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

The question has been closed Apr 14 '15 at 04:32 PM by Justin.Dooley for the following reason:

No other input is being added to this question and it require too much reading for other to join in. This question is being closed and another more specific one is being asked.


1 answer: sort voted first

Hi Justin,

I believe the problem you're running into is that replicated variables do not communicate from Client to Server, only from Server to Client, as described here:

https://docs.unrealengine.com/latest/INT/Gameplay/Networking/Blueprints/index.html#variables

For something like this, it might be better to use RepNotify functions. Let me know if you need any help setting that up.

Hope that helps!

more ▼

answered Apr 03 '15 at 08:47 PM

avatar image Justin.Dooley Apr 03 '15 at 09:47 PM

Well I can understand that but I could have sworn that I was going server to client. The only time the replicated variables are changed are within a server only function. Does this not effectively cause the client to request the change from the server and then have the server replicate the changes down to all clients?

I've updated the main post with screenshots of the post to make it easier to have a quick look.

avatar image Justin.Dooley Apr 05 '15 at 07:45 PM

So I have looked into this further Specifically the events section in the link you provided. It looks like the client can never call the collect because the object is not owned by the invoking client. (it starts in the level so it is never called due to it being owned by the server)

I then tried to have the client spawn an actor that replicates. Due to it not being the server it only appeared on the client and not the server but the client was able to interact with the object just fine.

The last thing I tried was to spawn an object using a check for authority. If you had authority spawn the object if not call a server only function that spawned it. Doing this cause the object to spawn on the server and replicate down. however the server owned the object again so the client could not interact with it because the run on server call was dropped.

Given that player controllers do not inherently replicate (nor does it really make sense for them to) how should a non replicating actor make a request to the server?

avatar image Ben Halliday STAFF Apr 06 '15 at 08:12 PM

That's correct. Sorry I answered before looking at the project first, but since the Actor is owned by the Server, Run on Server won't communicate with the Server from the Client, and that RPC will be dropped.

To get around this, the easiest thing is to send information to the Client's PlayerController, which can communicate with the Server. Something like this:

alt text

That calls this on the local PlayerController:

alt text

Which calls the Server_CollectItem Custom Event on the Collectible.

Hope that helps!

avatar image Justin.Dooley Apr 06 '15 at 10:08 PM

while I understand the workaround, that ruins the encapsulation of the system since I can't make a interface event server only. Having to make a new version of a collectible based on every version of player controller isn't practice. Is there a way for the server to assign ownership to a client?

avatar image Ben Halliday STAFF Apr 06 '15 at 10:26 PM

There isn't a way to assign ownership to a Client, but that wouldn't make a lot of sense outside of components; most everything in a level belongs to the Server. Clients can only own a few things: the Client's player controller, pawn, and player state, and any components belonging to those. For your collectible to belong to a Client, it would need to be a component of one of these. Since you want the everyone to be able to view and interact with the collectible, it needs to belong to the Server so the results of that interaction can be replicated to everyone else. The Client can't replicate anything to other Clients (everything is done through the Server), so it wouldn't work if the collectible was owned by the Client.

I'm not certain I understand what wouldn't work this way. You shouldn't need to create a new version of the collectible for every player controller version. So if you have multiple types of player controller, each would utilize the same call to your collectible. It references the collectible instance (it's passed Self from the collectible that calls it). Why would you need multiple collectible versions for this? How does your interface work into this scenario? Is there something I'm missing with your setup?

avatar image Justin.Dooley Apr 06 '15 at 10:55 PM

in your setup you cast to a CollectiblePlayerController in order to call the ClienttoServerCollect event. If a different player controller (say a sidekickController) would not be able to call the ClientToServer call as it would fail the cast.

My interface in this setup is to help work around this. I perform a check to see if the class implements my interface first. This determines if the client can interact with it at all. If it does then call the appropriate function that implements the custom based on who collected it. (Dr Jekyll collects it then heal, Mr Hyde collects it then hurt as an example.) same item but different implementations. For encapsulation the item should take care of it's own clean up. In this case animating and destroying itself.

I only see two options at this point. One is to have the player controller call call a server function to implement the clean up which breaks the encapsulation as it makes the communication two way rather than one way.

The other is to create an adapter for client to server function calls through c++ using a special class of game instance. this way I can basically do the same thing as the event but pass it a function name and use the object->findFunction method.

If you have other suggestions, I'm more than open to them.

avatar image Justin.Dooley Apr 07 '15 at 04:16 PM

Hi Ben.

So I have been trying a few things. Specifically I created a new game instance to act as an interface for replication. this resulted in the same result in the end though.

I got to thinking though. Why does a RunOnServer event work on a player controller that isn't replicated? Is there something about the player controller that is special and allows for this to happen?

As a side note this documentations states that:

You can use the Replicates checkbox for any Interfaces containing functions that need to replicate across the server. This is found within the Details tab by first clicking the BlueprintProps.png button.

That would make this whole thing a whole lot easier.

avatar image Justin.Dooley Apr 13 '15 at 07:18 PM

Hi. I just wanted to check if there anyone had a chance to look at this about the interface replication methods. That would fix everything.

avatar image Justin.Dooley Apr 14 '15 at 04:24 PM

At this point I'm guessing that this is a bit of a loss cause. Having the implementation encapsulated for easy reuse doesn't seem possible while interface replication is not implemented. I'll post a new question regarding that and reference this post.

(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