Making "Zelda Pick-Up/Throw" Multiplayer

Hi guys,

Would appreciate some help on this one, as I’ve been trying to figure out myself now for days, and I just don’t seem to be having any luck. I followed this tutorial:

And now I want to have the same system working in a multiplayer environment, with the slight difference of the mesh not being destryoed when thrown, instead just becoming something that can be picked up again and again. However!

Animations aren’t replicated on either the client or server side - I’ve set the animation booleans to replicate, that changed nothing, and I’m just not seeing any other settings to play around with to get this to work.

The pick up actor does attach to the socket on the character mesh and follow the server around on the server and on the client, but without the “Hold” animation, it’s following the hand around during the running animation.

Picking the actor up as the client can only be seen on the client side, it does not seem to replicate the position changes or the animations on the server.

Now, I’ve read through the forums and it looks like replicating a physics actor is already something of a no no? To what extent? I was really hoping to have a single parent actor that could have it’s mesh changed on the fly, allowing players to be able to pick up a variet of different items, while the logic for doing so remained the same. Is this beyond the scope of the engines capabilities?

Secondly, why is it so difficult to get animations replicating for the client and the server? Allow me to expand on this frustration: If I set up a blank third person template project, and launch it as a multiplayer game, the animations and logic for jumping work without me having to change anything. You’re able to see the client jump on the server side, and the server jump on the client side. Yet when you try to implement your own animations ontop of these, following the logic already in place by default, it just doesn’t seem to work. Researching this topic and people are creating multiple custom events, one to fire on the server, another to fire on the client, to control all of this, which seems…wrong? If I had 50 animations then that would mean i’d need 100 custom events to run them all? I must be overlooking something with the way the state machine/animations in general, work within the engine?

The idea that to add any of your own content to your games can’t be done in a way that mimics the system that comes as default is honestly enough to make me want to give up before I’ve even started! This is about the most simple idea I’ve ever been able to imagine developing - everything else was far too complex for a solo dev to tackle - and even with this it’s made to feel impossible.

I’ve captured a couple of screenshots below to try and better illustrate the problems I’m currently facing. The blue pawn is the server, and the grey pawn is the client.

Any assistance in getting this working would be massively appreciated!

Tom

I’ll just address the animation part of your question because I’m heading to bed and I’m on my phone.

First, make sure you aren’t using root animations for the most part. If you use root then you usually have to use montages.

Secondly, it’s not the animations that are the problems but the actions that you are calling. Unreal is Server authorative to prevent cheating and such. So yes. Usually 2 custom events per action.

Like this…

Input action “dodge” button that goes into custom event called Client-Dodge and set it to multicast. Then custom event called Server-Dodge that is set to replicated. That then feeds into your animation BP to make the dodge happen.

So client says, “hey I’m dodging. Let me dodge and tell everyone else around me that I’m dodging. Please let me dodge Server?!?”

Server says, “Ya that’s cool. Seems legit. I’ll let everyone know.”

That’s the way I understand it. We’ve been working 12-14hrs a day for 9 months on an MMO and the replication is frustrating. Takes 3 times as long for each little micro project in multiplayer but it’s a safer way to have your game run. Just look at the BS that New World is going through because they aren’t 100% server authorative.

Thanks for getting back to me, Dave.

Let me clear up that I understand replication, and why it’s used, that’s not where my issues lies. As I said above, the default “Jump” works in a blank third person template, when run as a multiplayer game, without me having to change anything - all the animations and logic work on the client side, and on the server side, through a single input action event. Mimic this with my own animations and suddenly I need multiple events with different settings to achieve the same result? Why?

I’ve taken your advice and looked over each of the 3 animations in use, and none of them are ‘root animations’ - assuming I’m interpreting what you mean by that correctly:

Hi all, so I came away from this for a couple of days because it was driving me crazy. During that time I realised that asking a bunch of strangers to follow a tutorial for over an hour before they could start looking at the problem probably wasn’t going to happen. Therefore, I’ve set up a new, clean, third person project and followed along the tutorial, then saved it so you can doanload the project after the tutorial has been followed.

1 Like

I’ve had a chance to do a little more work on this today, for a couple of hours this afternoon, so have decided to log the progress I’ve made to try and help others in the future.

So far It’s still not working! :smiley:

Changes made:

Character Blueprint - Pick Up Input Action calls a custom event that runs the pickup logic on the client. The custom event also runs another custom event that runs the same logic again, but on the server.

