Is Locally Controlled returns True for remote players?

I have two clients running the example first person tutorial. I’d like to operate on just the local client’s actor.

I tried to use the ‘Is Locally Controlled’ function, but it seems like it’s returning true for both the local player and the remote player.

How can I get a Boolean value that returns true if the Actor/Pawn is the local client?

EDIT: Could this be because the actors are replicated? When one actor detects it’s a local client, both clients see the result. How could I remove mesh visibility from being replicated?

19739-islocallycontrolled.jpg

APawn::IsLocallyControlled It will return true if it is controlled by a local (not network) Controller.(from the documentation).

That link breaks down how IsLocallyControlled works, if you’re curious.

As far as I can tell this only matters on the machine that’s running the code. You would have to run that code exclusively on the server without replicating it on the client. There are some good UE4 tutorials on YouTube for starting with networking and replication if you’re new to the subject.

This is a known issue with replicated pawns. The internal flags that are used to determine local control have not been properly set up yet when the BeginPlay event is called.

It is possible to work around this issue, by moving the logic that depends on the IsLocallyControlled check to the PostLogin event on the game mode. Inside the PostLogin event (and thereafter), IsLocallyControlled should return the correct value. PostLogin only runs on the server though, so if you also want to handle it on the client, you’ll need to create a custom replicated event and call it from PostLogin.

Did you ever find a solution to this?

hi, when will it be fixed, still returning true for remote players in 4.10

Short Answer:

I think the function you are really looking for is a blueprint node called “IsServer” This will return whether you are on a Dedicated or Listen Server when true or if you are on a Client when false… and Get Player Controller with index 0 will always get the controller that belongs to the machine.

If you want the long winded explanation…

There is a way to determine if you are working with the “LocalController”. Forewarning My Replication-foo is strong but not expert, plus I am running off 100% memory at the moment with no method to actually test. I assume what you are searching for is a method to determine if you are dealing with the controller for that client. I’m not entirely sure why “Is Locally Controlled” is always true… But as a background to replication all controllers exist on the server and are replicated to THEIR respective clients. This means that in games where two people are connecting to a server who is also running the game (3 players total), there will exist 3 player controllers on the server but the two clients will only have 1 player controller. In a game with a dedicated server the (2 players total) two controllers will exist on the server and the clients will have only one. It maybe possible that Is Locally Controlled is meant to be used in the Dedicated Server senario.

There is a blueprint function called “IsServer” which determines if your code is currently executing on on the server. Now you need to get the controller for that machine so you can get the Pawn. When you are using a Listen server, (3 players, 2 networked clients), there is a function called “Get Player Controller” which takes an index of the player. This function can be called on the server and the client. In a Listen Server scenario Calling GetPlayerController(0) will always return the Player Controller that “belongs” to that machine. So on the server, index 0 will get the player who is running the server, on a client index 0 will get the player who is connected to the server. In a Dedicated Server Senario, on the server, it will get who ever is first, most likely the first client who connected, on the clients it will get the client who belongs to that machine.

So to answer your question completely… If you are on a dedicated server check to see if “Is server” is false, if so then hide the mesh of the Pawn owned by the player controller at index 0. If you are on a Listen Server than Player Controller at index 0 is always going to be the owning controller and you “simply” need to hide the mesh of the player at index 0… however… (I put simply in quotes for a reason)

I may be throwing a new wrench to your problem I am pretty sure the standard “Mesh” component that all Characters (and possibly Pawns) start with is automatically replicated. This means that any time you set properties to that mesh on the server… it’s going to replicate down to the client and poof you now have a visible mesh in your face again. (remember I’m running off 100% memory at the moment) If this is so you may need to leave the Mesh Component empty, and create a new Mesh component that replicates according to your specifications (“not owner” most likely) or not replicates at all and is set using a client/server or multi-cast function. If you are using a normal actor that does not start with a mesh component then you should be fine as you should be able to set it’s replication method or use a multi-cast or client function to update the mesh.

Is this issue on the UE4 bug roadmap anywhere? If not - can I create a ticket for it somewhere (github?)

Hmm… this solution doesn’t seem to work. I tried using IsLocalPlayerController by calling a custom event on the owning client from OnPostLogin, but IsLocalPlayerController still returns true for every player controller on both the client and the server. Something is very wrong with the system.

Still having this issue with 4.12

If anyone stumbles on this issue, the way I do it in C++ so it works even in BeginPlay is :

    ENetRole LocalRole = GetLocalRole();
    if (LocalRole == ENetRole::ROLE_AutonomousProxy || // local client controlling its own pawn
        (LocalRole == ENetRole::ROLE_Authority && GetRemoteRole() == ENetRole::ROLE_SimulatedProxy)) // we are the server controlling our own pawn
    {
...
    }
2 Likes