Authority with UNET client

437 views Asked by At

I need to modify a non-player object. I am able to do it but for some reasons, I get warning:

Trying to send command for object without authority.
UnityEngine.Networking.NetworkBehaviour:SendCommandInternal(NetworkWriter, Int32, String)
ModelControl:CallCmdSetCube()
ModelControl:Update() (at Assets/Scripts/ModelControl.cs:21)

I have gone through the unity docs and the various answers but the weird part is that it does work but I wish to prevent the warning.

First there is a Manager object that creates the neutral object. This happens on the host.

public class ObjectControl : NetworkBehaviour
{
    public GameObject cube;
    public override void OnStartServer()
    {
        if (GameObject.Find("Cube") != null) { return; }
        GameObject cubeInstance = (GameObject)Instantiate(this.cube,
            new Vector3(0f, 0f, 5f), Quaternion.identity);
        cubeInstance.name = "Cube";
        NetworkServer.Spawn(cubeInstance);
    }
}

Then each player has the following:

private void CmdSetCube()
{
    GameObject cube = GameObject.Find("Cube"); // This is the neutral object
    if (cube != null)
    {
        NetworkIdentity ni =cube.GetComponent<NetworkIdentity>();
        ni.AssignClientAuthority(connectionToClient);
        RpcPaint(cube, new Color(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f)));
        ni.RemoveClientAuthority(connectionToClient);
    }
}

[ClientRpc]
void RpcPaint(GameObject obj, Color col)
{
    obj.GetComponent<Renderer>().material.color = col; 
}

The host does not trigger the warning. Only the remote clients gets the warning. When I have many clients, I can see in the editor console that it will print as many times as there are clients. But again, it does actually work, I can see the new data being propagated to all sessions but I am expecting something to go down later on.

1

There are 1 answers

0
Everts On BEST ANSWER

So the issue came from the Update method:

void Update()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        CmdSetCube();
    }
}

The problem here being that all instances of that script will run the code while only one is really getting authority.

Solution:

void Update()
{
    if (this.isLocalPlayer == false) { return; }
    if (Input.GetKeyDown(KeyCode.Space))
    {
        CmdSetCube();
    }
}

Add the line to make sure this is the local player calling.