Netcode For Gameobjects

Hello. I need some help with multiplayer. I have purchased the new multiplayer course and so far everything works as it is suppose to(I have completed the first section to the combat polish) but I don’t understand the material very well.

This is my first attempt with multiplayer and I am having trouble understanding the client vs server actions. I am trying to reinforce the learnings by applying to my own project. What I’d like to do is have a loot box. If the client interacts with it I need the box sprite to change to an open state and have that by synced on the host and clients. Then I want to spawn objects about the box for the players to pick up.

What I have tried so far is to subscribe to the OnDie action so that the player can shoot the loot box and “Kill” the box and that will trigger the following

sudo
subscribe to OnDie += BreakOpen

(BreakOpen)
OpenChestServerRpc
OpenChestClientRpc

(OpenChestServerRpc)
Instantiate loot
update sprite

(OpenChestClientRpc)
update sprite

This seems to work ok but not sure if this is the correct way or is there is a better way. Also I’d like to have the open to have the player walk up and interact with the loot box. This is where I get lost. I am not sure the best way to let the server know. I tried the following

Sudo Code

Button Press to interact triggers (Open)

(Open)
OpenChestServerRpc

(OpenChestServerRpc)
spawnloot
update sprite

When I do this interacting on the host seems to work fine triggering the host update and the client but if I interact with the client there is no update on either.

Any help would be greatly appreciated. Or pointing to some material. I have looked at the unity docs and codemokey multiplayer tutorial as well. Still confused. :slight_smile:

It sounds like what you are referring to is loot boxes and although this might be a little different the code should give you a jumping off point to be able to get this implemented.

https://docs.unity.com/ugs/solutions/manual/LootBoxes

Let me know how you get on with this and if it helped at all

I would first check if the RPC is being sent correctly. Debug.log that on the server to see if it’s being called. Is your script inheriting from NetworkObject?

Hey. No this isn’t what I am looking for. Maybe loot box was a bad term. I meant chest or crate or a pot. Player walks up and opens. Finds loot, gear etc.

The RPC is being sent when in the first example. I think its because in the multiplayer tutorial the health is managed on the server so when the crate dies and the OnDie is called the server knows.

However, in the second example where I am trying to have the client walk up and interact nothing gets called on the server.

public void Open()
{
    OpenChestServerRpc();
}
[ServerRpc]
void OpenChestServerRpc()
{
    Instantiate(square);
}

There’s probably an error. Run the built game as the host and connect via the editor. Then you’ll see the error in the console. SeverRPC requires ownership by default. I suspect the caller is not the owner, so it can’t call the server rpc

You rock! I keep putting the client on the window and the host in Unity. I feel stupid lol.

I am getting that exact not saying only an owner can call. I think I read something about adding a parameter to [ServerRpc] that will change the permissions. I will try that.

But is that the correct way? I think that is what confuses me most on this multiplayer stuff. I feel like I am hacking my way to just getting it to work.

What I will do if that works is

public void Open()
{
    OpenChestServerRpc();
}
[ServerRpc]
void OpenChestServerRpc()
{
    //spawn loot
    Instantiate(square);
    //update clients about spawned loot

    //update chest sprite

    //tell clients
    OpenChestClientRpc();
}
[ClientRpc]
void OpenChestClientRpc()
{
    //update chest sprite
    //no spawning since the server already did
}

It’s something like this

[ServerRPC(RequireOwnership = false)]
void OpenChestServerRpc()
{
    //spawn loot
    Instantiate(square);
    //update clients about spawned loot

    //update chest sprite

    //tell clients
    OpenChestClientRpc();
}

Thanks! I will try that.

Is setting requireownership = false the proper way? I get it is needed to solve my specific issue. But is there a better way or more correct way to update an object that is shared between the client(s) and server?

I don’t know. But I don’t know any other way of calling asking the server to do something with something I don’t own.

Tested this and it works fine. Marked as the solution. Thanks again.

1 Like

So I think the parallel to this in the course is the coin pickups. We are using physics detection here to trigger the pickup. Notably, a script on the player (CoinWallet) is what triggers the pickup, not the coin itself. The physics detection is done on the server and so the picking up of the coin is handled on the server as well.

So I think the approach for this should be that a script on the player object calls to the server (via server RPC) to ask if it can open the chest, with some reference to the chest. Since the client owns the player, you shouldn’t have any issues calling. Then the server validates that you can open the chest, handles all the chest logic and syncs the player and chest states back to the clients.

Let me know if that makes sense, I can try and break that down further if you’d like.

1 Like

Ah, this. Yes. This is the way

1 Like

Thanks! I will try this approach. Wont be able to work on it again until the weekend but I will post back updates so others can see results if interested.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms