Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - francoe1

#241
General (Antiguo) / Armonía de las variables
Julio 08, 2018, 03:23:55 AM
Debes tener un factor de multiplicación - En tu caso el nivel -
 

public class NaveStats
{
    public int Level { get; set; }
    private int _speed = 10;
    public int Speed { get { _speed * Level; } }
   
    private int _force = 10;
    public int Force { get { _force * Level; } }
   
    private int _damage = 10;
    public int Damage { get { _damage * Level; } }
}

 
O si no puedes plantearte la idea de hacer un estructura que contenga la estadísticas en cada nivel, tambien si la nave se vera afectada por algún items debería tenerlo en cuenta.
 

public class NaveStats
{
    public int Level { get; set; }
    public List<NaveItem> Items = new List<NaveItem>();
    private int _speed = 10;
    public int Speed { get { (_speed + Items.Sum(x => x.SpeedAdd)) * Level; } }
   
}
public class NaveItem
{
    public int SpeedAdd;
}

 
 
#242
General (Antiguo) / networkbehaviour!!!
Julio 07, 2018, 09:14:37 PM
A ver .... lo que yo te explique arriba se trata de la integración del "NÚCLEO" de tu librería -.
 
¿Con que estas trabajando UDP o TCP? -
 
TCP funcionaria desde un primer punto, pero luego ocasiona problemas por sus algoritmos de seguridad de transferencia, si implementas UDP puedes tener pérdida, alterados, duplicados de paquetes para solucionar esto se puede implementar un técnica de "UDP RELIABLE" - 
 
En la capa de envío tanto del servidor como del cliente tienes que contar con diferentes tipos de mensajes, por ejemplo, en envío de posiciones debería ser un paquete no seguro pero ordenado, esto quiere decir que el receptor solo recibe paquetes con un DATE o ID más alto que el anterior y a los otros los descarta << esto genera pérdida de paquetes, pero a la misma vez te asegura de estar o intentar estar en el último estado.
 
----
 
Creo que el problema en tu proyecto es que estás permitiendo que los usuarios decidan sus propias posiciones, es decir, el servidor no puede calcular las posiciones por que no tiene una simulación del mundo en el que se está jugando, si piensas hacer un FPS esto te podría traer problemas con absolutamente todo, por eso te pregunte si tu juego iba a utilizar algún componente de UNITY, es decir Rigidbody, RayCast, Etc... 
 
También, te recomiendo no trabajar 2 lenguajes diferentes, si vas a programar solo, podrias diseñar tu servidor en C#, podrias crear una librería y luego desde unity crear la capa para el servidor, el cliente y el servidor utilizar el mismo core, las mismas estructuras, por lo que no tendrías que tener problemas para esto -
#243
General (Antiguo) / networkbehaviour!!!
Julio 07, 2018, 02:25:08 AM
Lock bloquea el objeto para que este no sufra cambios en tiempo de ejecución de tareas paralelas -
 
Por ejemplo, si quieres modificar una lista desde 2 tareas a la misma vez dependiendo del contexto de ejecución te va a dar un error, o vas a ocasionar que el procesador no pueda trabajar como debería (EN BLOQUE) -
 
Cuando estás programando una clase networking necesitas controlar todo desde un hilo único, pero el problema de esto es que los SOCKETS trabajan en bloque, quiere decir que la ejecución se detiene hasta que haya una actualización, para solucionar este problema los Sockets se ejecutan en otro hilo, pero esto trae otro problema, "Modificación de objetos por procesos diferentes", lo que en un 90% te va a dar un error fatal -
 
Entonces que se hace .... una técnica llamada (Push and Pop) - todos los mensajes recibidos se insertan en una lista, y luego se quitan con cada actualización del hilo principal -
 

