How can I properly interact with a Client's Controller from the Server?

This is for an interaction object. I have an event that only gets called on the server and passes a pointer to the interacting character. It disables the input on the character, enables it on the object, and creates / displays a new hud widget. When the player hits a key (captured by the interaction object), it removes the new Widget, disables input on the object, and re-enables input on the character. This all works flawlessly on the server.

The trouble I’m running into right now is that I want to do functions (enable/disable input, create hud widget) that use to the interacting character’s controller, but none of it is working on the Client. After some research, I think that the Server doesn’t have access to the Client controllers (they don’t ever get created).

I tried creating a new custom event that the server can call on the owning client only, and the client seems to be receiving it properly. But now the problem is… even though I’m passing the character right along through the events, the client doesn’t recognize it as its own character! If I call get controller on it, it returns something, but it doesn’t seem to be its controller… I think. At least, none of the controller functions are working.

Any ideas on how to properly pass character references in events? Or how to find the proper local controller for a character? Ideally, I’d love to do everything right in the Server Only event, but that’s not looking like it’s possible.

After more research, I’m fairly certain the server does have access to all the controllers… so I’m still not sure why I can’t enable / disable input on a client from the server.

But I managed to get my functionality working using a multicast event in conjunction with “is locally controlled” instead of doing a direct comparison on the characters.

Hi there!

Actually every client has its own PlayerController and the server has all of them. But not everything the server does in the PlayerController gets network replicated to the client by default! So you need your own Variable Replication or as you already figured out: Event Replication. The fact that the client and the server have the same Controller (network instantiated) makes replication inside the controller possible :slight_smile: Same for GameState and network instantiated Actors and so on.

So your solution is the solution :slight_smile: (Besides i just would do a RunOnOwningClient instead of Multicast since the call from within a specific PlayerController reaches only the specific client anyway).

The server has full access to its own PlayerController if host and not dedicated. So there is no need for replication. But it is better to handle everything in the same way (within the replication event) to avoid possible differences in host client behavior and remote client behavior. Host “replicates” to itself as well for that.

hth :slight_smile: Marooney

Right, that’s what I meant, the other controllers don’t exist on other machines, except the Server.

Honestly, I would’ve expected functions you run on a controller on the Server to get replicated out… it seems meaningless to make changes to a controller that you never control if it doesn’t get propagated out.

Regardless, I think I understand better now. All my logic is on the interactive object itself, so I couldn’t do the RunOnOwningClient. At least, it didn’t seem to work in my testing. I’m just checking if the character I’m passing along is locally controlled and that seems to make it all work.

Otherwise, yeah, it all works the same way for Client and Server. Thanks for all the feedback and knowledge!