Multiplayer and actor ownership

I’m currently stuck trying to understand how replication works when it comes to actor ownership.

In my game, I have a player who possesses a pawn. The pawn can spawn an actor (a robot humanoid character) and take movement control of it while still possessing the main pawn. In other words, the player doesn’t possess the spawned actor, but he can control it’s movement while still walking around as the pawn.

This works fine in single player, but when it comes to multiplayer I get stuck.

In the blueprint below, the top green section is located in the pawn (PlayerCamera).
The player presses P to spawn the robot character.

The middle yellowish blueprint is located in the player controller (GameplayPC).
The controller spawns the robot (IceMan) and sends the character’s reference back to the pawn (as ‘ControlledUnit’).

The bottom green blueprint is in the pawn and shows part of movement control.

This works fine when playing as the server, but fails as a client. The client can spawn the character (and is replicated properly from other clients/server), but cannot control it.
From what I can gather, the pawn never receives the reference to the spawned character so cannot control it. I don’t understand why the character reference isn’t sent back to the pawn client-side.

It would be great if somebody could help me solve this. More importantly, I want to learn why this doesn’t work.
Alternatively, if somebody has a better way of achieving this goal (pawn being able to spawn a character without changing possession), I would love to hear how it could be achieved.

Thanks in advance for any help.

Your variable controlled unit is set on the rpc server. So the server is set. The client isnt set because the variable isnt replicated. Click on your controlled unit and set it to replicated in the properties. So your variable should now have two white icons in the event graph.

The reason it didnt work because it wasnt valid and you have no pins connected to not valid. A good thing I do whenever I cast to something or do an is valid I put a print string node on the server to say what failed if it does fail.

Thank you very much for your quick answer. It sounds so obvious now - I didn’t even consider that the variable also needs to be replicated. Also, thanks for the string node tip!

While the ControlledUnit variable is now replicated properly, the movement inputs still don’t work. Any ideas on why movement input isn’t getting accepted by the character?

Get player controller with index 0 is bad node for multiplayer game i think…
Put overlap box near robot and when you overlap it, drag wire from “other actor” and “get instigator controller”… then cast it to your custom PC… try to control it from your player controller… yesterday i worked with robot too but with possessing, let me know if this helped, if not i will test it on my project and let you know. Also use “owner” pin, plug into that your currectly controlled pawn/camera actor

After is valid node try making a custom event with a float input for axis value. Make it a run on server or multicast. It might be multicast though. Then connect that custom event to add movement input and pass the float in the custom event to the scale value. You would have to make 2 separate custom events. One for thumbstick y and one for thumstick x. Also if that doesnt fully work also rechange the cast to gameplay pc from pure to impure. Sometimes that fails on me when I do multiplayer so I check using a print string on failed to see if thats the issue. Using a pure cast you wont ever know thats failing or causing the problem.

Thanks ptjackson, that worked perfectly. The custom events needed to run on server to work (multicast didn’t work at all). I can’t say I understand why it didn’t work before or why it does work when running it this way, but I’m very glad it is working! Thanks again.

Hey guys,

I have a problem that’s extremely similar to what amatthies was having, let me explain. First of all I am making a Titanfall game in VR.

The Pilot(that the player controls) can enter a M**ech, **and control it without possessing it. Inside the mech is a Joystick control that the player can grab and upon doing so I pipe all inputs from the respective controller grabbing the joystick control into that joystick control which then tells the mech what it needs to do.

For my current specific scenario I am:

  1. Entering the mech with my pilot
  2. Grabbing the joystick control with my left controller
  3. Tilting the left thumbstick to give input to the joystick control which theoretically should make the mech walk around

Everything works fine on the server, however on the client I can detect(with print statements) that the inputs values are ultimately getting to the mech, but it does not move. I believe none of the above actions need to be replicated except for the movement so I did not do any networking for the in-between values, and for movement I am using the mechs Add Movement Input node. If anyone can enlighten me, it would be greatly appreciated, I’ve been working a week on this very problem without any clue as to what is going wrong :’(

P.S. If I am approaching this problem completely incorrectly I would love someone to point me in the right direction

One thing I do notice is that on the Server it shows that the mech has a controller(AIController namely) that I verified with print statements, whereas on the Client it shows there is no controller for the mech. Since I am using the Add Movement Input node is that a problem? But I do have “Run Physics with No Controller” enabled on the CharacterMovement component on the mech so shouldn’t movement work even without a controller?

I really dunno what I’m missing ?_?

So I experimented with the pilot possessing the mech(not something I want to keep, it’s just for testing), and indeed the movement works and I can see that there is now a controller that the mech has access to as well. Which means the solution to my original problem is that for some reason on the client side when the pilot gets in the mech a controller is not set properly even though I make sure the client pilot takes ownership of the mech. Am I taking ownership incorrectly or is it something else altogether? I have provided my code for taking ownership as well.

Please if anyone knows what I’m doing wrong I would greatly appreciate it.


https://forums.unrealengine.com/core/image/gif;base64



https://forums.unrealengine.com/core/image/gif;base64

After lots of research and testing I made some new discoveries. It seems the reason why I might not be able to control the mech on the client is because the mech could be a server-owned actor which disallows clients to run RPCs on it, which might be why the “Add movement input” node gets ignored. So I was thinking maybe I could go full 360 and have the client pilot make the RPC calls to tell the mech to move.

In the image attached, I tried executing the mech’s “Add movement input” through the pilot and it still doesn’t move. However, if I disconnect the connection to the scale value on the “Add movement input” node and put in 1.0 it moves. So this means, that the node there works for moving the mech, but for some reason when I give it the value from the mech’s input(Left Stick YValue) it doesn’t work. And I was able to verify with print statements that the value isn’t 0. In fact when I input a 1.0 from the controller the value that is displayed for the Left Stick YValue is like 0.26, though weird at least its non zero. So how come the mech doesn’t move even when given a non zero input?

I’m so confused. Am I just verifying values incorrectly? Or am I doing something fundamentally wrong?

EDIT: I did another round of testing and this time the input values from the pilot and on the mech were the same, dunno what happened in my previous test that gave those weird numbers.

Update: I figured what was wrong. It turns out I just wasn’t replicating some key values correctly for the blueprints to behave properly. Networking is hard! >.<