public class Server
{
    private object lockObj = new object();
    public delegate void OnReadDelegate(byte[] bytes);
    private Stack<byte[]> _stackReceiver = new Stack<byte[]>();
    private void handleReceiver(byte[] bytes)
    {
        lock(lockObj)
        {
            _stackReceiver.Push(bytes)
        }
    }
    public void ReadMessages(OnReadDelegate callbackRead)
    {
        lock(lockObj)
        {
            while(_stackReceiver.Count > 0)
                callbackRead.Invoke(_stackReceiver.Pop());
        }
    }
}

 
¿Por qué se utiliza un object para el lockeo? por que de usar el stack estaríamos desperdiciando memoria y dependiendo del tamaño del stack tendríamos una pérdida de rendimiento considerable.
 
En el ejemplo puedes ver cómo handleReceiver bloquea el objeto, porque va a modificar _stackRecevier aca se genera un "Semáforo" entonces hasta que la invokación no finaliza el objeto lockObj sigue bloqueado,  a su vez el objeto tambien se bloquea cuando se utiliza ReadMessages justamente para el mismo propósito -
 
Ahora para cualquier modificación en _stackRecevier se debe utilizar lock(lockObj) .- si utilizas lock(this) estas bloqueando todo el objeto y es una practica malisima -
 
 
 
Espero que se haya entendido, esto es más fácil explicarlo hablado que escrito.
 
 
 
Para terminar -
 
handleReceiver se llama desde el hilo que trabaja con Sockets - 
 
ReadMessage(callback) se llama desde una función Update de Unity <<< Ejemplo ---
 
 ------------------------------------
 
En cuanto al método para armar los mensajes lo más práctico es trabajar con bytes, puedes crearte una clase que trabaje con BinaryWriter y BinaryReader, luego creas una clase base para los paquetes que tenga una función virtual para escribir y leer - por ejemplo - 
 

public class NetMsg
{
    public int MessageId { get; internal set; }
   
    internal void Write(BinaryWriter writer)
    {
        writer.Write(MessageId);
        OnSerialize(writer);
    }
    internal void Read(BinaryReader reader)
    {
        MessageId = reader.ReadInt32();
        OnDeserialize(reader);
    }
    protected virtual void OnSerialize(BinaryWriter writer){}
    protected virtual void OnDeserialize(BinaryReader reader){}
}
public class PlayerPositionNetMsg : NetMsg
{
    public Vector3 Data { get; set; }
    protected override void OnSerialize(BinaryWriter writer)
    {
        writer.Write(Data.x);
        writer.Write(Data.y);
        writer.Write(Data.z);
    }
    protected override void OnDeserialize(BinaryReader reader)
    {
        float x = reader.ReadSingle();
        float y = reader.ReadSingle();
        float z = reader.ReadSingle();
        Data = new Vector3(x, y, z);
       
        //o de una manera mas comprimida        
        Data = new Vector3(
            reader.ReadSingle(),
            reader.ReadSingle(),
            reader.ReadSingle()
        );
    }
}

 
  -------------------------------> 
#244
General (Antiguo) / networkbehaviour!!!
Junio 25, 2018, 06:56:53 PM
Cita de: Kvashir date=1529943363Saludos gente, hace tiempo que no me pasaba por aquí falta de tiempo libre, pero ahora eh vueeeelto ! 
   
   
      Estoy haciendo un "proyecto" en unity conectando unity a un servidor JAVA (eso lo eh conseguido)
   
   
      el problema que tengo es que los datos llegan al servidor y del servidor llega a todos los clientes
   
   
      los clientes reciben los datos, pero algunos clientes mueven a todos los jugadores otros no y otros no aparecen ni el propio player de ese cliente

       
   
   
      
   
   
      creo que es un problema con el cliente unity y no con el servidor java, eh probado locks para bloquear el acceso a funciones cuando esten en uso por otro proceso y falla menos pero sigue con errores (en el servidor java eh usado synchronized)
   
   
      de momento estoy revisando los scripts c# me parece que el fallo está ahi porque reciben información del servidor.

      Mi duda es, alguien a intentado algo así?? 
   
   
      se puede usar networkbehaviour para servidores java?? 
   
   
      siempre que busco información para un mmo en unity todos y cada uno saltan con la genial idea de usar un cliente unity como servidor utilizando esas librerias, algo que no me parece muy eficiente del lado del servidor O-o
   


