Jump to content
UnitySpain

Aceptamos donaciones vía Paypal.

UnitySpain.com es un servicio gratuito, pero mantener la Comunidad conlleva una serie de gastos.

Fondo Anual Unityspain: Donados 58,34€ de 150,00€

  • Servidor: Dominio.com y Hosting Web
  • Mantenimiento de los Foros
  • Contenido y Servicios Extras
  • Mantenimiento para Redes Sociales

Recommended Posts

Buenas a todos.

Hace ya unas semanitas que estoy aprendiendo uNet, pero me surge una duda con objectos se se puede droppear (soltar en el mapa) y pickup (se pueden recoger del suelo por cualquier usuario).

Ahora mismo lo tengo funcionando bien, un player se encuentra un item, lo recoge y lo añade a su inventario, luego lo suelta y aparece en el mapa, otro player ve ese objeto y lo puede recoger.

La cosa es que no se si lo tengo bien estructurado en cuanto a Commands y ClientRPCs, pongo un ejemplo inventado y en bruto para que veais como lo tengo:

 

"Al hacer click en un item, ejecuta la funcion de "Añadir Item al inventario" y la esctructura de la funciona es la siguiente:"

 

....

....

if (isItem == true)
  {
      CmdAddItem();
  }

[Command]
void CmdAddItem()
{
    //añadir item a una lista
    //modificar el nombre a item.name
    //modificar parent del item
    //añadir item a un Slot
    //indicarle al item en que slot esta
    //...y mas logica

  RpcAddItemInform();
}

[ClientRPC]
void RpcAddItemInform()
{
      if(isLocalPlayer)
  {
    //añadir item a una lista
    //modificar el nombre a item.name
    //modificar parent del item
    //añadir item a un Slot
    //indicarle al item en que slot esta
    //...y mas logica
  }

  if(!isLocalPlayer)
  {
    //modificar el nombre a item.name
    //modificar parent del item
    //indicarle al item en que slot esta
    //...y mas logica
  }
}

Este código es muy bruto es solo para ejemplificar lo que me esta ocurriendo con todo lo que tengo que sincronizar entre servidor y clientes.

Como veis, tanto lo que ejecuto en el Command como en el RPC para el LocalPlayer, como en el RPC para el NoLocalPlayer, se repiten las lineas de la lógica, con variantes ya que cada cliente tiene que saber lo que que tiene que saber, pero encuentro absurdo tanto repetir código.

Primero en el Command le doy toda la logica ya que es el server y lo tiene que saber todo o casi todo, luego ejecuto el RPC para actualizar los clientes pero con variantes según si es el playerlocal o no es el local.

Parece una tontería pero al tener ya varios Command y RPCs en el código veo muchas lineas de Lógica repetidas y tampoco acabo de ver el sentido a actualizar la información del Item en el servidor si luego al informar a los clientes les paso el mismo código a mano, al ejecutar el RPC no debería "Copiar" lo que hay en el server? 

 

En mi opinión estoy haciendo algo mal en terminos de organizacion de donde ejecutar las lineas de logica, donde ejecutar las lineas de comprobación previas a la lógica (como por ejemplo saber si tengo un Slot libre en el inventario antes de añadir el item).

 

He buscado mucho por internet pero a parte de la poca info practica, la gente lo hace de distinta manera.

 

Alguien podria arrojar algo de luz para ver como se suele estructurar las sincronizaciones servidor-cliente y que el server sea autoritativo?

Un ejemplo en bruto como el mio seria genial.

 

Saludos!!

Share this post


Link to post
Share on other sites

Averigua sobre TargetRPC.

Estás bien encaminado pero tenés problemas de lógica repetida, deberías definir los model shared y por otro lado la lógica. 

Si el servidor es enteramente autoritativo entonces los RPC no tendrían que tener conexión con la información del servidor. 

Para que no tengas problemas deberías de crear una estructura de datos para el cliente y luego utilizar la misma para cada netPeer.