Anim Blueprint - AnimNotify_Pick Up now calls a custom event inside the Event Graph that runs on the client, and calls the Client Pick Up Loot event from the character (Which is found from a cast during the Blueprint Initialize Animation)

The Pick Up Loot on client runs within the character blueprint, attaching the component as per the above tutorial, but it also calls another custom event to run the same logic on the server.

I’m now getting the below error when the Client “Picks Up” the actor:

Blueprint Runtime Error: “Accessed None trying to read property Picked Up Mesh”. Blueprint: GnomeParent Function: Execute Ubergraph Gnome Parent Graph: EventGraph Node: AttachActorToComponent

(Gnome Parent - Is the name of the parent class within my game, you can substitute this for “Third Person Character” if it helps understand the error and screenshots)

I’ve tried changing the input action to use a switch to control which event to fire, as to my understanding, this should work better for what I want to achieve? Though the results, on testing, are identical to the previous method.

Another update (Still not got this working):

Found this really old post: Why are Client character animations not running on the server?

Have you looked into your character’s mesh MeshComponentUpdateFlag? By default it is set to EMeshComponentUpdateFlag::AlwaysTickPose which means tick, but don’t update bones. You would want to set it to AlwaysTickPoseAndRefreshBones.

This doesn’t even look like it’s still there any more? At least, I can’t find the option from the character mesh as suggested.

image

The only other response that seemed to harbour a result was this:

However, I’m not even using custom skeleal meshes at this point, and certainly not more than one within the actors Blueprint, as you can see here:

image

This lead me to wonder if attaching the actor to the component somehow counted as an additional skeletal mesh, as far as the logic is concerned, but that event is only called partway through the animation, so if that was the case surely it should play the first part of the animation before it goes wrong?

As you will see, I started spamming the blueprints with print strings to try and figure out what might be going wrong, and that lead me to find that when the highlighted node was set to “Multicast” & “Reliable” it was only being called on the client, and not on the server.

As such I’ve now set it to “Run on owning client” and the first thing the event does is call the “Input Action Pick Up on server” event, which runs the same logic as itself.

The following snippet is from the AnimGraph of my character, it calls an event which attachs the actor I want to “Pick Up”. I can’t find anything that tells me whether this even is replicated or not, and no option to adjust it. I assume that it is only run on the client, as an AnimNotify is most likely going to be used for local stuff anyway, instead of stuff crucial to being run on the server. As such it calls a custom event on the character.

As you can see, I’ve set this event to “Multicast” & “Reliable” so that it runs on the server and on all clients, as the result of the event needs to happen for all players.

When executed as the server: It attaches to the player for the server and the client.

When executed as the client: It attaches to the player as the client, but does not attach on the server. A print string at the end has proven that the event is still being called for both the server and the client, no matter which executes it.

This is about the most simple set-up in the game and it still doesn’t work as it looks like it should? If anyone could steer me towards what I’m missing with this, it would really help me out, as on the surface it looks like the result should be the same on both, as both.

No one else might be looking into this, but I’m still playing around with it whenever I get an idea to try, or discover something about setting things up for multiplayer.

I’ve been swapping nodes around to try and help pin-point where the problem might be. I started with the “Set Lifting” Node, because I wanted to find out if the animation would play on both server and client side, or if something in the set up was preventing it.

“Set Lifting” Position 1:

From the server perspective:

Server character does play the lifting animation when picking up the box, and picks up the box.

Client character does play the lifting animation when picking up the box, but does not pick up the box.

From the clients perspective:

Server character does not play the lifting animation when picking up the box, but picks up the box.

Client character does play the lifting animation when picking up the box, but does not pick up the box, and gets stuck in the “Hold” animation.


“Set Lifting” Position 2:

From the server perspective:

Server character does play the lifting animation when picking up the box, and picks up the box

Client character does play the lifting animation, but does not pick up the box, and is stuck in the “Hold” animation

From the clients perspective:

Server character does not play the lifting animation, but does pick up the box.

Client character does play the lifting animation when picking up the box, but does not pick up the box, and gets stuck in the “Hold” animation.


Thereisn’t much of a difference between these positions, however the character does perform the animation on both the client character and the server characters, but only on the server, and only when it screws up the rest of the logic.

From what I can tell, this means that the animation blueprint is set up in a way that it should be possible to get it to work!


I changed the custom event to a multicast and this gave the desired effect on both the server, and the client, but only on the server character. Still doesn’t work on the client’s character for either the client or the server. My understanding is that multicast should run the logic on the server and on the client, so the result should be the same for all? In my case, why is it not?