Полномочия с UNET-клиентом

Мне нужно изменить неигровой объект. Я могу это сделать, но по некоторым причинам я получаю предупреждение:

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)

Я просмотрел документы по единству и различные ответы, но странная часть заключается в том, что это работает, но я хочу предотвратить предупреждение.

Сначала есть объект Manager, который создает нейтральный объект. Это происходит на хосте.

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);
    }
}

Тогда у каждого игрока есть следующее:

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; 
}

Хост не вызывает предупреждение. Только удаленные клиенты получают предупреждение. Когда у меня много клиентов, я вижу в консоли редактора, что она будет печатать столько раз, сколько есть клиентов. Но опять же, это действительно работает, я вижу, как новые данные распространяются на все сеансы, но я ожидаю, что что-то пойдет дальше.

1 ответ

Решение

Итак, проблема возникла из метода обновления:

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

Проблема здесь в том, что все экземпляры этого скрипта будут запускать код, в то время как только один действительно получает полномочия.

Решение:

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

Добавьте строку, чтобы убедиться, что звонит местный игрок.

Другие вопросы по тегам