unity tag script prefab from create c# networking unity3d unity3d-unet

c# - tag - Unity3D. Intentando enviar un comando para un objeto sin autoridad



unity static inspector (2)

No puede enviar un comando sin la autoridad local.

if (!isLocalPlayer) return;

Pero, ¿qué tipo de datos está enviando con este comando? En general, y como dijiste:

"su estado debe estar sincronizado en el servidor"

Entonces, en mi humilde opinión, no tienes motivos para enviar un Command desde tu reproductor. Los comandos deben ser para la entrada del jugador. Estas entradas activarán acciones en tu juego. Su gerente obtendrá información de estas acciones (actualización de puntuación, final del juego ...) y enviará datos y / o activará acciones en los clientes, utilizando ClientRpc

Este es el modelo de autoridad del servidor. Si permites que un objeto local envíe comandos, un pirata informático podría entrar y decirle fácilmente a tu gerente

"Oye, es mi turno. Oye, es mi turno otra vez. Oye, mi puntaje es 9999999 y gané el juego en 1 segundo".

Tengo un juego de estrategia por turnos para varios jugadores que necesita un administrador de juego, que controle el estado actual del juego (a quién le toca, etc.). Este administrador debe ser común para cada cliente, su estado debe estar sincronizado en el servidor.

He aquí cómo estoy haciendo esto: el objeto del administrador del juego es NetworkBehaviour y tiene NetworkIdentity, que no es la autoridad del jugador local ni la autoridad del servidor. Creé un NetworkManager personalizado y genera Game Manager en la conexión de cliente, también probando si es un servidor. Aquí hay un código:

public override void OnClientConnect(NetworkConnection conn) { ClientScene.Ready(conn); if (NetworkServer.active) { var manager = Instantiate(MultiplayerManagerPrefab, Vector3.zero, Quaternion.identity) as GameObject; var tacticsManager = manager.GetComponent<MultiplayerManagerModel>(); NetworkServer.RegisterHandler(MsgType.AddPlayer, tacticsManager.CreatePlayerOnServer); NetworkServer.Spawn(manager); } ClientScene.AddPlayer(0); }

Cuando lo ejecuto en un servidor funciona bien, crea una instancia en un cliente y sincroniza variables de servidor a cliente. Pero cuando intento ejecutar comandos desde el cliente, los ignora, lanzando esta advertencia:

Intentando enviar un comando para un objeto sin autoridad. UnityEngine.Networking.NetworkBehaviour: SendCommandInternal (NetworkWriter, Int32, String)

Tenga en cuenta que este Administrador de juegos se genera antes que cualquier jugador porque debe ser responsable de generar jugadores. ¿Qué estoy haciendo mal?


Al lado de su fragmento de código, la advertencia

Intentando enviar un comando para un objeto sin autoridad.

Significa que: estás enviando un comando desde un objeto cuya autoridad, tu (jugador) no tiene.

Qué estados de Unity establece: Los comandos se envían desde los objetos del jugador en el cliente a los objetos del jugador en el servidor. Por razones de seguridad, los comandos solo se pueden enviar desde el objeto de su jugador, por lo que no puede controlar los objetos de otros jugadores.

PERO

Comenzando con la versión 5.2 de Unity , es posible enviar comandos desde objetos que no son jugadores que tienen autoridad del cliente. Estos objetos deben haber sido generados con NetworkServer.SpawnWithClientAuthority o tener autoridad establecida con NetworkIdentity.AssignClientAuthority. Los comandos enviados desde estos objetos se ejecutan en la instancia de servidor del objeto, no en el objeto de jugador asociado para el cliente ( más ).

Entonces, ¿cuál es la solución? Antes de enviar el comando (o ejecutar la función de comando), asigne la autoridad de ese objeto a su reproductor. Algo como esto

assignAuthorityObj.GetComponent<NetworkIdentity>().AssignClientAuthority(this.GetComponent<NetworkIdentity>().connectionToClient);

" this " se representará a su objeto Player. Después de realizar una llamada de comando, puede eliminar la autoridad utilizando este fragmento de código.

assignAuthorityObj.GetComponent<NetworkIdentity>().RemoveClientAuthority(this.GetComponent<NetworkIdentity>().connectionToClient);

De nuevo, " esto " representará a su objeto Jugador.

Nota: Por lo general, asigno la autorización de un objeto (si deseo usar eso) usando OnTriggerEnter y elimino la autoridad en OnTriggerExit. Depende de un escenario específico que el evento en el que desea adquirir o eliminar una autoridad de objeto.