Del lado del servidor, ¿necesitas utilizar alguna función de Unity? si es así entonces vas a tener que utilizar una librería que se integre en Unity, esto podrias hacerlo utilizando Unet u otros servicios tipo Photon, tambien puedes armar tu librería utilizando Sockets.
 
Si el servidor no requiere ninguna funcionalidad de Unity entonces requerirá crear una librería backend y otra frontend - 
 
¡- Pero de ningún modo podrias utilizar NetworkBehaviour fuera de Unet -!
 
Tu problema puntualmente es un problema de TAG de paquetes, o Relay, cuando un cliente envia un paquete al servidor es siempre requiriendo una acción o un dato cuando el servidor envia un dato a los clientes siempre se trata de un "SET" entonces podes crear un sistema que te identifique con TAG el tipo de paquetes 
 
Tipos: COMMAND, GET, SET

Propietario: OWNER, REMOTE, ROOT (Servidor)
 
- De ese modo sabias que paquete proviene de un RELAY o RPC -
 
Internamente esto funciona debido a que cada cliente se conecta al servidor, el servidor debe crear un ID asociado con el ENDPOINT del cliente para poder enviarle datos luego y lógicamente identificarlo, cada paquete que el servidor recibe sabe de qué cliente se trata, un ejemplo el inicio de sesión, podrias descartar todos los mensajes de X cliente si X cliente no está dentro de la lista de las sesiones abiertas -
 
La única entidad que controla los ID es el servidor, por lo que si un "man-in-the-middle" altera la información saltando lógicamente la encriptación el servidor podria descartar dicho mensaje -
 
 
 
 
#245
General (Antiguo) / Ayuda sustituir texto por otro
Junio 24, 2018, 06:14:02 PM
Lo mejor sería utilizar string.format()
 
 
#246
General (Antiguo) / Dudas: IA choca, y ***guir
Junio 23, 2018, 02:33:49 PM
Deberías analizar FSM para lograr lo que estas buscando de manera más "simple" -
 
Te recomiendo este 
 


   
eature=oembed" width="480">

 
 
#247
General (Antiguo) / Vidas en Unity
Junio 19, 2018, 07:13:27 PM
@aliciamartinez espero ser constructivo en mi respuesta, vi el "tutorial" de principio a fin, y la verdad es que es un nivel bastante principiante pero noto el interés de intentar aprender.
 
1º Las lógicas de los componentes tienen que ser objetivas, nunca debes mezclar la lógica del jugador con la interfaz de usuario.
 
2º La escritura debe ser parecida a las convenciones más conocidas, para obtener una mejor calidad de código, para esto existen convenciones de diseño, de lógica, etc.
 
3º Tienes que ponerte siempre como meta que un sistema funcional es aquel que no requiere de estar modificando el código para que siga funcionando, en tu caso, cada vez que quieras agregar un corazón vas a tener que volver a crear toda la lógica nuevamente.
 
4º Busca y lee sobre implementaciones o técnicas para casos simples de videojuegos que te serán de mucha ayuda.
 
 
 
Te muestro mas o menos como lo haría.

 - La lógica -
 

public class HeartControl : MonoBehaviour
{
    [SerializeField]
    private int _health = 3;
    public int Health { get { return _health; } }
    public event Action<int> EventChange = delegate { };
    public void TakeDamage()
    {
        _health -= 1;
        EventChange.Invoke(_health);
    }
}

 
- El controlador para UI -
 

