Jump to content
UnitySpain

Search the Community

Showing results for tags 'unity3d'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Inicio
    • Proyectos
    • Offtopic
    • Unity Feeds
    • Website
  • Mesa de ayuda
    • Unity
    • Arte
    • Otras Especialidades
    • Builds & Dispositivos
  • Aportes de la Comunidad
    • Recursos
    • Eventos
    • Buenas Prácticas
  • Bolsa de trabajo & Colaboraciones
    • Ofertas y Demandas
  • Post Antiguos
    • General (Antiguo)

Blogs

  • byGui

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Especialidad

Found 41 results

  1. He recuperado un artículo que explica el nacimiento y origen de la compañía y su juego, los cuales evolucionaron hacia lo que hoy en día es Unity3D. Siempre hace gracia conocer los orígenes de las cosas, y el por qué se hicieron de esa forma... Descarga: https://web.wpi.edu/Pubs/E-project/Available/E-project-030614-143124/unrestricted/Haas_IQP_Final.pdf
  2. Fps estilo half life (EJEMPLO UNITY3D) Dejo este ejemplo por aquí, mi ejemplo estilo half life de un FPS para Unity3d 2017. Incluye movimiento de camara con raton, movimiento de personaje con ASDW, C para agacharse, Shift para correr, Espacio para saltar, puedes subir escaleras (cubo rojo). Espero que os guste. Ya no teneis escusa para no hacer un FPS. Descarga en la descripción del video: https://www.youtube.com/watch?v=wP-QgfHTER4
  3. anonimo

    Fps Online

    Buenos días, os presento mi nuevo videojuego, realizado en javascript, con unity 343f3, es un juego FPS (disparos en primera persona), en el cual, hay que llegar a 100 kills, la partida esta 24 horas abierta, al llegar a 100 kills se reinicia. Para ello hay diferentes armas Cuchillo, Pistola, Metralleta y Escopeta, tienes que buscar la munición por el escenario y los medical kit para reestablecer la vida. Los personajes son cubos, estilo minecraft, ya que cuesta mucho trabajo meter un personaje animado, de momento no lo he hecho, lo he dejado con cubos para ser mas sencillo. El sistema de disparos es raycasting, el juego esta programado en javascript al 100% con el sistema online tradicional de Unity. Soporta hasta 64 jugadores en linea y el lag esta compensado para que no haya problemas en movimiento/rotacion, tambien para que vaya fluido. Controles: ASDW y raton para moverse , apuntar, y disparar. TAB: Ver puntuaciones E: Usar R: Recargar Space: Saltar Esc: Recuperar ratón para salir 1,2,3,4 / Rueda del raton: Seleccionar arma (cuchillo, pistola, metralleta, escopeta) Si quereis probarlo os dejo unas fotos y el link: Descarga: https://www.dropbox.com/s/6oe4dqj74skycf3/Fps200.rar?dl=0
  4. Buenas amigos, lo que quiero saber es un script de un jugador sea cual sea el modelo que el brazo esté configurado para seguir el mouse y disparar si es necesario, etcétera. Para que tengan una idea, algo como esto: Ese tutorial es de flash ya es viejo y quiero saber como hacer para llevar un script parecido a unity.-
  5. tengo un clase que la otorgo la variable cantidad y de tipo("La defino por lista de Enum"), pero me he dado cuanta de que es complicado buscar un objeto atrevas de este método lo que se me ha ocurrido es definir primero el tipo de objeto y que luego en base a esa elección me sea visible la lista de objetos de esa pila en especifico, pero no tengo idea de como hacer eso. [System.Serializable] public class Item { public enum ItenType { //consumibles posion, hierva, pierda, manzana, antidoto, megaposion, // , Attacks Barrida, Recuperacion, //ObjClave llave, pistola, palodepesca, //Frutas fruta1, fruta2, fruta3, fruta4, //Jaulas normal, especial, acuatia, sol, luna, rapida, recuperacion, solida, sinestado, Confusion, //Stands pasiva, agresiva, defensiva, desgaste, aguante, PosturaRapida, //ObjEfects ataqueEfec, defensaEfec, velocidadEfec, AntiEstado, MoreExperience, antiFinalHit } public ItenType iten = new ItenType(); public int cantidad; } Esta clase tiene la cantidad y todos los objetos visibles, pero quiero hacerlo por de forma que primero defino que clase objeto ejemplo; si es consumible, aparece todos los objetos consumibles, si una hierba la defino como tal y luego me aparece una lista con todas objetos hierbas.
  6. ¡¡Ya están aquí las rebajas de Mayo. Aprovechad mientras se pueda!! https://assetstore.unity.com
  7. Hola tengo un problema soy nuevo en unity 5 y estoy creando un juego el problema que tengo esque cuando hice modelos como casas y arboles los importo bien pero e intentado hacer un personaje en adobe fuse mas de 5 veces y cuando lo importo a unity me sale un color solido sin texturas
  8. Muy buenas a todos!! Es muy posible que todos nosotros hayamos visto en algún videojuego la típica escena en la que se muestra una pared con un agujero o grieta: El como se hacen depende del artísta, el engine, las herramientas que se empleen y el estilo artístico del juego. Como es algo tan común he decidido mostraros mi pipeline para hacerlas: Podéis encontrar un speedrun mio en la siguiente página: https://www.patreon.com/posts/wall-holes-15896133 Como podéis ver el proceso es bastante más sencillo de lo que uno pudiese pensar aunque si tenéis alguna sugerencia por favor díganla. El resultado se puede mejorar y los trucos e ideas siempre se pueden complementar.
  9. Hola a todos! Hoy he colgado un nuevo tutorial dónde muestro un pequeño ejercicio sobre cómo talar un árbol. Vamos a diseñar y pre-cortar el árbol en 3dMax, importaremos al Unity 3D y crearemos los scripts básicos para controlar el comportamiento del corte de un árbol. Por favor suscríbanse al canal y dejen un comentario! https://www.facebook.com/dbJocs/
  10. Buenas compañeros les dejo por aqui mi proyecto actual el cual se llama Blood Of Gods les dejo la info y una breve descripción. Nombre: Blood Of Gods Desarrollador: XGS Miembros del equipo: yo :pinch: (Quien se quiera apuntar es bienvenido). Motor: UNITY5 Lenguaje: C#. Genero: ARPG. Plataformas: Windows, Mac, Linux, Android. Idiomas: Ingles, Español. YouTube(No olviden darle Like, Suscribirse y Comentar). Facebook(No olviden darle Like, Seguir y Compartir). Estado: En desarrollo. Resumen muy breve: La historia se centra en una secta que adoran a los 7 dioses de la perdición, los cuales deben ser destruido y usar su sangre para cerrar la puerta que une el mundo terrenal con el espectral (No quiero contar mucho ya que quiero que el jugador vaya descubriendo la historia conforme avanza, aunque la idea se entiende :D). Quise darle un montón de simbolismos al juego por ello los nombres son una mezcla de varios idiomas y cada uno tiene importancia en el argumento sin mencionar que el argumento tiene referencias bíblicas, ya se vera en el juego. (Igual no soy experto en el tema pero e tratado de construir algo interesante :D). Personajes Principales: (Abran muchos mas aunque estos son los que mas peso tienen dentro del argumento). Dioses: Strast Gier Alcnost Faulheit Zorn Neid Stolz Secta y Seguidores: septem deorum Obispo nuntius Verdugo Ultor Acolito fidelis Protagonistas: Eve Mater Adam Patrem Co Protagonistas: Ignis zuerst Aqua zweite Caeli dritte Terra vierte Imagenes: https://goo.gl/photos/VyFhirfLpVQacu8Z6 Videos:
  11. ¡Saludos a todos! Recientemente unos usuarios del foro nos hemos juntado para montar un pequeño juego 2D cómico para mobile, de género Inifinite Runner. Acaba de empezar, y buscamos gente para el grupo (en especial artistas y animadores). Yo colaboro como Diseñador y Productor ocasional del juego. He hecho el proyecto público, así que tenéis acceso a él y podéis ver su progreso en todo momento. (Así luce el juego ahora mismo, con gráficos temporales, etc) Tenéis una breve descripción del proyecto y su diseño: https://bitbucket.org/unityspainrunner/runner-canibal/wiki/Home El Proyecto está colgado en repositorio de tipo GIT: https://wake_studios@bitbucket.org/unityspainrunner/runner-canibal.git Aquí tenéis el Planning de tareas del proyecto: https://trello.com/b/v5AzSTy7 Espero que os guste y os animamos a participar en él.
  12. Estoy queriendo realizar una clase generica la cual la utilizare para llamar a un metodo especifico llamado "Execute" lo cual tendra diferentes funcionalidades dependiendo la clase a la que se este refiriendo. La pregunta es si es el mejor metodo, lo cual cada objeto tendra la clase "Action" y sus derivadas estaran dentro de una clase llamada "GlobalActions" como para dar un nombre. La funcionalidad de este es que tengo una clase controladora encargada de la interfaz, lo cual muestra informacion segun el objecto seleccionado; mas especificamente en un juego RTS. Luego está analiza la clase "Action" y muestra los botones correspondientes segun el tipo (sprite, etc), lo cual agrega un Listener a un boton especifico con sus respectiva funcion (Execute). using UnityEngine; using System.Collections; using System.Collections.Generic; using System; using System.Reflection; namespace ControllerRTS { public class Action : MonoBehaviour { void Start() //test { AddAction(typeof(ActionTest1)); AddAction(typeof(ActionTest2)); Execute(); //test button1 Execute(1); //test button2 } private List<Type> actions = new List<Type>(); public void AddAction(Type action) { actions.Add(action); } public void Execute(int index) { Type type = actions[index]; MethodInfo method = type.GetMethod("Execute"); object instace = Activator.CreateInstance(type, null); method.Invoke(instace, null); } } //funciones externas class "GlobalActions" public class ActionTest1 { public void Execute() { Debug.Log("ActionTest1"); } } public class ActionTest2 { public void Execute() { Debug.Log("ActionTest2"); } } //etc.. }
  13. Bienvenidos a la segunda parte del "Tutorial de UNET en español" Hoy vamos a tratar de entender cómo funcionan los comandos y sync var de una manera más detallada y luego vamos a programar un sistema de puntuación que nos permita gestionar KILLS - DEATHS - SCORE - NAME ¿Cómo funcionan los Command? Los comandos son funciones que se encuentran del lado cliente pero se ejecutan del lado servidor, es decir, cuando nosotros llamamos un comando desde cualquier cliente no se ejecuta en dicho cliente, si no en el Servidor. ¿Y esto para que sirve?, Bien, esto nos sirve para dejar que el servidor se encargue de todos los datos del juego aplique las reglas y sincronice estos datos con los demás Jugadores, Ver el Ejemplo de Sincronización de Movimiento. ¿Qué son las SyncVar? Con las SyncVar podemos sincronizar variables de datos Simples, Como INT - STRING - FLOAT y otros característicos de unity como VECTOR3, aunque estas siempre deben ser actualizadas por el servidor, ya que el cliente no tiene el privilegio de hacerlo. Entonces ¿Cómo se fusionan las dos? Primero, deberíamos pensar la lógica de forma local, es decir, sin ponernos a pensar en Sincronización u otros aspectos Multijugador, supongamos que estamos pensando hacer un FPS SIMPLE, entonces empezamos creando el Movimiento del Jugador, Move, Jump, Rotate, RotateCamera estas serían nuestras funciones para controlar todo el movimiento del personaje. Una vez ya programado esta parte, debemos Sincronizar la Posicion y Rotacion del Jugador, más la Cámara (VER PARTE 1). Esto fue una breve y simple explicacion de como funciona, pero voy a resumirlo en simples pasos explicativos para que sea más fácil entender. 1- Realizamos la Acción Localmente 2- Enviamos los Resultados por Cmd al Servidor 3- El Servidor asigna los datos recibidos en su correspondiente variable. 4- Los Cliente no locales sincroniza cada instancia con los valores sincronizados. Bueno, ya teniendo en cuenta todo lo anterior pasemos a construir nuestro sistema de Puntuación. 1- Vamos a necesitar 4 Variables 4 Funciones y 4 Comandos. [SyncVar] public string Name; [SyncVar] public int Kills; [SyncVar] public int Deaths; [SyncVar] public int Score; public void SetName(string value) { Name = value; Cmd_SetName(value); } public void AddKill() { Kills++; Cmd_AddKill(Kills); } public void AddDeath() { Deaths++; Cmd_AddDeath(Deaths); } public void AddScore(int value) { Score += value; Cmd_AddKill(Score); } [Command] private void Cmd_SetName(string value) { if(!isServer)return; Name = value; } [Command] private void Cmd_AddKill(int value) { if(!isServer)return; Kills = value; } [Command] private void Cmd_AddDeath(int value) { if(!isServer)return; Deaths = value; } [Command] private void Cmd_AddScore(int value) { if(!isServer)return; Score = value; }Con esto ya tenemos nuestro sistema de puntuación funcionando, ahora debemos gestionarlo, vamos a crear una función OnGUI para visualizar los datos de todos lo Clientes conectados. void OnGUI() { foreach(PlayerInfo current in GameObject.FindObjectsOfType<PlayerInfo>()) { if(current == this)GUI.color = Color.red; GUILayout.Box(current.Name + " D [" + current.Deaths + "] K [" + current.Kills + "] S [ " + current.Score + "]" ); } }Bien, ahora podemos hacer nuestro test utilizando Inputs y la función Update void Update() { if(!isLocalPlayer)return; // Si no es el jugador Local Sale de la funcion UPDATE if(Input.GetMouseButtonDown(0))AddScore(100); if(Input.GetMouseButtonDown(1))AddKill(); if(Input.GetMouseButtonDown(2))AddDeath(); }FIN DE LA SEGUNDA PARTE Siguientes Sistema de Puntuaje + UNET + Simple UI Sistema de Salud + UNET + Simple UI Explicación más detalladas de Command Sistema de Disparos + UNET + Simple UI VIDEO TUTORIAL de todo lo explicado ¡SALUDOS A TODOS y SUERTE!
  14. Buenas! Como habréis notado por mi cantidad desorbitada de mensajes soy nuevo en la comunidad y me gustaría comentaros algunas dudillas que tengo respecto a la creación de gráficos, en este caso 2D, para los videojuegos que vaya haciendo en Unity3D. Llevo unos meses haciendo mini-juegos sin gráficos, con puros Debug.Log, y me gustaría empezar a darles un poco de color. Me gustaría enfocarme al diseño y desarrollo de videojuegos en 2D para PC principalmente, pero sinceramente no tengo ni idea de cómo empezar con el tema gráficos. Quiero hacerlos sencillos en un principio, en plan que te sangren los ojos, me da igual que sean feos porque no puedo pretender volverme un gran diseñador de la noche a la mañana, la cuestión es el tamaño en que debo hacerlos y que luego al importarlos en Unity se vean bien en todas las resoluciones y demás. Porque Unity puedo ponerlo a 800x600, 1280x720 o cualquier resolución y empezar a hacer el juego, pero supongo que si le meto la típica opción para elegir la resolución preferida o simplemente una vez terminado el juego la cambio, los gráficos no se verían igual o se pixelarían o cualquier cosa, entonces no sé cómo hacerlo, estoy hecho un lío la verdad... Y otra cosa que no entiendo es la opción de Pixels per unit cuando importas un sprite en Unity. He leído y he intentado entender de qué va eso o cómo se calcula, pero me está costando... Luego aparte, otra duda que tengo es si debo hacerlos cada uno por separado o tengo que crearme un spritesheet de esos en cuadricula y trabajar ahí directamente. Soy muy autodidacta y me puedo llegar a pasar horas viendo vídeos sobre estos temas y documentándome, pero todo esto no me ha quedado nada claro. No hay vídeos o guías que te enseñen todo el procedimiento de P a PA desde que creas el documento en Photoshop/GIMP hasta que lo importas en Unity, y si los hay, unos los crean de 50x50, otros de 256x256 otros de 128... incluso algunos que los hacen a lo bestia de 2000x2000 y yo ya me vuelvo loco, no sé por dónde tirar. A ver si alguien es capaz de darme un poco de luz porque estoy muy perdido y nada, gracias de antemano!
  15. Que tal Solo para compartirles un pequeño juego que hicimos para una Game Jam llamado Pizza Over Gun! Les dejo el trailer y más abajo el link para que lo prueben: Link al juego: https://ogre-pixel.itch.io/pizza-over-gun El juego no está terminado pero si es jugable al 100% =) Saludos!
  16. Buenas comunidad les dejo por aquí un proyecto personal que voy desarrollando poco a poco de uno de mis juegos preferidos Turok 2, un día hace ya tiempo se me ocurrió desarrollar una versión de este y varios juegos mas, la idea era sacarlos con un solo nivel pero tratare de que sean mas, y bueno aquí dejo unas imágenes de algunas armas y me comentar que les parecen salu2 Shotgun: Vértices: 1190 Caras: 1064 Triángulos: 2232 turok2fangame.blogspot.mx/2016/07/shotgun.html Razor Wind: Vértices: 550 Caras: 512 Triángulos: 958 turok2fangame.blogspot.mx/2016/07/razor-wind.html Cerebral Bore: Vértices: 2868 Caras: 2322 Triángulos: 5080 turok2fangame.blogspot.mx/2016/07/cerebral-bore.html Bow / Tek Bow: Bow: Vértices: 794 Caras: 784 Triángulos: 1528 Tek Bow: Vértices: 622 Caras: 458 Triángulos: 1040 turok2fangame.blogspot.mx/2016/07/bow-tek-bow-turok-2.html EDIT: Talon: Vértices: 526 Caras: 464 Triángulos: 992 http://turok2fangame.blogspot.mx/2016/07/talon.html War Blade: • Vértices: 858 • Caras: 772 • Triángulos: 1592 http://turok2fangame.blogspot.mx/2016/07/war-blade.html
  17. Not Jump ¡Buenas chicos! Tal y como dije por el grupo de Telegram de UnitySpain, aquí os traigo mi primer videojuego para iOS. El juego funciona para todos los dispositivos iOS 6.0 o superior, includo iPod Touch. El juego es super sencillo, he querido hacer uno dónde el jugador tuviera que obtener la máxima puntuación posible y que fuera bastante difícil de conseguir(el récord de momento está en 3 puntitos jejeje). La jugabilidad es la siguiente: deslizar la bola hacia derecha o izquierda para hacer que salte y poder pasar por las barreras que van subiendo. He querido crear un pasatiempo tonto que no gaste casi nada de batería y sea entretenido. Os adjunto algunas imágenes: Aquí os dejo el link de descarga: Descarga Not Jump ¡Si veo que el juego tiene aceptación lo subiré para Android! Un saludo, ¡y a seguir desarrollando! :)
  18. pioj

    Unite Europe

    until
    El próximo 31 de Mayo haremos un seguimiento especial del evento UNITE EUROPE. Informaremos sobre las novedades que presenten y aprovecharemos para promocionar un poco más la Comunidad.
  19. Hola gente. Estoy intentando realizar una animación con un Sprite 2D, os cuento: Cuando salto quiero que al coger altura tenga una animación, un sprite y cuando caiga tenga otra forma el sprite. He realizado las animaciones y las transiciones entre el reposo y el salto y he realizado también el Script pero no consigo realizar lo que yo quiero. El primer problema es que al pulsar el Space que es mi tecla de salto, no cambia la animación o si cambia lo realiza en medio del salto y luego la animación del salto no es como quiero porque no cambia cuando coge altura y cuando pierde altura. Os copio el Script a ver si me podéis echar un cable. using UnityEngine; using System.Collections; public class Movimiento : MonoBehaviour { public float velocidad = 3f; public float fuerzaSalto = 100f; private bool enSuelo = true; public Transform comprobadorSuelo; private float comprobadorRadio = 0.07f; public LayerMask mascaraSuelo; // Máscara para identificar elementos suelo. Es como un tag, así identificamos como suelo a todos los elementos que nosotros queramos. private bool dobleSalto = false; private Animator animator; void Awake () { // Función que se llama al inicio una vez. animator = GetComponent<Animator> (); } // Use this for initialization void Start () { } void FixedUpdate() { // Esta función es para que se llame a la función cada intervalo de tiempo, no cada Frame como hace Update ya que cada ordenador es más o menos rápido // y no coincidiría con todos los dispositivos. enSuelo = Physics2D.OverlapCircle(comprobadorSuelo.position, comprobadorRadio, mascaraSuelo); animator.SetBool ("isGrounded", enSuelo); if (enSuelo) { dobleSalto = false; } } // Update is called once per frame void Update () { if (Input.GetKey (KeyCode.RightArrow)) { this.transform.Translate (Vector3.right * velocidad * Time.deltaTime); } if (Input.GetKey (KeyCode.LeftArrow)) { this.transform.Translate (Vector3.left * velocidad * Time.deltaTime); } if ((enSuelo || !dobleSalto) && Input.GetKeyDown (KeyCode.Space)) { //if (Input.GetKey (KeyCode.Space)) { --> No usar esto para que no se mantenga el salto. Sólo quiero que al pulsar salte, no se mantenga como al caminar. // Insertar código de salta. Comprobar cual es la mejor opción GetComponent<Rigidbody2D>().velocity = new Vector2(GetComponent<Rigidbody2D>().velocity.x, fuerzaSalto); // Para que el segundo salto cuando el personaje esté cayendo del primero se note que salta y no solo se mantenga. //GetComponent<Rigidbody2D>().AddForce(new Vector2(0, fuerzaSalto)); if (!dobleSalto && !enSuelo) { dobleSalto = true; } } } }El Script está en C# y funciona correctamente (no saltan errores). En animator he realizado dos parámetros, uno llamado VelX para el modo correr que aún no he realizado y otro llamado isGrounded para saber que el Sprite está tocando el suelo. Además he realizado un Layer "Suelo" para que el Sprite sepa cuales son los elementos "Suelo" y así pueda diferenciar cuando está tocándolo. Cuando pulso la tecla espaceadora el parámetro "isGronded" pasa correctamente a false pero no ejecuta la animación. Además luego no se como realizar que un Sprite se ejecute cuando coge altura y otro cuando la pierde. ¿Podéis ayudarme o guiarme? Gracias de antemano, un saludo a todos.
  20. Buenas a todos, espero que anden bien. Como dice el titulo voy a aportar un pequeño componente que he creado hace un tiempo ya, se trata de un Timer, este nos permite gestionar el tiempo en segundo para efectuar acciones, consta de una muy simple implementacion, solo importamos una DLL a nuestro proyecto, luego agregamos en nuestra escena el Controlador del Timer. Con esto ya estaría configurado para utilizar, ahora vamos al script donde queramos agregar un Timer y agregamos la librería CustomTool. ¡Script de Ejemplo! using UnityEngine; using System.Collections; using CustomTool; public class Weapon : MonoBehaviour { private TimerItem _timerReload; private int _cadence = 1; private float _tmpCadence = 0; private void Start() { _timerReload = Timer.Singletone.QuickTimer (1, false, true); ReloadEventSetup (); } private void Update() { if(Input.GetKeyDown(KeyCode.R)) { _timerReload.Start (); } if (Input.GetMouseButton (0) && !_timerReload.IsRuning) { if (_checkCadence) { Shot (); } } } private bool _checkCadence{get{ if(_tmpCadence < Time.time){ _tmpCadence = _cadence + Time.time; return true; } else return false; }} public virtual void Shot() { print ("shoting"); } public virtual void Reload() { print ("Finish Reload"); } private void ReloadEventSetup() { _timerReload.EventStart += () => { print ("start reloading"); }; _timerReload.EventFinish += () => { Reload(); }; _timerReload.EventStop += () => { }; } } Como veras se maneja por Eventos, estos son muy descriptivos con sus propios nombre. 1- Para crear el Timer utilizamos la siguiente función Timer.Singletone.QuickTimer(TiempoDeEspera,AutoRepeticion,GestionManual); 2- Utilizamos la Funcion Start para dar inicio al Contador. 3- Si deseamos terminar con el contador antes de que este finalice utilizamos Stop. 4- Para limpiar todos los contadores utilizar Timer.Singletone.ClearAll(). 5- Para detener todos los contadores utilizar Timer.Singletone.StopAll(). Existen algunas cositas mas, esta completamente en Español podes guiarte muy fácilmente. ¡Saludos! Timer.rar Link en MEGA por si falla el del Foro https://mega.nz/#!cslnkShQ!jnJnbSSBtYg7gxeAHvQ00IUxyR0_tbrChxJ-pXZGvz8
  21. Bienvenidos a la cuarta entrega de UNET. En esta tratare de cubrir lo necesario para efectuar un disparo, como vimos en anteriores tutoriales logramos un movimiento, sincronizacion y sistema de salud funcional, aun que no de la mejor manera. En este tutorial vamos a necesitar utilizar Commandos. Bueno vamos al grano, para empezar debemos crear nuestro componente PlayerWeapon(Opcional), cabe destacar que cada juego tiene un GAME PLAY propio por lo tanto obviamos como funcionan los aspectos del mismo. Para poder enviar un dato, como lo necesitamos en este momento, el impacto de la bala con nuestro enemigo debemos tener los datos de nuestro enemigo, una forma muy simple de poder interactuar con otro jugadores es obteniendo su ID de red. Suponiendo que tenemos nuestro sistema de Armas con el método Raycast ya listo, nos daremos cuenta que siempre obtenemos un dato de las colisiones para frente a este seguir diferentes acciones. EJ: private void Shot() { Ray = Camera.Look; RaycastHit Hit; if(Raycast out Hit) { if(Hit == "Enemy") { Ejecuta Accion } } }Por lo genera siempre es de esta manera, bueno cuando trabajamos con networking se sigue haciendo del mismo modo. y el dato que tomamos el el ID a este lo enviamos por comando, y el servidor se encarga de aplicarle el daño en este caso. public void Shot() { Codigo de Disparo por RayCast, tomamos el net id y lo enviamos por commando Cmd_TakeDamage(hit.NetID); //EJEMPLO } [Command] private void Cmd_TakeDamage(uint PlayerTake, int Damage) { //buscamos los jugadores que corresponden al ID,con una simple funcion var otherp = FindPlayer(PlayerTake); if(otherp != null) { //llamamos la funcion de Take! otherp.playerHealt.HealtTake(50); } } private void FindPlayer(uint ID) { foreach(var p in GameObject.FindObjectsOfType<PlayerControl>()) { if(p.netId.Value = ID) { return p; } } return null; } public class PlayerControl : NetworkBehaviuor { public PlayerHealt playerHealt; public override void OnStartClient() { playerHealt = GetComponent<PlayerHealt>(); } } public class PlayerHealt : NetworkBehaviuor { [SyncVar] int current = 100; [Server] internal void HealtTake(int value) { current -= value; } }De esta simple manera tendríamos ya nuestro sistema de disparo funcionando, ahora deberíamos mejorarlo para que funcione aun mejor. !Importante¡ Cuando se trata de la programación de videojuegos o aplicaciones en red uno de los temas mas importantes son los de Seguridad, cuando se trabaja con dinero real este punto se refuerza con personal altamente calificado y experimentado, quiero decir que si la idea que tienes es crear un juego Online estilo AVA u otro MFPS y aun no tienes el personal y la experiencia necesaria, entonces no lo intentes. Esta serie de Información y Tutorial es solo para lograr juegos en red simple, para poder compartir con amigos o mejor aun un simple sistema networking donde la vulnerabilidad no se un problema grave. Bueno gente, como les prometí esta es la cuarte entrega, no es el material mas detallado pero se pueden dar cuanta de la fácil implementacion que UNET nos presta en su librería de Alto Nivel para networking. Mi idea es que si alguien necesita algo mas detallado solo comente y explicare paso por paso como lograr. obvio si es que entiendo lo que necesite. No olviden visitar mi Blog! Un abrazo -. Franco
  22. Saludos. Tengo un problema con mi proyecto de Realidad aumentada en Unity3D utilizando el SDK de Vuforia y tratando de compilarlo en Xcode para ponerlo en un dispositivo iPhone o iPad, la situacion es que si me compila el proyecto pero a la hora de ver el marcador no me aparecen los modelos 3D que le agregue a la escena. Datos de Platafomas: -Unity 3D 5.3.1 -Vuforia SDK 5.0.10 -Xcode 7.2 Adjunto un screen de como se ve mi proyecto en Xcode.
  23. Hola comunidad, es la primera vez que escribo en el foro, estudio diseño de videojuegos y soy de los que hacen las cosas solos, tocando y rompiendo, y volviendo a romper. Pero ahora estoy con un problema que la verdad no se me ocurre como solucionarlo. La cosa es asi, tengo un enemigo al que al dispararle con raycast, resta vida y muere perfecto, ahora bien, para detectar la colision estoy usando CompareTag, el problema es que cuando duplico este enemigo ("zorro"), al dispararle a uno, le estoy restando vida al otro tambien, y al volver a dispararle, muere el otro enemigo al que no le dispare. probe varias cosas, pero ninguna me resulto. Les paso mis scripts del player y el de la vida del enemigo. Espero alguno me pueda ayudar! SCRIPT PLAYER MANAGER: http://hastebin.com/oqaqiremas.avrasm Desde ya mil gracias!
  24. Bienvenidos a otro tutorial de UNET. Como vimos en anteriores tutoriales, para poder sincronizar una variable en nuestro jugador locas debemos primero asignarla y luego enviar ese valor al servidor. EJ : (P-Local) Cambió su posicion --(Envia a traves de comando su nueva posicion al servidor)--> (SERVER) El servidor recibe estos datos y los envía a todos los Clientes. Teniendo esto en cuenta, para lograr un Sistema de Salud funcional debemos primero tener el valor de la salud actual, un evento que se llame cuando muere, 2 funciones una de daño y la otra de recuperación, y por ultimo el comando para enviar el estado de nuestra salud. Vemos... Primero creamos lo básico. public const int MaxHealt = 100; [SyncVar] public int Healt; public delegate void d_Death(); [SyncEvent] public event d_Death EventDeath; [Client] public void TakeDamage(int value) { Healt -= value; Healt = Mathf.Clamp(Healt,0,MaxHealt); } [Client] public void TakeCure(int value) { Healt += value; Healt = Mathf.Clamp(Healt,0,MaxHealt); }bien con esto ya tendríamos nuestro Sistema de salud casi terminado, pero debemos tener algunas cosas en cuenta. Jamás un jugador va a poder infringir directamente daño a otro, de esto se encarga el servidor, pero existe una problemática, cuando nosotros ejecutamos un disparo, este evento es gestionado por el servidor, entonces es el Servidor en nombre de X Cliente dueño del disparo, supongamos que este impacta con otro jugador, ¿Quien resta la salud?, La respuesta es el Servidor. Es decir, si nosotros llamamos una funciona cualquiera desde un comando estamos haciéndolo en nombre del servidor. (CLIENTE) ---> Ejecuta ---> COMMAND ---> (SERVIDOR) ---> Ejecuta Funcion ---> TakeDamage(); Dicho lo anterior, podremos darnos cuanta de que no existe interacción Cliente/Cliente por lo que esto se denomina Cliente/Servidor. ¿Cual es realmente la problemática?, Aunque existan varios problemas relacionados solo con un sistema de salud, deberíamos destacar el mas importante. El Jugador local solo debe enviar su estado, no hay que confundir, es decir, el servidor no se debe de encargar de procesar si está muerto o no, para eso creamos nuestro sistema. Vi muchos errores a la hora de implementar funciones incoherentes, por ejemplo, que todos los jugadores comprueben si la salud es menor o igual a cero entonces esta muerto. void Update() { if(Healt <= 0) { IsDeath = true; } }Esto es un grave error, porque los tiempos de sincronización pueden variar según el Ping (Tiempo de Envío y Recibo de Datos) que el Cliente y servidor tengan. vamos a dar un Ejemplo: Tenemos 4 Clientes en un servidor, Cliente 1 dispara y le quita 100 de salud al Cliente 2 Esta acción tomó un tiempo de. 1- Cliente 1 (Enviar Datos del disparo al Servidor y Retornar Resultados) : 2s 2- Cliente 2 (Recibe la noticia de que se le a impactado, el servidor llama a su función TakeDamage(), luego, el Cliente 2 envía los dato de su estado al Servidor) : 4s 3- Clientes (Servidor Actualiza el Estado del Cliente 1 en todas las instancias del juego, diciendo que el valor de Healt es cero) 1s Vemos que en el Punto 1 el Cliente 1 ya sabe que le infligió daño al Cliente 2, pero aun el Cliente 2 no se enteró, suponiendo que el primer paso Duro solo 1s, ya que el segundo añadido es el tiempo que el Servidor tardó en enviar esa información al Cliente 1, el Cliente 2, por lo tanto recibe daño, y envía el valor de Healt al servidor, 4s + 1s que el servidor toma para enviar los datos de este evento al Cliente 3, 4 es el retardo que existiría, suponiendo así, que cada instancia debería comprobar aún si el Cliente 2 está vivo, pero qué pasa si en ese lapso de 4 segundo el Cliente 2 sobrevive, es decir, un ejemplo, lo reviven estilo BF, el Cliente 1,3,4 tendrían una mala información. en destiempo. Aunque el ejemplo en cierta forma parece no tener coherencia el problema se presenta cuando múltiples clientes con distintos tiempos de respuestas se conectan al servidor, este error puede llegar a hacernos ver el jugador muerto disparando. ¿Cómo lo solucionamos? La solución en cierta parte, sería utilizar Eventos, va a seguir existiendo un tiempo de retardo, es normal, pero la información de las instancias de cada cliente va a ser más clara. [SyncVar] internal bool IsDeath; [SyncEvent] public event d_Death EventDeath; void Update() { if(!isLocalPlayer)return; if(Healt <= 0 && !IsDeath) { IsDeath = true; if(EventDeath != null)EventDeath(); Cmd_SendInfo(Healt,IsDeath); } } [Command] private void Cmd_SendInfo(int healt, bool isDeath) { Healt = healt; IsDeath = isDeath; if(IsDeath)if(EventDeath != null)EventDeath(); }De esta manera estamos enviando de una manera, quizas un poco desprolija nuestra información al servidor, pero si prestaron atención en la función Update, se agregó un condicional para saber si es el jugador local, ya que solo él, podrá gestionar su salud y avisar al servidor su estado. Hay que entender, que aunque Unet Serialize nuestros datos y los optimice podemos ayudar también nosotros, a que esta tarea sea aun mas optima, por ejemplo enviando un string formateado de una manera para guardar el valor de nuestras variables. string Data = "100/0"; [Command] private void Cmd_SendInfo(string data) { string[] values = data.Split('/'); Healt = int.Parse(values[0]); IsDeath = int.Parse(values[1])? false : true; Data = data; } de esta manera optimizamos el paquete, ya que solo enviamos un dato. Bueno eso es todo por ahora, espero les sirva. Para tener un poco más organizados mis tutoriales abrí un Blogger donde encontraran todo mi material y podrán seguir mis tutoriales de UNET. http://unitydoc.blogspot.com.ar/ Saludos
  25. ¡Buenas a Todos! Para Empezar necesitamos una version 5 de Unity3D (Mejor si es la Última), conocimiento en programacion C#, breve idea de cómo funcionan Servidores Autoritativos. Primero Pasos 1- Empecemos por crear un objeto vacío en la escena y agregamos el componente de NetworkManager y NetworkManagerHud. 2- Crear un Script en C# asignar el nombre de PlayerSetup (Opcional) agregar la librería UnityEngine.Networking y la clase PlayerSetup que herede de NetworkBehaviour. 3- Empezar con la Programacion del Movimiento: A- Programar un movimiento, simple sin fisicas. private void Movement() { Vector3 Direction = new Vector3(Input.GetAxisRaw("Horizontal"),0,Input.GetAxisRaw("Vertical")); Direction = transform.TransformDirection(Direction); Vector3 NextPosition = transform.position + (Direction * Time.deltaTime * 5); transform.position = NextPosition; } B- Para llamar a esta función debemos primero comprobar si somos el Jugador Local (isLocalPlayer). C- Volvemos a la escena donde teníamos nuestro NetworkManager creamos un cubo y le asignamos nuestro componente PlayerSetup, automáticamente se añadirá junto a este otro componente llamada NetworkIdentity, en el debemos seleccionar la opción LocalPlayerAuthority creamos un prefabs del cubo y lo borramos de la escena. D- Nos dirigimos al componente NetworkManager, vamos a donde dice SpawnInfo y en el lugar de PlayerPrefab asignamos el que creamos anteriormente. E- Volvemos al Script PlayerSetup y desde la función Update ahora podemos llamar a nuestra función Movement, antes comprobando si es el Player Autorizado. public void Update() { if(!isLocalPlayer) { //CLIENTE NO LOCAL return; //Si no es el jugador termina la ejecución de Update } else { //CLIENTE LOCAL Movement(); } }4- ¡Excelente!, Ahora si compilamos para Windows podremos ver que el cubo se mueve en ambas ejecuciones, pero nos daremos cuenta de que el Jugador 1 no podrá ver el movimiento del Jugador 2 Sincronizando el movimiento 1- Para sincronizar el movimiento en red se utiliza una técnica llamada predicción de la posicion, esto quiere decir que mientras nos movemos de manera local el servidor intercepta multiples actualizaciones de nuestra posicion pero como el movimiento no va a ir por un canal seguro, podría perderse un paquete o simplemente el Ping sea muy alto y los clientes no locales experimentarian un movimiento extraño en los demás clientes. ¿Cómo creamos una sincronización? A- Para sincronizar debemos enviar los datos al servidor, gracias a UNET podemos utilizar SyncVar y Command para hacer este trabajo mucho más simple que el conocido "Serialize and Deserialize" de paquetes. Para empezar necesitamos crear una variable privada tipo Vector3 donde almacenamos nuestra posicion, y una función de tipo void con los atributos de Command ¿Qué son los Command? Son funciones que se encuentran del lado del Cliente pero siempre se ejecutan en el servidor. ¿Que el SyncVar? SyncVar nos sirve para que una variable esté sincronizada para todos los Cliente. ¡A tener en cuenta! Si nosotros cambiamos una variable de forma local, sin avisarle al servidor, los demás clientes no estarán enterados de este cambio, para que un SyncVar funciones esta debe ser modificada por el servidor, y este mismo se encarga de actualizar el valor en todas las instancias de cliente. Veamos el Código [SyncVar] private Vector3 SyncPosition; [Command] private void Cmd_SendPosition(Vector3 Pos) { SyncPosition = Pos; }2- Ya tenemos nuestro sistema para Sincronizar la posicion de nuestro jugador, ahora vamos a ponerlo en marcha, aun nos faltan 2 pasos muy importantes, al cliente local no le interesa el valor de SyncPosition, ya que este no depende de tal variable para su movimiento, pero no obstante los otros clientes no locales van a tomar ese dato para ubicarte en su espacio local. ¿Cómo hacemos esto?, vimos que nuestra función Update está separada en dos partes, la primera para los clientes NO LOCALES y la segunda es solo para clientes LOCALES, quiere decir que vamos a utilizar la parte no local para sincronizar nuestro movimiento en los demás clientes. A-Vamos a enviar la informacion de nuestra posicion al servidor utilizando el comando Cmd_SendPosition(), esto lo realizamos desde nuestra función Movement(); Cmd_SendPosition(NextPosition); B- Seguido a esto, nos dirigimos a nuestra función Update en la parte no local y creamos un movimiento Suave entra la posicion actual del Player no local y la de la variable Sincronizada transform.position = Vector3.MoveTowars(transform.position,SyncPosition, Time.deltaTime * 15); C- Por Último Compilamos nuestro proyecto y veremos como el movimiento se encuentra sincronizado en ambos clientes. El Código debe quedar de la siguiente manera public void Update() { if(!isLocalPlayer) { //CLIENTE NO LOCAL transform.position = Vector3.MoveTowars(transform.position,SyncPosition, Time.deltaTime * 15); // Movimiento del Jugador en ambiente no local return; //Si no es el jugador termina la ejecución de Update } else { //CLIENTE LOCAL Movement(); } } [SyncVar] private Vector3 SyncPosition; [Command] private void Cmd_SendPosition(Vector3 Pos) { SyncPosition = Pos; } private void Movement() { Vector3 Direction = new Vector3(Input.GetAxisRaw("Horizontal"),0,Input.GetAxisRaw("Vertical")); Direction = transform.TransformDirection(Direction); Vector3 NextPosition = transform.position + (Direction * Time.deltaTime * 5); Cmd_SendPosition(NextPosition);//Enviar información al Servidor. transform.position = NextPosition; }Bueno, eso es todo por hoy, el material es escrito para tratar de explicar mejor las cosas. Siguientes Sistema de Puntuaje + UNET + Simple UI Sistema de Salud + UNET + Simple UI Explicación más detalladas de Command Sistema de Disparos + UNET + Simple UI VIDEO TUTORIAL de todo lo explicado ¡SALUDOS A TODOS y SUERTE!
×
×
  • Create New...