Issue With Actor Ownership

I’m working on a rather simple project to help familiarize myself with how multiplayer works in UE4. I’ve worked with server-client communication in various projects in the past so it’s a concept I’m fairly familiar with.

What I am struggling a bit with understanding though is the ownership. For example I’m making a scenario where there’s this launcher that shoots a ball(projectile) every 2 seconds. The goal is for the player to be able to grab the balls mid-air, sort of like dodgeball.

This actor is placed inside the level and spawns the projectiles via the server. The projectile has two server-sided events for launching the projectile and stopping it. Launch is called immediately.

The problem I am having is that the client can’t catch the ball. I have a box collision in front of the character which I use for detecting overlaps.

It detects the overlap, casts to my projectile class and I try to call the server-sided event to stop the projectile. This does not work for clients, only the server.

I’m fairly certain this has to do with ownership since only the owning client can call a server-sided event, right? Then how would I go about making something like this work? It’s a relatively short-lived projectile and no owner is set when it’s spawned.

I’ve also tried to use bAlwaysRelevant but I couldn’t notice any changes.

Hi, the only client that can call “Run On Server” on an actor, is the client that owns the actor. By default the client only owns its player controller and its possessed pawn.

You can set new owners only on the server via the “Set Owner” node, but in this case I would not do this.


Basically you should view the client most of the times only as Monitor + Input, but no logic. All game relevant logic should happen on the server.

So when the client receives an input from the player to catch the ball, it directly sends an RPC to the server and the server then does all the logic (so client only handles the input but not the logic) and since everything is replicated the client will then see it.

And of course you would need to put all the player input either into the player controller or into the possessed pawn.

1 Like

Can you show an image of the code where you’re doing the overlap detection?

If you add a collision box inside the blueprint editor it should also exist on the server and the overlap event should fire on server and client. You would then execute the logic to stop the ball on the server (so basically you would need to do the overlap detection server-side).

Can you do a print directly after the “OnComponentBeginOverlap”, so before the branch and see if the server prints anything, or if only the client is printing? (So in the game where you will see the print there will either stand “Server:” or “Client:” before the print output).

And how did you add the CollisionBox, just through “+AddComponent” in the blueprint editor?

Thanks for the reply!

My problem is how I would approach this particular scenario, since the overlap detection is done client-side. The box collision is attached to the player’s pawn.

So when a collision is detected and the player was “blocking”, it would try and stop the ball. But since no owner is set for these balls when they’re spawned - I can’t do this with the clients.

Would the better way be to check for overlap within the ball’s blueprint instead? And then get the owning player controller from the overlapped pawn?

Sorry if this sounds confusing, not sure how I should describe the issue. :stuck_out_tongue:

That’s how I’ve currently got it set up, but the authority part never triggers since the detection is done client-side. Also tried setting the box collision component to replicate - but it had no effect.

Ok good, if it the server prints something, that means the server is executing this code, so the problem is between the branch and the “Cast To”.

Can you do a couple of more prints to pinpoint the problem? So one print after the branch, another after “Switch Has Authority” and the last one after the “Cast To” and see whether or not the server prints anything for each print.

Aye, it prints for both the Server and Client upon collision. It was added via AddComponent, yes. :slight_smile:

Seems the server stops executing directly after the branch…?

Guessing those variables should be set by the server since they’re replicated…

Ok, can you show the code where you set “Is Blocking”?

Yup, you would need to set those on the server.

If a variable is replicated that means when it is changing on the server, the server will replicate those changes to all clients. But this only works one way, when the client wants to tell the server something you would need to use an “Run On Server” event.