UNet server spawning objects can't be interacted with

I am spawning some targets on the server (a function with the [ServerCallback] Attribute.
Everything syncs up nicely but when I try to shoot them and call the hit function which calls a function with the [Command] Attribute I get “Trying to send command for object without authority”.

So i tried setting player authority but no luck at all!

 [ServerCallback]
        public virtual void SpawnObj(GameObject obj)
        {
            GameObject spawnObj = Instantiate(obj) as GameObject;
            m_Spawns.Add(spawnObj);
            
            NetworkServer.Spawn(spawnObj);
            RpcGiveAuth(gameObject.GetComponent<NetworkIdentity>());
        }

        [ClientRpc]
        private void RpcGiveAuth(NetworkIdentity id)
        {
            id.AssignClientAuthority(NetworkManager.Instance.client.connection);
        }

I have tried another way using SyncVar Hooks, but once again these are only picked up when the var is changed on the server, which means i need to use Command again so still need authority. Is there a better way of doing this?

ServerCallback attribute should be used for the standard MonoBehaviour methods like Update or Start. It means they’ll run only for instances in the server. I you want a custom method to run only on the server you have to use the Server attribute. Also, check if what you want here isn’t actually a Command function. Server and ServerCallback attributes make the method return authomatically if it’s not running on the server, so if you call those functions in a client nothing happens, while Command makes a method called on a client to be executed on the server.

NetworkIdentity.AssignClientAuthority should be called in the server, the server is the only one that can set who has authority over something, otherwise any client could take authority on anything. Since you’re calling that method in a function marked as a ClientRPC, you’re calling AssignClientAuthority on the clients, which does nothing, and if it did something, you’ll be giving authority over something to all clients, which doesn’t make sense.

Also, you’re spawning a GameObject and have a reference on the spawnObj variable, but you’re sending the NetworkIdentity of the gameObject with that script attached. You have to assign authority to the spawnObj’s NetworkIdentity component.

So, something like this might work, or at least be closer to working:

[Server]
public virtual void SpawnObj(GameObject obj)
{
    GameObject spawnObj = Instantiate(obj) as GameObject;
    m_Spawns.Add(spawnObj);
         
    NetworkServer.Spawn(spawnObj);
    NetworkConnection clientConnection = ; //Here you have to select a client and get the network connection to that client, I can't guess how you'll decide that.
    NetworkIdentity id = spawnObj.GetComponent<NetworkIdentity>();
    id.AssignClientAuthority(clientConnection);
}