Si necesitas más ayuda podemos seguir este hilo. 

Share this post


Link to post
Share on other sites

Buenas!

Pues el TargetRPC lo leí en su día pero como aún no sabia nada del networking lo deje atrás temporalmente. Parece muy útil para solventar ciertas situaciones, tengo que hacer pruebas con el.

Des de que me respondiste estuve la tarde leyendo, empapándome de mas teoría y me encontré con algo que te quiero preguntar, lo haré al final.

Puedo utilizar mi lógica para suponer a que te refieres con lo de "los RPC no deberían tener conexión con el servidor", pero para que no me queden dudas o por si acaso voy errado me lo podrías explicar porfa?

Con la estructura de datos, me pasa lo mismo, puedo verle un sentido a lo que comentas pero no lo veo en la practica.

Estoy aprendiendo a entenderlo, obviamente no busco soluciones, busco la manera de ponerlo en practica, hacer pruebas y entender el funcionamiento de lo que me comentas, así que disculpa tantas preguntas pero es un terreno complicado (o al menos a mi se me hace complicado) y llego a el des de cero.

Por cierto tambien me contre con esto: https://docs.unity3d.com/Manual/UNetVisibility.html . Me parece algo muy interesante, voy a estudiarlo y probarlo.

 

Lo que te comentaba al principio que encontré ayer leyendo por internet, es a gente con bastante experiencia con uNet comentando que al final se pasan a otra Network Solution como Photon, etc, por muchos motivos, tales como la falta de documentación, ejemplos, la falta de actualizaciones por parte de Unity sobre uNet/HLAPI..., limitaciones en cuanto a estabilidad cuando la cantidad de jugadores en el servidor es "alta" (en plan, mmo, survivals, etc..), la sensacion de abandono de este apartado por parte de Unity... Y muchos mas motivos que algunos de ellos no puedo comentar por que ni los entiendo ya que son demasiado técnicos para mi. Pero ademas lo que me sorprendió es la gran cantidad de gente que respondía a estos posts que estaban de acuerdo con el, osea que pensaban igual.

Y esto me da que pensar, realmente me vale la pena seguir aprendiendo uNet? No tendrá mas futuro (a corto y medio plazo al menos) aprender otra solución? En su momento tiré por uNet sin dudarlo porque no quería depender de un tercero, ya que si salen actualizaciones de Unity deberemos esperar a que ese tercero saque una actualización también.

Pero bueno, si la diferencia es tan importante quizas vale la pena cambiar, no lo se. Ademas quiero aprender a hacer funcionar muy bien uNet/Photon/lo que sea, antes de hacer crecer un juego, creo que es bueno ir programando el networking al mismo ritmo que crece el juego.

 

Voy a seguir leyendo cositas mientras espero tu respuesta :P

Gracias!

Edited by datmos

Share this post


Link to post
Share on other sites
hace 4 horas, datmos said:

Buenas!

Pues el TargetRPC lo leí en su día pero como aún no sabia nada del networking lo deje atrás temporalmente. Parece muy útil para solventar ciertas situaciones, tengo que hacer pruebas con el.

Des de que me respondiste estuve la tarde leyendo, empapándome de mas teoría y me encontré con algo que te quiero preguntar, lo haré al final.

Puedo utilizar mi lógica para suponer a que te refieres con lo de "los RPC no deberían tener conexión con el servidor", pero para que no me queden dudas o por si acaso voy errado me lo podrías explicar porfa?

Con la estructura de datos, me pasa lo mismo, puedo verle un sentido a lo que comentas pero no lo veo en la practica.

Estoy aprendiendo a entenderlo, obviamente no busco soluciones, busco la manera de ponerlo en practica, hacer pruebas y entender el funcionamiento de lo que me comentas, así que disculpa tantas preguntas pero es un terreno complicado (o al menos a mi se me hace complicado) y llego a el des de cero.

