Download

How to know on client side if an actor is "own" by the current network connection

Hi,

It must be simple but I can find/remember a way to know if an actor is “own” by the current connection.

I mean if you have 2 client and 1 server.
If Pawn A is created for client A, how can I know this when working on the Client A Pawn instance?
Pawn A will also be replicated on client B, so I think there is something to say “you own it”?

Thanks for your help,

I guess that you can use GetNetOwner() or HasNetOwner() but I haven’t used it myself yet.

Assuming your pawns are spawned by setting AGameMode:: DefaultPawnClass it becomes quite easy; check the state of Role.

if (Role == ROLE_Authority) ; // Will always mean server version.
if (Role == ROLE_AutonomousProxy) ; // Will always mean the client that ‘owns’ the actor.
if (Role == ROLE_SimulatedProxy) ; // Will always mean the client(s) that are just copying the actors data from the server.

I haven’t got experience trying to spawn actors in a multiplayer game outside of DefaultPawnClass so I can’t say what the right technique is. Should be the same thing though.

Thanks for your answer. I will check your proposal to see how it behaves.

for the Role Autonomous, it will only work for actor that are owned by the PlayerController as per the definition on this page: https://docs.unrealengine.com/latest/INT/Gameplay/Networking/Actors/Roles/index.html
So roles won’t work for my case.

@ MaxL No, thats not right.

HasAuthority (Role == ROLE_Authority) doesn’t mean server object and ROLE_AutonomousProxy doesn’t mean the object is owned by the client. The instance that spawned the class is always ROLE_Authority. If an Actor is spawned on the client, the client is the authority. And ROLE_AutonomousProxy means the same as SimulatedProxy, but the client has also right to call RPC calls (be carefull with that #cheating).

So, if you want simply check if a client is the owner, HasAuthority() or Role == ROLE_Authority is good, but remember, it doesn’t mean you are the server.

Maybe just add a boolean to your class like bIsServerObject. Together with HasAuthority() you can then be sure that you are on a client (or the server).

And concerning the owner stuff:

When you spawn an instance of a class on the server FOR Client A, you have to set him as the owner.

FActorSpawnParameters params;
params.Owner = PlayerAPlayerController;

SpawnActor<Class>(Class:StaticClass(),params);

Then on Client B you can say IsOwner(PlayerBPlayerController), which should return false.

+1 for OmaManfred for pointing out the distinction between authority and net owner. So to check whether an actor is owned by the local client, you can call AActor::IsOwnedBy(LocalPlayerController).

An easy way to get the local player’s PlayerController is by using UGameplayStatics::GetPlayerController( SomeWorldContextObject, 0 ), where SomeWorldContextObject simply put can be any UObject that is linked to your current game world, like an actor. To summarize, to check within an actor whether the local client has net ownership:



void AMyActor::MyFunc()
{
   bool OwnedLocally = IsOwnedBy(UGameplayStatics::GetPlayerController(this, 0));
}


OmaManfred: There’s a reason I said “Assuming your pawns are spawned by setting AGameMode:: DefaultPawnClass it becomes quite easy; check the state of Role.” first, but thanks for clearing it up.
I didn’t know how to set the owner though, thanks.

@OmaManfred
Checking the role Authority is not correct. On a client, it won’t be set to Authority

From the docs:

On the other side, I can’t test the Owner as it can be “nearly any actor”. The owner is not always a PlayerController. You can define it as is during spawn, but in my case, the owner is a Pawn. (The owner defined can be used to know the actor replication is relevant on other connection, so settings it to another actor than PC is very interesting in multiple scenarios).

@NisshokuZK
IsOwnedBy will work if in the hierarchy of the ownership there is the PlayerController at some level (It loop & test against owner and owner of owner).
It might work in my case, but it’s not 100% relevant
If you take a case where you spawn a projectile where the owner is the weapon which owner is the pawn which is the PlayerController, if the pawn died before the Projectile Exploded, during ExplosionEvent, you won’t be in position to know if it’s owned by the local PC.

Thanks,
Ps: so my initial question is not so obvious ^^

It depends on your situation! But since you’re talking about the pawn, the only pawn that is “owned” by the client’s network (done already in most cases), is the pawn that the client is controlling. So you need to have their Owner equal to the controller of that player. With that in mind, you can just use



YourPawn::Function()
{
if(IsLocallyControlled()
{
  //Client version of the pawn
}
else if(HasAuthority()) //Pawn's Authority is set to the SERVER
{
 //Server
}
else
{
  //everyone else!
}


Sorry for the confusion, the Pawn was just an example. In my case it’s not the pawn actor that I’m trying to identify, it was for the understanding of my question but that leads to confusion as the Pawn is a special case that you test easily ^^

From the different answer, there are no “simple” way to do this. I will find another approach of my problem of solve this by replacating a bool value only on the owner at the startup^^

IsLocalController() for Player Controllers. IsLocallyControlled() for Pawns.

They are the only objects that are ever owned by a local player, which is also why they are the only objects you can call RPC’s from (aside from components of those actors) as well. Other Actors don’t have a client-owner, UNLESS they were spawned client-side (but of course, they will ONLY exist there if that happens).

This part is not true. I have actors that are not Controller/Pawn that are using RPC call without any issue.

You can still call RPC’s on non-Controller/Pawns. Any Actor that’s set to bReplicated = true can have an RPC.

If you’re trying to do a separate class then you probably want to use the Authority method. Most all objects give the server Authority unless spawned by the client (and will only exist on the client). These objects are rare, but can be frequently used. Such as explosions, blood splatters, unimportant gameplay actors (such as random physics actors that don’t alter gameplay), etc. These are usually special effects in short. A few other things that exist for the client I believe are things such as the HUD (if I remember correctly) only ever exists for the client. So then you don’t have to worry about server/client/owning-client situations.

For all other actors, it’s a case-by-case basis. An “owning” client will have the ROLE == Authority. So I think you may be mixing up your terminology a little. Do you want to know WHO owns it? Or which computer is running it? Server Version or Client Version? Those are different concepts.

In most cases you only want to figure out which version of the object is running currently. I’d use an approach like so



if(HasAuthority()) //Server
{
  //Server Stuff
}
else //All Clients
{
 //Client Stuff
}


Without knowing what you’re working with that’s the “generic” form of how to tell between Server/Client. But it’s not a guarantee.

I know for certain that you can’t call RPC’s from any Replicated Actor, the client must be the owner.

See Here:

Discovered this the hard way when we tried to make three players control one actor in Multiplayer. Essentially they have to send all RPC’s through their own Pawn and then interface with the Actor instead.

In terms of clients, sort of, yes. If you want to use a Server/Client RPC you must own the object for a client to send/receive an RPC. But if a Multicast is called (which is an RPC) you can receive them even if you don’t own them (although not send). I was under the impression you meant in general (including server).

Ah yeah I see what you mean, I just meant the Client requesting the Server to do something on an object :slight_smile:

Hi,

Thanks for the answers.

In mybcase, I wanted to know on client side, if the Actor was “owned” by the client connection. The answer is: Depanding on the type of actor and the owner( GetOwner()) trees, you may or not get the information (see answer in the thread).

When a thing seems simple is not implemented, it’s usually that what you want to do is not the proper way to do it. In my case, after thinking to the problem another time, I took it in another way that solves all the bottleneck that I faced with this “client ownership questions”

Thanks all for your time. I discover some functions that I never met before so it was more that useful.