Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Join us on Dec 8, 2022, between 7 am & 7 pm EST, in the DOTS Dev Blitz Day 2022 - Q&A forum, Discord, and Unity3D Subreddit to learn more about DOTS directly from the Unity Developers.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Question Mirror: Prevent destruction of objects with client authority on client disconnect

Discussion in 'Multiplayer' started by DasMaeh, Dec 13, 2020.

  1. DasMaeh


    Oct 18, 2017
    Hey everyone,

    I am working on a multiplayer project using Mirror in the background. It is a VR game, so the server initially takes care of all items lying around in the scene. If a client wishes to pick up an item, the object's authority will be transferred to the client.

    My problem is now: If the client disconnects from the server while having authority over an item, the object gets deleted with him. I need a routine that resets the authority back to the server instead of deleting the item.

    My initial idea is to override NetworkManager.OnServerDisconnect(). And at anytime a client disconnects, I ran a loop over all objects to look for the missing ones and respawn them. But keeping track of all objects and their transforms to respawn them in place is a lot of overhead compared to just resetting the authority. Especially, as most objects are not a prefab and therefore not registered with the NetworkManager, as they are gameplay-wise not intended to be respawned. (As far as I understood it, for NetworkServer.Spawn to work, the object needs to be registered first)

    Does anyone of you have a smarter solution to it?
    brainwipe and Kokowolo like this.
  2. DasMaeh


    Oct 18, 2017
    In the end, I prevent the destruction of the objects in the first place.

    Down "/Assets/Mirror/Runtime/NetworkConnection.cs" there is the function "DestroyOwnedObjects()". I basically RemoveClientAuthority() for every object except the disconnected client's avatar gameobject, which gets destroyed. This code is not a beauty, especially that I need to reapply this patch every time I update Mirror, but it works.
    Kokowolo likes this.
  3. Kokowolo


    Mar 26, 2020
    Hey, having a similar problem as well where I want all Networked objects to persist after the server/client shuts down. I'll let ya know if I have any solution that could be applicable, but I was considering the same solution as you found.

    While my issue is slightly different (all networked objects vs. only networked objects with client authority), I was thinking that in your case, is it possible to avoid giving authority to the client in the first place? Does the client really need authority over the objects they pick up? If you need to run a command that utilizes these picked-up objects, you could have the command header utilize the parameter [Command(ignoreAuthority = true)] while passing the client's connection as a parameter for the method. In this command you could then validate whether or not the player's character is holding the object on the server. Hope this helps, if not, glad you found a solution that works.
  4. brainwipe


    Aug 21, 2017
    My solution for removing all client owned objects to stop them despawning is:

    Create a NetworkManager of your own:

    Code (CSharp):
    1. public class MyNetworkManager : NetworkManager
    2. {
    3.    public override void OnServerDisconnect(NetworkConnection conn)
    4.         {
    5.             var ownedObjects = new NetworkIdentity[conn.clientOwnedObjects.Count];
    6.             conn.clientOwnedObjects.CopyTo(ownedObjects);
    7.             foreach (var networkIdentity in ownedObjects)
    8.             {
    9.                 networkIdentity.RemoveClientAuthority();
    10.             }
    12.         }
    13. }
    You need to copy the clientOwnedObjects into an array because it's a HashSet collection that gets changed when you call RemoveClientAuthority().