Por cierto tambien me contre con esto: https://docs.unity3d.com/Manual/UNetVisibility.html . Me parece algo muy interesante, voy a estudiarlo y probarlo.

 

Lo que te comentaba al principio que encontré ayer leyendo por internet, es a gente con bastante experiencia con uNet comentando que al final se pasan a otra Network Solution como Photon, etc, por muchos motivos, tales como la falta de documentación, ejemplos, la falta de actualizaciones por parte de Unity sobre uNet/HLAPI..., limitaciones en cuanto a estabilidad cuando la cantidad de jugadores en el servidor es "alta" (en plan, mmo, survivals, etc..), la sensacion de abandono de este apartado por parte de Unity... Y muchos mas motivos que algunos de ellos no puedo comentar por que ni los entiendo ya que son demasiado técnicos para mi. Pero ademas lo que me sorprendió es la gran cantidad de gente que respondía a estos posts que estaban de acuerdo con el, osea que pensaban igual.

Y esto me da que pensar, realmente me vale la pena seguir aprendiendo uNet? No tendrá mas futuro (a corto y medio plazo al menos) aprender otra solución? En su momento tiré por uNet sin dudarlo porque no quería depender de un tercero, ya que si salen actualizaciones de Unity deberemos esperar a que ese tercero saque una actualización también.

Pero bueno, si la diferencia es tan importante quizas vale la pena cambiar, no lo se. Ademas quiero aprender a hacer funcionar muy bien uNet/Photon/lo que sea, antes de hacer crecer un juego, creo que es bueno ir programando el networking al mismo ritmo que crece el juego.

 

Voy a seguir leyendo cositas mientras espero tu respuesta :P

Gracias!

Definitivamente UNET no es lo mejor, PHOTON es algo más complejo. Pero en ningún caso es bueno utilizar HLAPI esto dejalo para la gente que no tiene idea de cómo se comportan las cosas.

Conceptos 

Servidor: son los SOCKETS encargados de la transmisión de información desde un Dispositivo a Otro. este se suele basar en 2 protocolos TCP y UDP, las diferencias entre podes buscarlas en google, pero para resumir de una manera "brutal" TCP es como HLAPI de UDP (No es así, pero te puedes dar una idea).

Cada Socket requiere un PUERTO, en el caso de los Servidores, el puerto debe ser siempre el mismo o estar dentro de un rango controlado, por lo que si el puerto utilizado por el servidor ya está en uso en el dispositivo HOST este no funcionara.

Cliente: nuevamente SOCKETS.

¿Como haces para que un Socket sepa de dónde viene cada Paquete?
Cada conexión que recibe el Socket del servidor contiene la información del emisor "EndPoint" dentro de este objeto tenes algunos datos como la IP y el Puerto utilizados para dicha conexión. Cuando se trata de conexión el puerto no es especificado por el cliente, si no, se toma uno libre. es decir, EJ:

  1. Conexión : Puerto 2555
  2. Conexión : Puerto 2556

Esto se debe a que debemos estar seguros de que la información recibida por el sockets es en cierta forma la esperada.

 

Funciones -
Los clientes deben mandar cada x tiempo un paquete de vida al servidor.
El servidor debe controlar en cada actualización si cada cliente está vivo << esto se hace observando el tiempo del último paquete de vida. 
El servidor envía paquetes a X cliente.
El servidor envía paquetes a Todos los clientes.
El cliente envía paquetes a el servidor.

¿Qué son los RPC?
Como los clientes no pueden enviar un paquete a otro cliente, la única vía posible es pedirle al servidor que lo haga. Imaginemos el siguiente escenario, tienes un amigo viviendo en otro país, para enviarle una carta no te queda otra solución que hacerlo por correo. esto mismo para en la estructura Cliente/Servidor.
 

