Mirror: Bullet with physics not moving another player object.

I have a multiplayer game where players shoot each other with bullets. The bullets should “push” the players’ rigidbodies when they’re hit. The bullet is spawned on the server, has mass, and has force applied to it. The OnCollisionEnter for the bullet looks like this:

    private void OnCollisionEnter(Collision collision)
    {
        if (!isServer)
        {
            return;
        }

        Debug.Log("Server Bullet:  Hit.");
}

Very simple.

Situation:
Player1 (host + client) fires a bullet and hits Player2 (client only)
Result:
Player1’s screen shows the bullet “push” Player2’s rigidBody, but Player2’s screen shows the bullet hit and does NOT push Player2 back. I suspect this is because Player2’s authority over his own position takes precedent over the location calculated by the server’s physics? I’m totally guessing, though.

What’s interesting is that when Player2 (client only) fires a bullet and hits Player1 (host+client), both players see the bullet push Player1 back correctly. It seems that because Player1 is also the server, it makes the physics work when he’s hit.

How can I make it so that the physics of a collision on the server update the player’s position? Do I need to handle the forces myself?

Thanks!

Do you have a Network Transform component attached to the player prefab?

I do, yes:

I also have it on the Bullet prefab that one player shoots and hits the other player:

You can create a client rpc call to update the client player’s position with that of the server. I’m wondering though why the collision and push back aren’t already happening on the client, or did you want that to be server side only?

What’s weird is that I think the server position is updated. I think the problem is that the Player who got hit has client authority and ignores the server’s update on their position. I don’t understand the authority system enough to know why, but my gut says that the Player’s authority overriding the server position has something to do with it.
I’ll try the ClientRPC, but it seems like the purpose of NetworkTransform is to keep the client’s position updated without an explicit call back to the client.

I’ve only tinkered with it to be honest, but I’d say you’re on the right track.

With Client Authority ticked the client will dictate the player position to the server. If the player position only changes on the server it won’t be automatically sent to the client. If the client is not informed of the server position, once the client player moves it’ll put client and server back in sync overwriting the pushed back position.

I don’t know what the best solution is but an rpc call is one option.

One last note for those who follow and get stuck on this in their first few days with Mirror. I had to kind of triangulate this information from multiple videos, docs, and forums before I understood it. @cerestorm - your hints helped.

First, you need to understand the authority model on NetworkTransform. Client Authority means that the client owns their position. This is super easy to implement. You just check the client authority checkbox on NetworkTransform and Mirror will do the following:

  1. Allow you to move the local player using physics or translations.
  2. It will update the server with the new position
  3. It will sync from the server back to all the other clients (who have an interest in the position)

That’s a really easy way to get the game up and running, but it has some limitations.
First you run into my situation. When one player causes a second player to be repositioned (by bumping into them or pushing them with a projectile), you can update the impacted player’s position on the server, but the server doesn’t own that position. Next time the impacted player moves, they send their new position to the server and overwrite the server’s position.
Second, allowing client authority lets players cheat. This generally isn’t considered a problem until your game takes off, but one can choose to implement server authority early if wanted.

So now that you’ve decided to use server authority on NetworkTransform for the players, how should that work? This post from vis2k (creator of Mirror) was the key. He describes simply how he intends NetworkTransform to work in a server authoritative model:

In short:

  • Player sends and command to the server asking for movement. For example, CmdPleaseMoveMeTo(xyz);. It seems most people send the controller inputs to the server, rather than a requested position, but this will depend on your game.
  • Server checks if this is a valid move. Most people validate the controller inputs here.
  • Server moves the player there. This is also where the server can do things like decrement your ammo, make sure you had the item in your inventory, etc.
  • NetworkTransform automatically syncs the new position to all clients

I hope that helps someone in the future.

1 Like