public class HeartUIControl : MonoBehaviour
{
    [SerializeField]
    private HeartControl _heartControl = null;
    private List<HeartUIElement> _hearts = new List<HeartUIElement>();
    private void Awake()
    {
        _hearts.AddRange(transform.GetComponentInChildrens<HeartUIElement>());
    }
    private void Start()
    {
        Show(_heartControl.Health);
        _heartControl.EventChange += Show;
    }
    public void Show(int length)
    {
        int count = 0;
        _hearts.ForEach(x =>
        {
            if(count < length)
                x.Show();
            else
                x.Hide();                
            count ++:
        });
    }
}
public class HeartUIElement : MonoBehaviour
{
    protected CanvasGroup _cg { get; set; }
    private void Awake()
    {
        _cg = GetComponent<CanvasGroup>();
        if(_cg == null)
            _cg = gameObject.AddComponent<CanvasGroup>();
    }
    public virtual void Show()
    {
        _cg.alpha = 1;
        _cg.interactable = true;
    }
    public virtual void Hide()
    {
        _cg.alpha = 0;
        _cg.interactable = false;
    }
}

 
Esto podría mejorar si se utiliza interfaces o mejor aun si directamente migras a ECS -
 
Sigue practicando :) Saludos.
#248
Tenes que trabajar con rotaciones globales, estas mezclando rotaciones locales y globales.
#249
General (Antiguo) / problema para recoger objetos
Mayo 25, 2018, 04:33:45 PM
Cita de: lightbug date=1527220002En estos casos, casi todos los post que tratan de lo mismo (si buscas en este sitio vas a encontrar por lo menos 20 post) el código está perfecto, pero el problema está en la escena/proyecto, busca en la documentación la tabla de colisiones (aparecen X's ), fijate entre que y que se da un OnTriggerEnter, (no se da con cualquier cosa) una vez tengas esos tipos de objetos y el obj tenga el tag correspondiente debería funcionar. Y si querés estar seguro de que pasa lo que pasa simplemente usá la consola, sino estás adivinando si esto anda o no, la incertidumbre es lo peor, siempre matá estas cuestiones, un simple print("anda") en cualquier lado del código te saca de esto y no cuesta nada.
   
   

void OnTriggerEnter(Collider other){
print("anda el ontrigger");
   if (other.tag == "Salud") {
      print("se mete al if");
      Curas++;
      Destroy (other.gameObject);
      Contador ();
   }
}

   
      tecnicamente podés hacer debugging para esto pero con el print esta bien
   


Y por que no usar breakpoint, sería más fácil de debugear cada para por el que pasa .
#250
Cita de: Braltor date=1527089000jajaj si... si alguien me dijera "te pago mes a mes por hacer eso hasta q lo termines" eso me daria una gran alegria xq tendria trabajo pagado para el resto de mi vida!
   


Jajajjaja Exactamente... 
#251
Cita de: Braltor date=1527088088entonces tienes q enfrentarte a estas cosas entre otras:
   
   
      * como procesas las fisicas en los limites de esas cuadriculas?

      * como procesas los objetos en cada cuadricula en todo el universo en tiempo real para q hagan sus tareas segundo a segundo?

      * como procesas los movimientos y los sistemas de ecuaciones de gravedad entre todos los objetos de diferentes masas en todas las cuadriculas?

      * hacer el perlin de un planeta es sencillo, pero como le aplicaras erosion para q el entorno se vea real?

      * como vas a simular las dinamicas de fluidos para aguas y atmosferas?

      * como vas a procesar los datos de suelos plantables y los q no son aptos para la vida?

      * como vas a generar formas de vida diferentes adaptadas a sus planetas y entornos?
   
   
       
   


Como.. Para una persona y agregado a esto sin conocimientos es IMPOSIBLE. Uno tiene que ser sincero .
#252
Cita de: Jeko37 date=1527085170Ayer estuve revisando información, me vi los vídeos que me pasaron y encontré alguna que otra porción de código que no llevó a buen puerto, con respecto al problema de los floats se puede resolver dividiendo el espacio en cuadriculas y reiniciando las coordenadas de las cosas cuando se pase de una cuadricula espacial a la otra, pero desconozco si Unity me permite hacer algo así, en su momento supongo que se podrá abordar el problema pero por ejemplo imaginen que están dentro de un área espacial y van a pasar a la siguiente, simplemente trasladas el personaje de su coordenada actual y lo mandas más atrás mucho mas atrás (como una teletransportacion digamos jaja) y en ese interín borras todo el contenido 3D del area espacial y cargas los nuevos elementos (previamente procesados) y das la sensación de "infinitud" espacial sin llegar a tener problemas con el calculo de los floats, para poder volver para atras y cargar contenidos virtuales viejos como estaban antes es que ayudaria el seed. No se si me hago entender.
   
   
      Por lo que estuve viendo en la documentación de Unity no hay porque creer que esto sea una tarea imposible, lo primero es lograr un pequeño algoritmo que deforme una esfera, después la idea es aumentar el detalle a medida que uno se acerca (si hacemos todo de una no hay manera que el procesador lo aguante) y después vendría la parte mas divertida, diseñar un algoritmo matemático que genere un ruido que de como resultado paisajes que den la sensación de reales, yo vi en No Man Sky los planetas y me aprecio muy descuidado el algoritmo que genera los mundos, da la sensación de que todos los planetas son iguales cuando para mi la gracia es entender que los planetas son muy diferentes entre si, por ejemplo vas a tener planetas como la tierra, con variedad de biomas muy distintos según las áreas donde aterrices, planetas como marte donde el paisaje va a ser mas bien monótono, planetas golpeados por asteroides con gran cantidad de crateres, planetas gaseosos que serian los mas fáciles de hacer ya que no hay calculo de terreno.
   
   
      Con el tema de la historia del juego, no tengo en mente hacer un juego a partir de esto, sino crear un framework de base para que quien quiera crear un juego con un universo explorable lo pueda hacer facilmente.
   
   
      En fin, cuando tenga algún avance voy a ir publicando las imágenes y el código así me ayudan a ir afinándolo.
   


¿Por qué no empezar con algo más simple?, me comentaste que tus conocimientos en matemáticas son bajos y esto es matemática avanzada, empieza con simulación de olas deformación de mallas planas.
#253
Podrias empezar con un sistema de voxel para entender los conceptos básicos matemáticos y la implementación de técnicas para la optimización como los CHUNK.
 
Si logras algo decente con esta técnica entonces podrias pasarte a produceral mesh e intentar aplicar las mismas técnicas pero esta vez con matemáticas más complejas, recuerda que tambien un entorno tiene componentes físicos, por lo requiere un sistema que pueda manejarse de manera estable y simular sus propiedades.
 
Por ejemplo, una idea que se me ocurre es realizar un VOXEL con una cuadrícula de 100x100x100 y que cada bloque ocupe 1 unidad, luego dividir la unidad que cada bloque ocupa, con cada división obtendrás más "calidad", en este punto puedes implementar "shaders" para convertir el voxel en una malla. 
 


   
eature=oembed" width="480">

 
 
 
Te dejo un tutorial que recomiendo lo sigas para entender algunos puntos complejos de estas implementaciones. 
 
https://forum.unity.com/threads/tutorial-procedural-meshes-and-voxel-terrain-c.198651/
 
Y otro para entender un poco más sobre shaders (No se aplica en su totalidad a Unity pero sirve para los conceptos)
 


   
eature=oembed" width="480">

 
 
 
Desde ya te digo, si tu conocimiento matemático es bajo, trata de aprender cada fórmula, para que en un futuro entiendas que estás haciendo. 
#254
Cita de: juanma_teso date=1526996770Hola! No sé si sabes cómo funciona internet, de manera simple son como direcciones a ordenadores, el problema es que la dirección que tenemos en casa por lo general suele cambiar, por eso es necesario tener o un servidor contratado para que el jugador se conecte, registre su sala y otros jugadores lo encuentren (este es el servicio que da Unity y otros), o bien montar tú tu propio servidor (hablar con tu ISP y pedir una IP fija) y tenerlo siempre encendido.
   
   
      De cualquier manera necesitas un servidor donde poder registrar la dirección del jugador que crea sala, porque de otra manera el jugador que busca sala no encontrará la dirección del jugador que crea sala. Una vez hecha esta conexión puedes hacer lo que quieres (descargar los datos del jugador-servidor), pero lo primero es crear la conexión.
   


La respuesta está en 50% acertada, en principio llamemos IP ESTÁTICA a lo que muchos llaman IP FIJA, para que 2 equipos o más se puedan conectar necesitan obligadamente tener una conexión física, esto se lo puede aplicar en casa, cuando tenemos conectado dos equipos al mismo ROUTER. En el apartado de networking te vas a encontrar con muchos más problemas que solo programar, es más, puedes lograr una librería decente basada en TCP en pocas horas, pero al momento de que "ESTO" funcione en producción lo veo un poco complejo, en primer lugar antes de aprender SOCKET's deberias saber que es NAT, FIREWALL, PROXY, las llamadas CAPAS, protocolos como segmentación, datagramas, etc.
 
Por lo que veo muy dificil que una persona sin conocimientos en lo que respecta "NETWORKING" a  nivel FÍSICO pueda lograr algo decente, te recomiendo aprender cosas básicas, experimentar con servidores DHCP, DNS, PROXYs, y luego cuando te sientas cómodo con todo eso ponte a programar SOCKETS y te vas a evitar muchos dolores de cabeza.
 
Servicios como UNET no los recomiendo, en principio por que lo que dice "SER SIMPLE" puede ser muchas veces complejo, UNET se basa en componentes por lo que tarde o temprano la estructura de nuestro proyecto se ve afectada por la arquitectura que debemos tomar para la implementación, por otro lado, el servicio que proveen no tiene una cobertura mundial, por lo que dependiendo tu posición geográfica podes experimentar entre 200 y 500 ms de retraso lo que realmente afecta muchísimo el desempeño de un juego multijugador y aumenta mucho mas el tiempo de producción debido a la implementación de predicción para los componentes como físicas, npc, entornos, etc.
 
Si tienes ganas de aprender descargate un programa CISCO Tracer Packet donde puedes simular múltiples entornos de red, recorda que no todo tiene un Web Interface, vas a tener que aprender a utilizar SSH, vas a comprender lo que es portknock y vas a luchar contra los servidores DNS, los Loop backward y Loop forward, hasta que luego de mucho tiempo logres entender por que pasa cada cosa, y entonces ahí vas a poder programar networking para video juegos.
 
 
 
Por otro lado lo que vos estas necesitando es un "Web Service" que te sirva para recibir y obtener información de los usuarios.
 
 
 
Saludos.
#255
Cita de: Eskema date=1525959964Varios apuntes o dudas que tengo del video.
   
   
       
   
   
      Clase StoreData, linea 11, una lista publica que devolvemos. ¿Para que?, quiero decir, ¿se deja el get para que se pueda examinar la lista aun corriendo el riesgo de modificarla?, ¿o simplemente no importa si se modifica, en cuyo caso en vez de hacer var privada y luego el get yo la habria dejado publica directamente.
   
   
      Las listas son modificables aunque las pases como un get, yo cojo ese get, modifico la lista y te jodo vivo. Cuando tu intencion probablemente era solo de get.
   
   
      No se si esto que digo se ha hecho asi en el video por ser un simple tutorial, porque se queria ese comportamiento, o ha sido un "error".
   


La idea era utilizar arreglos y no listas, esto lo cambie sobre la marcha para evitar extender más el tutorial, pero como práctica si la variable no se debe asignar desde fuera de la clase entonces debe ser privada, tratándose en este caso de un lista, no tiene validez.
 
Gracias por tu opinión!