¿En qué casos un cliente requiere enviar un paquete a otro cliente en particular?
El más fácil de ejemplificar es en un chat, existen 2 tipos, un chat global y un chat privado, pero, ¿Como se puede hacer?, primero debes saber el UID otorgado por el Servidor de cliente que necesitas enviar el mensaje. luego, envias al servidor un paquete de chat. supongamos que dicho paquete tiene la siguiente estructura.

public class NETPKG_Chat
{
	public enum EType
    {
		Public,
		Private
    }
	
	public EType Type;
	public string Message;
	public int TargetUID;
}

Deberíamos de crear una instancia con los valores deseados. new NETPKG_Chat {Type = EType.Private, Message = "Mensaje de Prueba", TargetUID= IdDelCliente }; luego deberias crear la lógica para que el servidor sepa que hacer con x paquete y sus valores.

Todo esto sucede en UNET la diferencia es que HLAPI intenta solventar problemas relacionados a la estructura del motor, como por ejemplo la instancia de Objetos Remotos, la sincronización de Network Behaviours, la compilación de Command, RPC, etc. ¿Esto es un problema?, desde mi punta de vista, si, creo que cada desarrollador debería armar lo justo y necesario para su proyecto.

En mi experiencia he armado FPS bastante completos con UNET, el problema es que terminas teniendo grandes dolores de cabeza por la Incoherencia contextual que existe en la escritura del código, me refiero a que un Componente no autoritativo tiene lógica del servidor dentro, no tiene sentido, creo que las cosas deberían estar separadas y bien definidas.

Si estás interesado en Networking te recomendaria ver soluciones como LIteNetLib es bastante simple de utilizar. o eNET, un poco más compleja pero nada que envidiarle a LiteNetLib, como dato interesante el Core de Photon está basado en eNET.

Entonces, en resumen, ¿qué es lo que nos provee UNET que en cierta forma es aceptable? NetworkTransport, es quien se encarga de toda la lógica de Sockets y nos da una comodidad excelente para trabajar, la gran desventaja es que no podemos crear un servidor basados en Network Transport, debido a que solo funciona en UNITY, están en la duda de liberar una librería... Pero no creo que esto sea posible, apuntan a un Cloud Server por lo que intentan realizar un servicio de PAGO sin posibilidades de poder montarlo en otra plataforma.

Share this post


Link to post
Share on other sites

buena explicacion, me ya venido muy bien pues estoy muy pero que muy "verde" en networking...

Edited by Igor
croreciones orthogafricas

Share this post


Link to post
Share on other sites

Fenomenal @francoe1, muy buena explicación, gracias.

 

Voy a ponerme a estudiar las soluciones que me as propuesto, a hacer pruebas y demás, me parece muy interesante y quiero llegar a controlarlo.

Seguiré comentando en este mismo hilo. Si se te ocurren mas cosas, consejos, utilidades... que crees que me puedan ser de ayuda no dudes en ponerlo, estaré atento al post!

 

Muchas gracias!!

 

 

Edited by datmos

Share this post


Link to post
Share on other sites

Dale! -

Tengo algunas cosas que podría ser de ayuda, pero primero intenta entender a fondo cómo funciona.

1º Te recomiendo familiarizarte con Socket UDP en C#, no uses UdpClient, hazlo todo desde cero.
2º Intenta recrear un sistema como TCP donde un cliente se conecta el servidor lo valida y lo agrega a una lista de clientes para luego ser utilizados.
3º Intenta crear un escritor binario para la serialización de paquetes.
4º Intenta crear una arquitectura donde puedas enviar y recibir paquetes personalizados entre el servidor y los clientes.

Si dominas ese 4 pasos, podrias pasar a hacer pruebas con sistemas más complejos como Relay Server, Master Server.. Etc.. 

Para el networking utilizó un sistema basado en Plugins, el cliente y el servidor tiene plugins.. 

Sin título.jpg

Fijate que el Servidor y el Cliente tiene plugins, y cada uno tiene su respectiva lógica.

Edited by francoe1

Share this post


Link to post
Share on other sites

×
×
  • Create New...