Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 07/15/2019 in all areas

  1. 7 points
    Hola gente les dejo un link a mi curso de youtube, totalmente gratuito y disponible para la comunidad. Esta totalmente actualizado al 2020 y hecho por mi, soy programador con titulo universitario y 10 años de experiencia en unity! El curso esta dividido en niveles de dificultad, Comenzando para gente que nunca toco unity y terminando con contenido muy avanzado como creacion de framework propios para multiplayer, entre otras cosas. Para que los usuarios mas avanzados puedan saltearse las partes que no les sirve y explorar mas fácilmente el contendio. Son mas de 200 videos, con muchisimas horas de grabacion que complete con la intención de subir a udemy. Al terminarlo cambie de parecer y ahora lo estoy subiendo de forma gratuita a youtube. Se sube 1 video cada dia de forma atomatica, y ya estan todos los videos seteados para subirse a youtube de forma automatica a este ritmo. Link: https://www.youtube.com/channel/UCl3p_fKnx2-GIUWVbiDAcMg Sin mas, espero verlos por mi canal y que les sirva el curso. Un saludo!!
  2. 6 points
    Estoy leyendo el libro "Unity Game Optimization" que está en Packt y la tercera edición es de noviembre de 2019. He hecho un resumen de los apartados dedicados a scripting que me parecen muy buenos. Algunos los conoceréis, otros no y otros es posible que no supiérais porqué utilizar una manera u otra. En todos los casos el concepto de optimización ve sus frutos cuando es un desarrollo de cierto tamaño. Desde mi punto de vista, si empiezas con buenos hábitos, luego no tendrás los mismos problemas de rendimiento que el resto de desarrolladores. La optimización se debe realizar desde el día 1. Paso a relatar. Optimización 1 Eliminar las callbacks vacías de Start() y Update() al crear un script si no son necesarias. El tenerlas afectará a la inicialización de la scene y al instanciar prefabs. La de OnGUI() es especialmente problemática ya que puede llamarse más de una vez por frame. En la de Update() se realiza un Native-Managed Bridge, o sea, hay que enlazar el modo managed de C# con el del código nativo dependiente de plataforma. En general no dejar nunca una callback vacía. Optimización 2 Cómo obtener los componentes de un GameObject. Hay tres maneras de hacerlo, aunque a la práctica se utilizan dos de ellas. Los datos hablan por si mismos para 30.000 objetos. // 6413 ms test = (TestComponent)GetComponent("TestComponent"); // 89 ms test = GetComponent<TestComponent>(); // 95 ms test = (TestComponent)GetComponent(typeof(TestComponent)); El mejor es del uso del template o tipo genérico. Como en C++ ;) Optimización 3 Cachear los GetComponent, preferiblemente en el Awake. Esto es realmente crítico si se realiza en el Update. Al final obtendremos un mejor rendimiento a cambio de un coste de memoria mínimo (entre 32 ó 64 bytes por item dependiendo de la plataforma). Optimización 4 El uso de funciones dentro de Update. Si las acciones no requieren se llamadas en cada frame es mucho mejor convertirlo a un InvokeRepeating que puede llamarse en el Start y cancelarse en el OnDestroy: private void Start() { InvokeRepeating("ProcessAI", 0f, _aiProcessDelay); } Optimización 5 La comparación de objetos null. La llamada directa de "gameobject == null" genera una conversión Native-Managed Bridge con la consiguiente sobrecarga. Es mucho mejor utilizar el ReferenceEquals que no utiliza la conversión. Por eso se incluyó en Unity: if (!System.Object.ReferenceEquals(gameObject, null)) { // No es null } Optimización 6 La comprobación con Tag directa genera memoria adicional y hará actuar al GC posteriormente. Utilizar el CompareTag no utiliza memoria ya que evita el Native-Managed Bridge completamente y tarda la mitad de tiempo: // Asignación de memoria y GC. Tarda el doble de tiempo if (gameObject.tag == "Player") { // realizar acción } // Evita el Native-Managed Bridge totalmente. No asigna memoria adicional if (gameObject.CompareTag ("Player")) { // realizar acción } Optimización 7 Dictionary vs List. Las List son mejores para iteraciones. Los Dictionary son mejores para búsquedas aleatorias. El Dictionary es peor para las iteraciones debido a que debe realizar una comparación hash para cada uno de los elementos. De todos modos tener los dos tipos en algunas situaciones no es mala idea. Optimización 8 La Transform. Cuando instanciamos un nuevo GameObject con GameObject.Instantiate(), uno de sus argumentos es el componente de la Transform del parent que queremos asignar, que por defecto es null y colocará el GameObject en el root. Todas las Transforms que está a nivel root necesitar crear un buffer de memoria para poder almacenar los children que tienen más aquellos que vendrán después. Esto no ocurre con las Transforms que son child. Pero si una Transform en root le cambiamos el parent una vez creada y la reasignamos, se procederá a descartar el buffer de memoria que iniciamos en el Instantiate. Para evitar esto es mejor proveer del parent en la función. Otro apartado interesante es que, hay una propiedad en la Transform llamada hierarchyCapacity. Si somos capaces de estimar el número de Transform child de este objeto root, podremos reducir el número de asignaciones de memoria. Optimización 9 World Position, World Rotation, World Scale. Cuánto más profundo esté en la jerarquía un objeto mayores cálculos son necesarios para determinar el resultado final de su estado. Esto significa que es mucho más eficiente utilizar los elementos de Local que de World. Optimización 10 Cambios en la Transform. Si es posible, agrupar todos los cambios en una Transform y no realizarlos hasta el final de todos los cálculos y en FixedUpdate. Esto evitará movimientos extraños o teleportaciones de los objetos debido a que Unity lanza eventos internos cada vez que una Transform es modificada. private bool _positionChanged; private Vector3 _newPosition; public void SetPosition(Vector3 position) { _newPosition = position; _positionChanged = true; } private void FixedUpdate() { if (_positionChanged) { transform.position = _newPosition; _positionChanged = false; } } Optimización 11 SendMessage y Find. El método SendMessage() y la familia de métodos GameObject.Find() so especialmente costosos y deben evitarse en su totalidad. El método SendMessage() es como 2,000 veces más lento que una simple llamada a una función, y el coste de Find() se escala pobremente según la complejidad de la scene aumente ya que tiene que iterar por todos los GameObject de la misma. Optimización 12 No solamente Occlusion Culling/Frustum Culling. Para los objetos que solamente tienen renderizado es factible utilizarlas únicamente. Otros objetos que utilicen cálculos internos de manera constante continuarán consumiendo a pesar del Culling. Una buena solución a este problema es utilizar las callbacks OnBecameVisible() y OnBecameInvisible(). Como los nombres dicen, estas callbacks son invocadas cuando un objeto renderizado se ha vuelto visible a una cámara o invisible respecto a todas las cámaras de la scene. Además, cuando hay múltiples cámara en la scene (por ejemplo en un juego multiplayer) las callbacks son solamente invocadas cuando es visible para una cámara o invisible para todas ellas de igual modo. Esto significa que las callback serán llamadas en el momento preciso que se necesitan. Si nadie puede ver el objeto se llamará a OnBecameInvisible(), si como mínimo un player puede verlo se llamará a OnBecameVisible(). Optimización 13 Distance vs sqrMagnitude. El cálculo de raíces cuadradas para las CPU implica bastante proceso comparado con otras instrucciones. Cuando tengamos que utilizar un cálculo de distancia, y si no requerimos de una precisión extrema, es mejor utilizar sqrMagnitude y valor a comparar por su potencia de 2. // Utilizar la raíz cuadrada en Distance() float distance = (transform.position – other.transform.position).Distance(); if (distance < targetDistance) { // dentro de distancia } // No realiza el proceso anterior float distanceSqrd = (transform.position – other.transform.position).sqrMagnitude; if (distanceSqrd < (targetDistance * targetDistance)) { // dentro de distancia } Optimización 14 Datos de Prefab a un Scriptable Object. Si tenemos muchos diferentes tipos de Prefabs que contienen datos que pueden compartirse entre ellos, como fuerza, velocidad, puntos, etc. entonces todos estos datos serán serializados en cada Prefab que luego se instancie. Una mejor solución es serializar estos datos en un ScriptableObject. Esto reduce la cantidad de datos a serializar en el Prefab, el tiempo de deserialización y el tamaño del Prefab en sí mismo reduciendo el tiempo de acciones que serán repetitivas. Optimización 15 Update(). Una mejor solución al problema del Update() es no utilizar nunca, o mejor dicho, una sola vez. Cuando Unity llama al callback Update(), o cualquiera relacionado, cruza la ya comentada frontera del Native-Managed Bridge que es una tarea costosa en términos relativos. En otras palabras, el coste de procesamiento de 1.000 Update() independiente será mucho más costoso que la ejecución de un Update() con 1.000 funciones. Para poder minimizar este problema es mejor agrupar todos los Update() en un solo Update() global que luego llame a las diferentes funciones que requieran la acción.
  3. 6 points
    Introducción En esta ocasión vamos a crear una Carta con un efecto 3D similar a la que vemos en el gif anterior. Para ello vamos a partir de un proyecto donde tenemos preparados los assets necesarios. Este proyecto podemos descargarlo desde aquí: URL: https://drive.google.com/open?id=19J6lgCA-DH28lMu9dmntk1K5l3lPE66f Una vez descargado vamos a abrirlo desde el Unity Hub. Este proyecto está creado con la versión 2019.2.9f1 asique podría ser incompatible con versiones anteriores. Una vez abierto vamos a tener una escena llamada “Sample Scene” y una serie de carpetas con los modelos,sprites,prefabs… necesarios. Además contamos con los paquetes TextMeshPro y PostProcessing que usaremos a lo largo del tutorial. Puedes acceder en todo momento a los paquetes usados a través del Package Manager. Preparando el proyecto En primer lugar vamos a abrir la escena “Sample Scene” y vamos a arrastrar en ella el prefab “Hornet” dentro a la ventana de Hierarchy. Verás que aparece en rosa, eso es debido a que no tenemos aún ajustado el Render Pipeline. Vamos a empezar por ahí. Vamos a crear una carpeta Settings donde colocaremos aquellos ajustes globales del proyecto. Siéntete libre de elegir otro nombre, yo siempre soy malisimo poniéndolos. Una vez creada vamos crear una configuración pulsando click derecho y Create/Rendering/LightweightRenderPipeline/PipelineAsets. Elige el nombre que quieras y seleccionalo para verlo en la ventana de Inspector. Aquí tenemos los ajustes del Render Pipeline. La configuración es muy intuitiva y prácticamente todo hace lo que indica. En nuestro caso solamente vamos a activar el HDR y el antialiasing. Lo demás no lo tocaremos, aunque esto va de experimentar, así que “rómpelo” a tu gusto. Una vez creado vamos a añadirlo a nuestro proyecto, para ello vamos a irnos a ProjectSettings/Graphics y lo colocamos en el hueco de Scriptable Render Pipeline Settings. Hecho esto si volvemos a la escena podemos ver que el color rosa ha desaparecido. Aunque ahora se verán blanco. No te preocupes que ese será nuestro siguiente paso. También verás que hay una luz añadida dentro del prefab de Hornet. Está configurada por mi pero llegado el punto puedes quitarla o cambiarla como quieras. Creación de Shaders Vamos a darle color a nuestros objetos ahora. Como has podido ver todos los objetos están en blanco. Eso es porque nuestros shaders y materiales están por defecto. Para nuestro objetivo vamos a necesitar crear un shader con la herramienta Shader Graph. Esta ya viene por defecto en todos los proyectos que usen el Scriptable Render Pipeline nuevo. Para ello vamos a crear una nueva carpeta llamada Shaders y vamos a crear un nuevo Shader PBR (Create/Shader/PBR Graph). Puedes ponerle el nombre que quieras, en mi caso lo he llamado Standard_SG (ya he dicho que soy muy malo poniendo nombres). Vamos a seleccionarlo y abrirlo. No es el objetivo de este taller aprender a usar ShaderGraph, asique no voy a pararme en explicar el contenido, aunque como veréis es muy fácil e intuitivo lo que haremos. Crearemos las siguientes variables: Conectaremos al Albedo un Sampler de una textura y la multiplicaremos por un color. Cómo veis el shader es lo más simple posible. Haremos lo mismo en el canal de Emission para poder ajustar la emisión de algunos objetos posteriormente. Pulsamos en Save arriba a la izquierda y cerramos. Ya tenemos nuestro shader creado pero tenemos un problema que veremos a continuación. Stencil Buffers Para obtener el efecto que buscamos tenemos que conocer el concepto de Stencil Buffer. Con ellos podemos principalmente renderizar unas partes de un objeto y descartar otras. Aquí podemos obtener más información: https://docs.unity3d.com/Manual/SL-Stencil.html https://www.ronja-tutorials.com/2018/08/18/stencil-buffers.html El objetivo es mantener “invisible” un objeto y que cuando este se encuentre en la “visión” de otro objeto, se muestre. Vamos a necesitar por dos shaders: Uno que leerá del stencil buffer y se dibujará solo donde el búfer tenga un valor específico, en cualquier otro lugar se descartará. Por otro, un shader que permanerá siempre invisible y que solamente mostrará aquellos valores específicos que coincidan con el stencil buffer. Para el primer solo necesitamos añadir unas líneas, pero actualmente no es posible hacerlo a través del ShaderGraph. Por lo que vamos a realizar una transcripción del Shader Graph al código. Para esto vamos crear un nuevo Shader Unlit pero esta vez no será de ShaderGraph. Le ponemos de nombre Standard_StencilRead por ejemplo y lo abrimos. Mientras se abre vamos a volver al Shader Graph y vamos a realizar la copia del código del shader. Para ello nos vamos al PBR Master Node y con el botón derecho seleccionamos Copy Shader. Una vez copiado vamos a pegarlo en nuestro reciente nuevo shader unlit creado, sobreescribiendo todo lo que este tuviese. También deberás cambiar la primera línea y ponerle tu la dirección y el nombre que elegimos antes. En mi caso lo he guardado en MyShaders con el nombre Standard_StencilRead. Ahora tenemos el mismo shader de Shader Graph pero en código para poder modificarlo. Vamos a necesitar añadir una nueva propiedad que será el valor específico del stencil. Simplemente dentro de properties al final, debajo del Color añadimos lo siguiente: [IntRange] _Stencil ("Stencil Value", Range(0,255))= 0 Quedando de la siguiente manera: Por último vamos a necesitar añadir los ajustes del Stencil debajo de los Tags antes de los diferentes pases. Esto hará que sólo cuando tengamos el valor de referencia, el objeto se muestre. Podemos obtener más información sobre la sintaxis y el contenido en los enlaces que anteriores. Ya podemos guardar el shader y volver a Unity. Tenemos preparado nuestro primer Shader. Para el segundo simplemente creamos otro shader unlit de nombre StencilWrite por ejemplo. Este estará siempre invisible y servirá para mostrar los objetos que compartan valor de referencia. Abrimos el shader y lo modificamos de la siguiente forma: En properties añadimos el valor de Stencil como con el anterior y eliminamos cualquier otra propiedad (normalmente textura) ya que este shader queremos que se muestre totalmente invisible. Añadimos el Stencil y le decimos que esté siempre comparando y si en algún momento el valor de referencia es el mismo, lo reemplace. Ahora le decimos al buffer de profundidad que no se escriba (por ser un objeto que será invisible) y cambiamos el modo de Blend. Podemos obtener más y mejor información de esto aquí: https://docs.unity3d.com/Manual/SL-Blend.html También eliminamos todos los añadidos de Fogs por defecto de Unity y aquellas referencias a texturas que no nos interesan. Por último hacemos que la función frag devuelva siempre 0, ya que como hemos comentado esto se muestra siempre como invisible. Con esto tenemos todo listo para pasar al montaje de la carta. PD: Asegurate también de que lo tienes en la misma ruta que el anterior. Esto no es necesario, pero te facilitará encontrarlo más adelante. En mi caso al igual que antes, esta en la ruta MyShaders. Montaje de la carta Para empezar vamos a cambiar por fin el blanco de nuestra escena, para ello vamos a irnos a Materials/Hornet y seleccionando todo vamos a elegir nuestro Shader (en este caso el Standard_StencilRead) Ahora tendremos que arrastrar las texturas requeridas (Main Texture y Emission Texture) si procede y establecer el MainColor en blanco (tened cuidado que el alfa no este a 0) y el EmissionColor en negro. En el caso que no tengamos texturas (como en el caso del personaje Hornet) simplemente cambiale el MainColor a tu gusto. Puedes hacerlo similar al original o ponerle tu propia versión. Así quedaría el del grass_material por ejemplo: O el dress_material, que no tendría textura: Sigue estas pautas en los demás materiales. El stencil value lo cambiaremos más adelante, de momento necesitamos ver en pantalla todo y no solo cuando este a través de nuestro “marco”.. Una vez terminado debería de quedarte algo similar a esto: Ahora vamos a crear un nuevo objeto en la escena llamado Card y lo ponemos en la posición 0,0,0. Ahora buscamos el Sprite “cover” dentro de Sprites y lo arrastramos dentro de Card. Le damos el tamaño a nuestro gusto. Este será el envoltorio de la carta. Ahora vamos a crear un Quad dentro de Card. Le ponemos de nombre StencilMask y lo colocamos en la posición 0,0,0 también. Este será nuestro marco a través del que se verá nuestra Hornet. Para poder ajustarlo vamos a tener que configurar ya el valor de referencia del stencil así como crear un nuevo material StencilWrite para nuestro quad recién creado. Vamos a empezar por esto último, crearemos un nuevo material con el shader StencilWrite. Lo colocamos dentro de Materials para tenerlo ordenado. A este material le vamos a poner en el valor de Stencil el valor 2 por ejemplo. Es simplemente un valor referencia, mientras tanto el receptor como el emisor tengan el mismo, funcionará. Una vez configurado vamos a arrastrarlo al StencilMask (o cambiamos el material dentro de MeshRenderer) para colocarselo. Veréis que se ha vuelto invisible, eso es que funciona como debería. Por último vamos a irnos a los materiales StencilRead que configuramos anteriormente y vamos a ponerles el mismo valor de referencia al Stencil. Seleccionamos todos o uno a uno y en Stencil Value le colocamos 2. Ahora debería de volverse todo invisible en la escena quedando solo la carta en negro. Vamos a desactivar de momento la carta llamada “cover” (o el nombre que tu le hayas puesto) de la ventana de Hierarchy. No se ve nada pero no es un error. Ahora mismo todos los shaders tienen el mismo Render Queue por lo que nuestro efecto no está funcionando. Más información de esto aquí: https://docs.unity3d.com/Manual/SL-SubShaderTags.html Sabiendo esto solamente tendremos que asegurarnos que nuestro StencilWrite se renderice antes. Vamos a nuestro material y le restamos 1 al RenderQueue. Con esto ya deberiamos tener visible nuestro modelo únicamente cuando estemos viendolo a través de nuestro quad. Ahora volvemos a activar el cover para ajustar la carta y el hueco como queramos. Al activarlo verás que tapa la visión a través del quad. No te preocupes, simplemente ve a los ajustes del SpriteRenderer del cover y cambia el MaskInteraction a Visible Outside Mask. Ahora ajustamos el Quad hasta tener el tamaño que deseemos. Una vez confirmado podemos probar a girar en la escena alrededor de la carta para comprobar el efecto. Para organizar mejor la escena vamos a colocar el objeto Hornet dentro de Card y vamos a crear un prefab para tenerlo guardado. Gracias a los Nested Prefab ya podemos hacer prefabs dentro de prefabs, asique nos viene genial. Ahora solo nos falta añadirle algo de texto. Vamos a usar TextMeshPro para esto. Pulsamos botón derecho y creamos un nuevo texto en 3D. Vamos a empezar por el nombre de la carta, por lo que le ponemos de nombre al text “Name” por ejemplo. Vamos a escribir el texto del nombre en el apartado Text y vamos mover y escalar el objeto colocándolo donde más nos guste. En mi caso he decidido ponerlo arriba. Vereis que no se ve cuando lo colocamos en la zona de la carta. Eso es por el orden de renderizado que tienen. Vamos a abrir los ajustes extra del texto (extra settings) y vamos a subirle el orden in layer a 1. Con esto conseguimos verlo, pero existe un problema, que el texto aparece también por detrás. Esto lo solucionaremos más adelante ya que tendremos que añadir un script simple para que active el culling. Llegados a este punto me he dado cuenta de que la carta está colocada del revés y el nombre por la parte trasera se ve invertido. En nuestro caso podemos solucionarlo rápido ya por delante la carta no se ve afectada. Simplemente nos vamos al objeto “cover” y marcamos Flip X. De esta forma la parte de atrás estará perfecta. En el caso de que tuvieras una imagen diferente deberías tener cuidado ya que la carta es la misma tanto en la partal como en la dorsal. Todo se dará la vuelta. Si quieres tener un control más exacto, deberás tener una carta delantera y otra trasera, cada una con su ajustes (y quizás optimizada para no pintar dos cada cara). Vamos a guardar el avance, aplicamos el prefab y guardamos escena. Deberíamos tener algo similar en estos momentos: Vamos a crear ahora otro texto para colocarlo en la parte de debajo. Duplicamos el objeto Name con Control+D y cambiamos el nombre a Description. Movemos el objeto a nuestro gusto, en mi caso lo coloque en la parte de abajo, centrado. Puedes tocar los ajustes del TextMesh que son maravillosos, sobre todo si has trabajado con el deprecado Text. Si queremos podemos cambiar la fuente. Para ello simplemente tendrás que descargarla de internet (o obtenerla de otra forma) y meterla dentro de Unity. Una vez dentro no es simplemente arrastrarla. Para poder usarla en TextMesh necesitarás crear un atlas de la fuente. Pero es fácil de hacer, simplemente abre la ventana Font Asset Creator desde WIndows/TextMeshPro. Selecciona la fuente y pulsa Generate Font Atlas (si quieres cambiar algún otro ajuste puedes hacerlo, pero ten cuidado. Más información sobre esto aquí: http://digitalnativestudios.com/textmeshpro/docs/font/ ) Una vez generada simplemente guárdala donde quieras y luego colócala en el texto dentro de Main Settings: Una vez tengamos la descripción vamos a guardar el prefab y a colocar los Post Procesos. Para ello Vamos a ir a la cámara y vamos a asegurarnos que tiene añadido un Post Process Layer. Esto es imprescindible para poder continuar. También vamos a activar a antialiasing FXAA y vamos a crear un nuevo layer PostProcessing para posteriormente usarlo en el Volume. Ahora vamos a crear un nuevo objeto en la escena. Le vamos a añadir el componente Post Process Volume. Vamos a marcar IsGlobal porque solo tendremos este para toda la escena y vamos a seleccionar un profile. En nuestro caso no tenemos ninguno creado, asique le daremos a New. Ahora simplemente asegurate de que este objeto está en el Layer PostProcessing De otra forma no funcionará y no podremos ver ningún cambio. Una vez configurado podremos ir añadiendo efectos ya creados por Unity o crear los nuestros propios. En este caso vamos a usar dos creados, el Bloom y el Color Grading. Pulsamos en Add Effect y seleccionamos uno y después el otro. Aquí puedes sacar tu lado artístico y elegir la configuración que más te guste. En mi caso después de una serie de pruebas quedó así: En este punto deberías tener algo similar a esto. Si no es así asegúrate de que el material del lazo tiene un emission color bien configurado. Por último nos queda solucionar el error del texto por ambas caras. Para eso simplemente vamos a crear un script con el nombre CullingTextMeshPro o el que querais y vamos a dejar solo la función Awake con el siguiente código: De esta forma al darle al Play el texto automáticamente hará culling y no se renderiza por detrás. Estuve informándome sobre otras formas de hacer esto, pero las respuesta de Unity fueron que esta era la forma. Pero si conocéis otra forma contactad conmigo y lo actualizo. Espero que os haya gustado y hayáis aprendido cosas nuevas que al final es el objetivo esto. Cualquier duda contacta conmigo via twitter: https://twitter.com/_davidlopez29 o por aquí Hasta pronto!
  4. 6 points
    Hola soy James Roman, tengo ya varios años trabajando con Unity, y actualmente trabajo en una compañía como desarrollador de experiencias en Realidad Virtual. Y tengo ya bastante tiempo trabajando en VRLAB. Puedes verlo desde aqui. ¿Que es VRLAB? Es básicamente una colección de componentes para interacciones en VR usando Oculus, me he enfocado bastante en las armas ya que creo que es una de las cosas mas divertidas de probar en la Realidad Virtual, he incluido diferentes tipos de armas, escopetas, armas automáticas, revolver, arco y flecha, espadas. También diferentes tipos de recarga para estas armas, puedes cambiar manualmente el cargador a cada arma cuando este se agote, recargar usando diferentes tipos de gestos como en dead and buried, puedes recargar el revolver haciendo un giro rápido con la mano. - Armas - Como ya he mencionado he trabajado bastante el tema de las armas con un completo sistema de armas, varias armas ya incluidas (Escopetas, revolver, Automáticas), puedes tomar las armas existentes como base para crear las tuyas, o crear nuevas armas desde 0. - Completo Sistema de Interacción - También posee un completo sistema de interacción, muy extensible, puedes tomar objetos, interactuar con objetos, mover palancas, botones etc, crear animaciones de interacción diferentes para cada objeto, y diferentes comportamientos incluso para cada mano. - Arco y Flecha - Posee un arco realista con el cual puedes lanzar flechas, puedes tomar una flecha de tu espalda o simplemente tomar una que ya hayas lanzado, estas se pegan a los demás objetos de una manera bastante realista. - Diferentes Modos de Recarga - Posee diferentes formas para poder recargar las armas, puedes cambiar el cargador una vez que este se haya acabado, o simplemente realizar gestos con la mano como en dead and buried para recargar tus armas o simplemente tener munición infinita. - Sistema de Combate Cuerpo - En VRLAB puedes tomar un par de espadas y luchar contra los enemigos, los cuales responderán correctamente a las físicas, ademas de eso puedes golpear a los enemigos con tus armas, como con el arco o una escopeta si no tienes munición. - Botones y Palancas - Botones y palancas que responden correctamente a las físicas, desde las distancia puedes activar una palanca con un disparo o simplemente lanzando un objeto. - AI - Aunque el fuerte de este asset no esta en la AI, he añadido unos ejemplos bastantes interesantes y extensibles para trabajar con estos mismos. - Character Controller y Teleport - Tienes diferentes formas de moverte en VRLAB, la mas común quizás moviéndote alrededor con el joystick o usando un sistema de teleport muy parecido al de roborecall. Todo esto en prefabs bien organizados listos para tomar y soltar en la escena, con montones de posibilidades de modificación mediante el inspector, de igual manera me he esforzado para crear un código legible y placentero a la vista, así que si quieres simplemente entrar y mirar como esta hecho todo, y aplicar tus propias modificaciones mediante código, no debería ser muy difícil para alguien que tenga ya su experiencia con Unity. - Futuras Actualizaciones - - Añadir nuevas armas, entre ellas un lanzacohetes. - Sistema de inventario, para que puedas cargar varios objetos a la vez. - También cabe destacar que me gusta roborecall, y quizás añada algunas de sus funciones, entre ellas la posibilidad de tomar balas en el aire y devolverlas a los enemigos. - Luego simplemente escucharlos a ustedes y seguir mejorando. Dejo nuevamente el link al assetstore aqui, si lo pruebas no dudes en dejar un review para seguir mejorando, y si quieres contactar conmigo directamente puedes escribirme a james@unity3dninja.com finalmente los dejo con algunos vídeos cortos mostrando distintas funcionalidades.
  5. 6 points
    Hola a todos, mi nombre es David y este es el primero de una serie de tutoriales sobre Unity3D. Esta iniciativa surge del programa Unity Student Ambassador y están creados por mi inicialmente para workshops presenciales. Los he adaptado a este formato pero si tienes cualquier duda no dudes en preguntarme. Espero que os guste. Introducción ¿Que es Shader Graph? La creación de shaders en Unity ha sido tradicionalmente el terreno de juego de personas con habilidades para programar. Shader Graph abre el campo para artistas y otros miembros del equipo para que la creación de shaders sea mucho más sencilla. Solo conecta nodos en una red gráfica y podrás ver los cambios al instante. Requisitos El Shader Graph está disponible desde Unity 2018.1. Está diseñado para funcionar con otra característica de Unity 2018.1: Scriptable Render Pipeline (SRP). Por lo tanto, no puede usarlo con el Built-In Unity Renderer. Tiene por tanto soporte tanto para LWRP como para HDRP (o para su propio SRP). Para este tutorial usaré la versión 2019.2.9f1. ¡Comencemos! Lo primero que necesitamos es abrir Unity y crear un nuevo proyecto. Asegúrese de que elige usar el nuevo SRP. En nuestro caso elegiremos el LWRP. Confirmamos y esperamos que Unity lo prepare todo. Una vez dentro de Unity ya podemos ponernos a trabajar. Por defecto debería tener incluido el paquete Shader Graph. Puedes comprobar ese y otros paquetes instalados en Windows/Package Manager. Nuestro primer Shader En la ventana Project, pulsamos el botón y elegimos Create/Shader/PBR Graph. Si queréis conocer más acerca del PBR está es una buena guía: https://blog.teamtreehouse.com/beginners-guide-physically-based-rendering-unity Nombramos el archivo con el nombre que queráis. En este caso le llamaremos Standard_Color. Ya tendríamos nuestro primer Shader creado, vamos abrirlo. Lo seleccionamos y en la ventana Inspector pulsamos Open Shader Editor. Si todo ha ido bien, deberíamos ver esto: Dentro del Shader Editor podemos ver tres sectores claramente diferenciados: PBR Master Node: Es el nodo principal, al que acaban llegando todos los demás. Es el encargado de mostrar las características en el material. BlackBoard: Puedes activarlo y desactivarlo arriba a la derecha. Es donde creas y guardas las propiedades que necesitas usar. Encontrarás Colores, Vectores, Texturas etc… Estas pueden aparecer en el inspector del material para ser usadas más adelante. Preview: Es la previsualización actual de la entrada del PBR Master Node. Puedes cambiar el tipo de renderización pulsando el botón derecho. (Cubo, quad,sphere…) Una vez conocemos las partes vamos a añadirle funcionalidad a nuestro nuevo Shader. Comencemos añadiendo color. Vamos a abrir el Blackboard y vamos a pulsar en el +. Con esto podremos crear una variable de entre las que Shader Graph nos ofrece. En este caso elegiremos Color. Ahora podremos cambiarle el nombre, pero en nuestro caso lo dejaremos tal y como está, con el nombre Color, que al fin y al cabo es lo que será para nosotros. El toggle de Exposed indica si quieres que esa variable aparezca posteriormente en el material para ser editada de forma rápida. En nuestro caso así lo queremos así que la dejamos marcada. En Default puedes elegir el color que desees por defecto, como he dicho podrás cambiarlo después en el material pero si quieres ver como queda en el Shader Editor tendrás que cambiarlo aquí. Por último el Mode te permite establecer el color como HDR. Puedes hacer efectos realmente atractivos con esto pero de momento lo dejaremos como está. Una vez creado nuestro Color vamos a arrastrarlo hacia el Grid donde esta el PBR Master y lo soltamos. Como vemos este nodo Color solo tiene una salida, conectamos la salida con la entrada de Albedo. Si habías cambiado el color default verás que la Preview ahora aparece de otro color. Sino puedes ir ahora y cambiarlo. Una vez hecho esto pulsamos arriba a la izquierda en Save Asset y podemos cerrar el editor. Ahora solo nos falta ver nuestro shader en pantalla. Para esto añadimos una esfera a la escena y creamos un nuevo material. Le pondremos de nombre Standard_Color_MAT, por ejemplo. Una vez creado el material, lo seleccionamos y en el desplegable del Shader elegimos ShaderGraph/Standard_Color o como llamases a tu Shader. Arrastramos nuestro nuevo material y lo soltamos encima de la esfera y … Ahora podemos cambiar cambiar desde el Material el Color, ya que anteriormente lo activamos. Nodos importantes Antes de continuar el tutorial voy a explicar algunos de los nodos más usados ya que los vamos a usar más adelante. Me dejo muchos pero para esta introducción son suficientes: Math Basic: Son las operaciones matemáticas más comunes. Suma, División, Multiplicación, Resta … UV: Son nodos que actúan sobre las coordenadas de uv. Podemos rotarlas, moverlas y darle algunos efectos como el Twirl o Spherize. Veremos un ejemplo más adelante. Shapes: Son texturas generadas proceduralmente dentro del editor. Podemos crear círculos, rectángulos, polígonos etc… One Minus: es simplemente la operación 1 - x. Es muy útil como veremos más tarde, tanto que tiene su propio nodo. Noise: es un nodo generador de ruido. Veremos también su uso más adelante. Step: es un nodo que dado un valor entre 0 y 1, compara la entrada con ese valor y devuelve 0 si es menor y 1 si es mayor. Por ejemplo: si nuestro valor es 0.4, todos los valores por encima que entren en el nodo, serán convertidos a 1 y todos los inferiores serán 0. Dot: es un nodo que calcula el Producto Escalar entre vectores. Devuelve 1 si apuntan exactamente en la misma dirección, -1 si apuntan en direcciones completamente opuestas y 0 si los vectores son perpendiculares. Lerp: es un nodo que devuelve el resultado de la interpolación lineal entre las dos entradas en función de la entrada T. El valor de la entrada T está sujeto al rango de 0 a 1. Por ejemplo, cuando el valor de la entrada T es 0, el valor de retorno es igual al valor de la entrada A , cuando es 1, el valor de retorno es igual al valor de la entrada B y cuando es 0.5, el valor de retorno es el punto medio de la dos entradas A y B . Dissolve Shader Una vez conocemos los nodos más importantes, vamos a hacer un Shader algo más complejo que el anterior. Vamos a crear un efecto que disuelva el objeto haciendo que desaparezca y aparezca a nuestro gusto: Para esto volvemos a crear un nuevo Shader y le ponemos de nombre Dissolve. Lo abrimos y seleccionando el PBR Master pulsamos en el icono del engranaje. Aquí vamos a encontrar algunos ajustes interesantes como si el objeto es Opaco o Transparente. En este caso lo dejaremos como está (Opaque) y lo único que marcaremos será el Two Sided. Esto hará que el objeto pinte también sus caras internas, lo que conlleva eso sí, un coste extra. Tenlo en cuenta en el futuro, en este caso para el Cubo en cuestión, nos interesa que las caras internas también se vean cuando está disolviendo. Una vez marcado, vamos a crear algunas variables que usaremos. En primer lugar necesitaremos un valor comprendido entre 0 y 1 que se encargue de llevar el progreso disuelto. Será 0 cuando el objeto se vea por completo y 1 cuando esté completamente disuelto. Para eso en el BlackBoard crearemos un Vector1(que no es más que un simple número) y lo nombraremos como Dissolve Value por ejemplo. Para facilitarnos el trabajo, podemos cambiar el tipo de número con Mode. En nuestro caso está comprendido entre 0 y 1 por lo que elegiremos Slider y rellenaremos el min y el max con esos valores. A su vez, necesitaremos también un Color para el objeto, como en nuestro anterior Shader y un Color diferente para la parte que se esté disolviendo. Creamos ambas variables, estableciendo el Color para disolver cómo HDR si quieres que brille como el del gif (necesitarás también tener el paquete de post procesos y activar el Bloom). Por último necesitaremos un valor que indique el grosor que tendrá el dissolve. Podemos revisar el Gif para ver el grosor que tiene la parte que se está disolviendo. Creadas todas las variables en mi caso quedó así: Para el efecto de disolver necesitamos en primer lugar una textura que genere ruido donde las zonas negras indiquen lo que llevamos disuelto y las zonas blancas lo que nos queda por disolver. Por suerte, como vimos antes, tenemos un nodo de ruido perfecto para este uso: Simple Noise, asique lo añadimos. Podemos cambiar el valor de Scale del nodo a nuestro gusto. Cuanto menor sea el valor más “zoom” hará el ruido. También vamos a necesitar el nodo Step que si tenías dudas de su uso, en este caso lo vas a entender perfectamente. Ahora unimos la salida de Simple Noise a la entrada Edge del Step. Ahora podemos cambiar el valor del Step entre 0 y 1 para ver su utilidad real. Los valores de ruido que estén por debajo de ese valor devolverán 0 y los que estén por encima devolverán 1. Es decir cuando el Step sea 0 el objeto no se verá y cuando sea 1 se verá completamente. Justo lo que queremos que ocurra. Simplemente conectamos nuestra variable DissolveValue a la entrada In del Step. Para hacer pruebas vamos a colocar la salida del Step en el Albedo del PBR Master. Vamos a guardar y vamos a Añadir un cubo a nuestra escena. Crearemos un material con nuestro shader y se lo colocaremos al cubo. En nuestro material podremos cambiar el valor del DissolveValue. Como vemos el efecto se acerca a lo que buscamos, aunque tenemos dos problemas. Primero no se está disolviendo realmente ya que está pasando de negro a blanco simplemente. Y segundo que el efecto está al contrario, cuando el DissolveValue vale 0 debería verse el objeto completo y cuando está a 1 indica que el objeto está completamente disuelto. Vamos a volver a abrir el Shader Editor para solucionar ambas cosas. Primero vamos a hacer que la parte negra se convierta en transparente. Para ello simplemente tienes que conectar la salida del Step con el Alpha del PBR Master. También tendrás que activar el AlphaClip. Aunque el valor que entra por defecto es 1 tendrás que ponerle tu el valor a través de un nodo. Simplemente crea un nodo Integer (que es un número sin decimal) y conectalo a AlphaClip. Para el segundo problema simplemente usaremos el nodo que comentamos anteriormente. OneMinus. Si a 1 le restamos el DissolveValue obtendremos la parte contraria, que es justo lo que necesitamos. Si guardamos y probamos comprobamos nuestro material ahora podemos ver que funciona como queriamos. Se disuelve de blanco a negro con el ruido que creamos. Solo nos falta añadirle color. Para ello volvemos al editor. Necesitamos pintar el borde que se disuelve y a raíz de ahí lo que tengamos a un lado del borde lo borramos y lo demás lo pintamos del color normal. Una forma de encontrar el borde es sumar el DissolveValue y el borde y restar por un lado el Step de la suma y por otro el Step del DissolveValue solo. Es más fácil de entender con una imagen (para que sea más visual he cambiado el valor default del Dissolve Value a 0.5): Como vemos ahora tenemos el borde diferenciado, pero no lo estamos usando. Lo que vamos a hacer es pintar con los colores que creamos al principio. Una buena forma de hacerlo es usar Lerp. Podemos hacer que si la resta es 1(blanco) se coloree con el Color del Borde y si es 0(negro) el color sea el normal. Y esa salida del Lerp la conectamos a Albedo. Ahora podemos guardar y probar el shader. Si todo ha ido bien debería funcionar como esperábamos. Puedes cambiar a tu gusto los valores del material, como los colores o el borde. Si eres perfeccionista te darás cuenta de que si el borde es muy grande, pueden quedar algunos restos al disolverse. Esto podemos arreglarlo con un simple cambio. Sumando el valor del borde al dissolve antes de hacer el OneMinus. También podrías crear una variable para el Scale del Simple Noise. Así tendrías un valor más que podrías modificar desde fuera sin tener que cambiar el shader. Por último vamos a añadir una textura que se añada al color, así lo podremos usar en más objetos. Simplemente crea una variable de tipo Texture2D y arrastrala al grid con los demás nodos. Tendrás que sacar un nodo llamado Sample Texture 2D y arrastrar la textura a la entrada correspondiente. Luego solo queda multiplicar por el color normal y sustituirlo en la entrada A del Lerp anterior. Guardamos y desde el inspector del material añadimos la textura que queramos y habríamos terminado. No es la única forma de hacer este efecto, hay muchas otras, esta es la forma que yo usé. Espero que os sea útil. Cualquier duda que tengáis hacérmela saber y estaré encantado de ayudaros. Podéis encontrarme también por twitter: https://twitter.com/davidlopezdev Nos vemos en el siguiente.
  6. 5 points
    En la anterior entrada hablé sobre trigonometría, repasando las razones trigonométricas y viendo el teorema de pitágoras. Si no lo recuerdas o has llegado nuevo aquí, míralo antes de continuar (enlace debajo). Trigonometría Vectores Matrices Funciones Introducción Si estás familiarizado con motores de videojuegos como Unity, conocerás el concepto de vector ya que se usa habitualmente. Pero ¿qué es realmente un Vector? Un vector básicamente es una flecha que apunta en una dirección y que tiene una longitud concreta: Esto sería un ejemplo de un vector y cualquier flecha apuntando en cualquier dirección sería otro ejemplo. Pero ¿cómo representamos esto? Para poder hacerlo tenemos que llevarnos nuestro vector a un sistema de coordenadas (x e y) y establecer el origen del vector en el centro del sistema. Por si no recuerdas que era un sistema de coordenadas, es una forma de visualizar un punto en el espacio. En este caso el espacio es 2D por lo que se representa con dos líneas, una horizontal (representado por el valor X) y otra vertical (representado por el valor Y) que se cruzan en un punto, llamado centro: Así quedaría nuestro vector anterior dentro de un espacio de coordenadas. Esto, por ejemplo, podría representar el movimiento de una nave en su proceso de despegue. Comienza en la posición (0,0) y sigue en la dirección del vector hasta llegar a su objetivo. Teniendo en cuenta que X es el valor horizontal e Y el valor vertical, el vector sería (2,1) Pero ¿qué podemos hacer con esto? Como has visto puedes representar movimientos con ellos, por ejemplo. Pero para ver de forma práctica su uso vamos a usar Unity3D. Cualquier versión te servirá para este propósito puesto que solo vamos a tocar código básico. En mi caso usaré la versión 2020.1. Si usas otro motor la teoría sigue siendo válida pero tendrás que buscar la forma de adaptarlo por tu cuenta. Unity internamente usa vectores para colocar un objeto dentro de la escena (realmente esto es incorrecto ya que usa una matriz, pero no nos adelantemos). Si vas al componente Transform (crea un gameobject nuevo si no tienes ninguno) te encontrarás con este Vector3 (un estructura propia de Unity) que contiene 3 valores: Estos son la posición en X,Y,Z. Pero ¿pero qué son estos valores? Pues al igual que la gráfica anterior nos indican que desde el centro del mundo hasta la posición de este objeto el vector es (0,0,0). Vamos a ver qué podemos hacer con esto. Para ello creamos un objeto de nombre Player y otro de nombre Target. Los colocamos en diferente posición y le asignamos diferentes iconos para poder diferenciarlos: Recuerda que puedes cambiar el icono en la siguiente pestaña: Una vez hecho esto vamos a crear un nuevo script de nombre Player y lo vamos a añadir al objecto Player. En este script vamos a añadir una variable Transform pública de nombre target y vamos arrastrar nuestro Target a través del inspector. Con esto tendremos acceso al vector de posición del Target desde nuestro Player. Ya tenemos acceso a los dos vectores de posición, el del personaje y el del objetivo. Sabiendo esto ¿cómo hacemos que el personaje se mueva hacia el objetivo usando vectores? Pues aquí llega la parte interesante ya que si restas el vector de posición del objetivo con el vector de posición del personaje, el resultado es el vector necesario para llevar el player al objetivo. Veámoslo gráficamente creando la siguiente función: Si pulsamos play al añadir este código, veremos cómo el personaje se mueve hasta la posición del objetivo. Vale parece que se mueve, pero quiero más. ¿Que tal si medimos la distancia que hay entre uno y otro antes de moverlo? Para esto vamos a recordar la trigonometría que aprendimos en la parte anterior. Magnitud La magnitud de un vector es la distancia que hay entre dos puntos. En nuestro caso sería la posición del personaje y nuestro objetivo. Para calcularla solo tenemos que aplicar la fórmula de la distancia. Esta fórmula es simplemente el teorema de pitágoras disfrazado, y lo vamos a ver en la siguiente imagen: Como puedes ver, nosotros lo que queremos calcular es la distancia (h) por lo que podemos convertirlo en un triángulo añadiendo X e Y. Ahora solo tenemos que usar pitágoras para despejar h. ¿Lo recuerdas? Vamos a resolverlo en código. Para ello vamos a crear una clase estática nueva llamada BasicMath donde vamos a ir añadiendo nuestras funciones matemáticas a partir de ahora. Seguiremos usando Mathf (Unity) o Math (System) para realizar las operaciones básicas que se salen del objetivo de este tutorial. Mencionar que todos los cálculos e igualdades que haremos aquí serán basados en 2 dimensiones. Una vez se han entendido correctamente los cálculos, solo hay añadir la componente z. Esta sería nuestra implementación del teorema de pitágoras. Para ver la distancia simplemente podemos añadir un log en nuestra función MoveToTarget: Si estás familiarizado con Unity ya sabrás que por defecto nos soluciona todos los problemas de vectores con su estructura Vector. Podemos acceder directamente a la magnitud de un vector desde dentro del mismo de la siguiente forma: Como puedes ver, ambos resultados son iguales, aunque nuestra implementación es menos óptima que la que usa internamente Unity. Por lo que esta clase BasicMath y todo lo que contenga es únicamente para uso educativo. La magnitud tiene un pequeño problema y es que hacer una raiz cuadrada es algo costoso a nivel computacional. Por eso habitualmente se usa el valor antes de pasar por la raiz cuadrada. Seguirás teniendo un valor que representa la distancia pero será más eficiente. Podemos crear esta implementación de la siguiente forma y equivale al SqrMagnitud de la clase Vector: Esto es genial, tenemos al personaje moviéndose al target y conocemos su distancia hasta él. Pero no queremos que el player avance directamente hacia el objetivo, sino que lo haga poco a poco a la velocidad que nosotros queramos. Para esto vamos a necesitar normalizar nuestro vector. Normalización Normalizar un vector es cambiar su longitud a 1, manteniendo su dirección. En nuestro caso de ejemplo, el vector “dir” que tenemos. Al cambiar su longitud a 1 podemos controlar la velocidad de movimiento mediante un valor multiplicador. ¿Cómo calculamos el vector normalizado (no confundir con el Vector normal)? Dividiendo el vector por su magnitud: Podemos implementar rápidamente esto en nuestra clase BasicMath: Podemos ver que equivale al valor normalized de la clase Vector: Una vez tenemos el valor normalizado, podemos multiplicarlo por un valor y hacer que el personaje se mueva en función del tiempo: Vamos a tener que pasar nuestra normalización a Vector3 ya que estamos trabajando en dos dimensiones y la posición añade la Z (aunque como este caso sea 0). Si modificamos el valor speed podremos hacer que el personaje cambie su velocidad al moverse a través del vector. Antes de continuar me gustaría darte otra forma de mover un vector de un punto a otro. Pero en lugar de basado en la velocidad, basado en un valor comprendido entre 0 y 1. Cuando el personaje está en su posición inicial, el valor es 0 y cuando llega a su objetivo es 1. Esto es llamado interpolación (Lerp). Interpolación Para interpolar un vector simplemente vamos a sumarle al vector inicial, el vector de dirección al objetivo por un valor t (comprendido en 0 y 1). Veámoslo en código: La primera línea limita la t entre 0 y 1. La segunda simplemente suma al vector de origen, el vector dirección multiplicado por t. Si la t es cero devolverá el valor “a” y si es 1 devolverá el valor “b”. Con el siguiente código podremos probar esta funcionalidad nueva: Tenemos que crear un valor t (el atributo Range nos ayudará a limitarlo entre 0 y 1) y un Vector3 que guarde la posición inicial. Esto es necesario porque si le pasamos la posición actual al Lerp los resultados se irán actualizando al ir moviéndose y el resultado no será el que buscamos. Comentamos la anterior MoveToTarget y añadimos la nueva en la función Update. De esta forma si pulsamos Play tendremos un valor t en el inspector que si vamos moviendo entre 0 y 1 hará que nuestro player se desplace más o menos cerca del target. Hay otros tipos de interpolación que veremos en el apartado de Funciones en próximas partes de este tutorial. Una vez tenemos esto, vamos a pasar con una de las operaciones con vectores más importante. Producto Escalar El producto escalar (dot) es una operación entre dos vectores que nos devuelve un valor. Este valor nos da información muy útil sobre estos dos vectores: Si este valor es cero: el ángulo entre los dos vectores es 90 grados por lo que son totalmente perpendiculares. Si este valor es negativo: el ángulo es mayor a 90 grados. Cuanto menor sea este valor, mayor será el ángulo. Si este valor es positivo: el ángulo es menor que 90 grados. Cuanto mayor sea este valor menor será el ángulo. Aquí puedes experimentar visualmente con estos conceptos: https://www.fisicalab.com/apartado/producto-escalar La fórmula del producto escalar, siendo “a” y “b” dos vectores, es la siguiente: dot = ax * bx + ay * by Ya conocido el concepto vamos a practicar con él. Primero lo añadimos la función a nuestro BasicMath. Ahora añadimos la función Dot de testeo con lo siguiente: Esto calculará el producto escalar entre el vector del personaje y el vector de dirección. Como ves hemos utilizado el transform.up en lugar de la posición. Este valor indica la dirección del vector hacia arriba teniendo como referencia el tranform. Ya conocerás estos vectores si estás habituado a trabajar con Unity. Podemos verlos mejor aquí: Si usamos estos vectores a la hora de calcular el producto escalar, los resultados serán en función a la dirección y no en función de la posición. El vector de posición no nos indica hacia donde está apuntando, sino su posición con respecto al centro del mundo. Una posición por ejemplo de (3,4,0) no nos es útil para calcular el producto escalar, sin embargo el vector.up (0,1,0) sí, ya que es una dirección en este caso hacia arriba. También hemos normalizado los dos vectores antes del dot para que sea más fácil trabajar con el resultado. Activamos esta función en Update, comentando lo demás (puedes dejar el MoveToTarget si quieres). Si damos Play podemos ir moviendo el target y ver como va cambiando el producto escalar. Pero ¿de qué sirve conocer este valor?. Pues anteriormente vimos que este valor nos da información muy relacionada con los ángulos. De hecho podemos calcular el ángulo entre dos vectores conociendo los productos escalares. Ángulo Para calcular el ángulo tenemos la siguiente fórmula,siendo “a” y “b” vectores: θ = arcocoseno (dot(a, b)) Vamos a añadir esto a nuestro BasicMath. Este resultado estará en radianes por lo que crearemos dos funciones, una en radianes y otra que convierta el resultado a grados. Hemos normalizado ambos vectores antes de hacer el Dot. De esta forma lo hará desde dentro y podremos pasarle el vector sin normalizar. El valor Rad2Deg es el factor de conversión de radianes a grados que es 180 . Esto es un valor constante: No es necesario que añadas tanta precisión, puedes coger los decimales que quieras para este fin. Creamos ahora nuestra función Angle en el Player (puedes sustituir la función Dot ya que no la volveremos a usar). Volvemos a usar el Vector.up y añadimos la función al Update para verla. Para visualizar mejor el ángulo, voy a añadir en el OnDrawGizmos el siguiente código. Esto crea dos líneas que simular el comportamiento de los vectores. Si damos al play podremos ver dos líneas que forman un triangulo, el angulo entre las dos es el que nos está mostrando por consola: Con este valor de ángulos podrías, por ejemplo, rotar al personaje para que siempre mire al target con la función transform.Rotate. Con esto llegamos al final de esta entrada sobre vectores. Ha sido algo básico pero que sirve como punto de partida si quieres profundizar por ti mismo. Como he comentado estos cálculos son teniendo en cuenta solo 2 dimensiones. Te animo a que realices los cálculos añadiendo a las fórmulas una dimensión más. Podéis encontrar el código del proyecto aquí Recuerdo que no soy matemático y que los cálculos que aquí he realizado pueden contener errores o no ser del todo precisos. Cualquier duda o anotación siéntete libre de contactar conmigo. Nos vemos en la siguiente entrada.
  7. 5 points
    Hola chicos, comparto con vosotros una implementación de ruido perlin noise con fBm para todos aquellos que esteis interesados. Si necesitais generación procedural de contenido, con esto solamente necesitais llamar a una función. Además las plantillas de ruido se guardan como Scriptable Object. Os dejo imagenes de las demos que incluye con ejemplos de uso, dependiendo del caso: link: https://github.com/davilopez10/PerlinNoise_Unity3D Perlin Noise 1D Perlin Noise 2D Perlin Noise 3D
  8. 5 points
    Hola, He creado unos pocos vídeos de programación básica de NPC's, o programación de NPC's básicos. La intención es ir creando mas de esta tématica, sin obligación, y de tanto en tanto, pero irlos agrupando en la misma lista de visualización de youtube: Aquí os la dejo: Por ahora hay tres vídeos, o 2.5 por que el último es un poco ampliación del primero. -Como crear NPC's en Unity que te siguen. -Creamos un centinela con Waypoints en Unity, -Como hacer un NC persiga y huya en modo pánico. Ya ire informando de nuevas incorporaciones a la lista 🙂
  9. 5 points
    GUÍA TUTORIAL PARA JUEGOS CON ENTORNO 3d PARA MÓVIL Buenas gente mi nombre es Javier García, el desarrollador del juego de Bramson Case, (esperemos que próximamente en las plataformas , que ya me queda pokito^^’). Debido un comentario que me hizo Pioj en uno de los hilos, me he animado a preparar un post para explicar algunas cosillas desde mi experiencia y punto de vista que he aprendido estos años con el proyecto que llevo entre manos. Lo primero vamos a comentar son algunas cosas a tener en cuenta antes de empezar nuestro proyecto, ya sea tanto para móvil, como para pc, aunque en este post luego lo enfocaremos a la preparación de juegos en 3d para las plataformas de móvil ya sea en primero o en tercera persona. CREACIÓN DE UN GRUPO TRABAJO. Tenéis que tener en cuenta que aunque parezca fácil, la típica frase de..“VOY A HACER UN VIDEOJUEGO Y ME VOY A FORRAR” eso lleva una carga de trabajo impresionante que nunca se suele tener en cuenta al empezar el proyecto. (lo digo por propia experiencia y ya veremos lo de me voy a forrar xD) -Ilustraciones -Texturizado -Modelado 3d -Guionistas -Programación -Betatesters -Música -Marquetin -Etc.etc.. (A mi manera de ver, a no ser que sea un proyecto pequeño que puedas cumplir en un par de meses como mucho, intenta montar un grupo de trabajo, ya que en un par de meses suele comenzar la cuesta arriba y empiezan a aparecer todos los problemas que no tuviste en cuenta cuando dijiste esa mítica frase, tanto personales como a nivel del juego). Ya se que puede parecer algo pesado esta intro de post, pero lo considero bastante importante. Y con esta pequeña presentación, vamos a ponernos con el tema.:D --------------------------------------------------------------------------------------------------------------- Para una explicación mas sencilla vamos a separarlo en dos bloques, como he comentado anteriormente esto esta enfocado para las plataformas de móviles (concreta-mente en entornos 3d, aunque algunos conceptos también se pueden aplicar en otras plataformas). -BLOQUE 1 (Modelado, Texturas, Iluminación, Consejos) -BLOQUE 2 (Menús Básicos) BLOQUE 1 (modelado, texturas, iluminación, consejos) COSAS A TENER EN CUENTA ANTES DE COMENZAR EL MODELADO. -No existe ninguna formula mágica para una optimización perfecta. Como indicamos no existe ninguna forma concreta de optimizar el juego para sacar el 100 del rendimiento, en plan... si pongo las texturas en modo móvil, y pocos polígonos en el modelado, me va a ir todo fluido.(desgraciadamente eso no funciona así ). Unity tiene múltiples maneras que puedan ayudar a una buena optimización en el compilado, pero esas opciones de menú (que explicaremos mas abajo) son ayudas muy generalizadas, una buena optimización implica un bueno modelado desde un principio, tanto de personajes, como escenarios, acorde a lo necesitemos en cada momento. Buen modelado + buen ajuste en los menús = todo va de puta madre :D Por poner un ejemplo la imagen puesto a continuación es el exterior de la mansión Bramson donde se desarrollara el juego que llevo entre manos. (No solo la mansión esta completamente amueblada, si no que dentro de esta misma escena hay otra mansión de 2 plantas, también totalmente amueblada y algunos eventos especiales que también están cargadas en la misma escena, por lo que si se plantean bien las cosas desde un principio se pueden conseguir los resultados deseados.) Olvidaos de detalles hiper realistas en los gráficos. Tenemos que tener en cuenta que vamos a realiza un juego para móvil y el procesamiento y los recursos de un móvil son muy limitados comparado con un pc de sobremesa, en este caso tendremos que tener en cuenta algunos conceptos básicos al modelar. 1-MODELADO Intentar siempre modelar en medida de lo posible en low-poly, dándole algún detalle mas a los objetos que puedan estar mas próximos a la cámara, por ejemplo. (Si en un decorado tenemos una montaña al fondo del escenario que nunca vamos a llegar en el juego, es una tontería detallarla con muchos polígonos y darle una textura a mucha resolución, ya que en un móvil no se va a apreciar ese tipo de cosas, pero si se apreciar en los objetos del escenario que estén mas próximo a la cámara) 2-DETALLE DE ESCENA Una de los trucos mas comunes es usar algo mas de detalles donde el jugador vaya a fijarse en el proceso del juego, este ejemplo es muy básico, si tenemos un folio con un punto negro en medio, el ojo humano por norma general suele enfocar la vista en el. (En la imagen puesta a continuación se aplica la misma teoría, el personaje tiene una textura muy básica y algo menos detallada que la cara, que literalmente la cara es una fotografía, por lo que al haber algo mas detallado en ese momento, te sueles fijar mas, otra cosa es que alguien se fije en algo mas concreto como algún detalle en la ropa.. pero eso no suele ser común, a no ser que estés también en el mundillo para percatarte de esas cosas, o que lleves 2 meses buscando la típica puta llave que te tiene atascado y ya miras hasta en debajo de las piedras). 3-COLLIDER Un tema delicado, esta sección para mi bastante importante y a tener muy en cuenta a la hora de preparar la escena en el Unity, como sabréis para los polígonos de los modelos en unity existen varias maneras de meterle los collider a los objetos, ya sea para crear alguna activación de un evento o para bloquear el paso del personaje y evitar de esta manera el clipeo. Intentar usar exclusivamente los collider mas básicos, a ser posible todo cubos o planos, olvidaros de los mesh collider (ya se que es automático y mola mucho), eso al principio parece que no consume mucho recurso pero conforme vaya creciendo el proyecto, la cosa se desmadra muy rápidamente, a continuación os pongo un pequeño ejemplo de una de las salas de la mansión. 4- EXPORTAR MODELOS A UNITY (OBJETOS PRE-FABRICADOS) Un de los errores mas comunes que suele haber a la hora de exportar, es exportar todo el conjunto creando un único prefabricado, teniendo en la escena objetos iguales como pueden ser libros, sillas, etc. Para poder explicar esto bien vamos a simplificarlo al máximo en un par de imágenes, ya que es algo mas complejo pero de esta manera se quedara la base mas clara. -En la imagen 1 hemos creado 4 sillas y las hemos exportado a Unity ya sea en FBX, OBJ o el formato que sea. Como podemos ver al pasarlo a Unity nos a creado 1 único prefabricado con las 4 sillas de 400 polígonos, ese calculo se queda guardado en memoria y si repite el prefabricado en algún otro sitio usara el dato en memoria. -En la imagen 2 como la silla que vamos a usar es igual que las otras, la exportamos independientemente y luego copiamos el prefabricado, hemos conseguido el mismo resultado y nos hemos ahorrado el calculo de 300 polígonos. (aunque parezcan pocos polígonos, recordar que es un juego para móvil, todo lo que podáis ahorrar en una parte, podréis meterlo en otra cosa, o pensar que si tenemos 50 sillas en todo un decorado no son 300 polígonos… 50x100 con 5000 polígonos, comparado con 100 la cosa ya cambia bastante mas ) 5-SHADER ,TEXTURIZADOS Bueno aquí si que hay para gustos colores, ya que hay muchísimas variedad para jugar en esta sección, simplemente me centrare en comentar mi opinión personal y ya cada uno que sopese las opciones, yo en mi caso he usado el shader standar, evitando en medida lo posible usar el shader para móvil, ya que si a malas tengo mucha perdida de fps siempre tendré la opción de pasar todas las texturas a los shader de móvil para ganar algo mas de optimización, para la resolución de las texturas he ido jugando 2048 para objetos mas detallados y cercanos, y 1024 para cosas mas de fondo. -Que tenemos que tener mas en cuenta de un shader estándar, para un juego 3d para móvil. De todas las opciones que podemos ver en la imagen vamos a centrarnos en las mas importantes de mi punto de vista ALBEDO (diffuse para algunos programas) -Este es el color base de la textura, ya sea JPG, BMP, Etc.. (Al ser un juego para móvil intentar que sean todas las texturas en jpg no mas grandes de 2048) METALLIC (Specular par algunos programas) -Esta textura es el brillo que puede tener un objeto al recibir un punto de luz. (Aquí tenéis que llevar mucho cuidado si se usa esta textura, tener en cuenta que no existe en la vida real un objeto que tenga brillo perfecto en toda su superficie, debido a la suciedad, el desgaste, o mil imperfecciones que pueda tener, por lo que el objeto necesitaría una textura para que quede bien y un punto de luz en “tiempo real” para que haga un buen efecto, por lo que es un gasto de procesamiento enorme que a veces no merece la pena meter) NORMAL MAP -Esta textura lo que crea es un capa nueva encima de la textura albedo que le da relieve, dándole un detalle al modelo de low-poly haciendo que parezca que tiene muchos mas polígonos teniendo la base de low-poly. (Aquí realmente no he hecho muchas pruebas para el juego ya que me centrado mas en otras cosas, me imagino que si es solo para darle detalles a algunos objetos en concreto no quedara mal, pero sinceramente no se lo que puede llegar coger de los recursos del móvil, pero me imagino que bastante) REFLECTIONS -Como su nombre indica son los reflejos de un objeto como puede ser un espejo, el reflejo del agua, etc… (Para un juego de móvil yo no me centraría en usarla, a no ser como siempre comento que sea algo muy… muy concreto y pequeño, no poneros ha hacer rascacielos de cristal que se reflejen entre si, que vais a poner el móvil para que se puedan freír huevos). 6-ILUMINACIÓN Este para mi es el tema mas importante y el primero que se tiene que tener en cuenta para realizar nuestro proyecto, debido a que es algo complejo ya que hay menús involucrados los voy a dejar para el final, con los menús correspondientes para explicarlo lo mejor que pueda. ALGUNOS CONSEJOS COSAS PROHIBIDAS A TENER EN CUENTA. -Cosas que tenemos que intentar evitar en medida de lo posible, ya que esto para un juego de móvil hace que la cosa se pueda ralentizar de cojones… hablando en plata. 1-Texturas con canal Alpha, como la gente conocerá y si no lo comentamos, hay algunas texturas como puede ser el PSD, TIF , PNG,etc.. que contienen información para crear desde el mismo archivo una transparencia a la textura, se puede encontrar mucho en hierbas, las hojas de los árboles, etc.. Esto ayuda mucho al modelado 3d (para los juegos de pc),porque poniendo un par de planos bien colocados podemos conseguir unos buenos detalles, pero el problema es que el procesamiento en un móvil para estas texturas es muy… muy limitado y aunque para pc sea una ventaja, para móvil suele ser una desventaja y un gasto de recurso brutal. (En mi caso este es uno de los árboles, como se puede ver tiene el tronco y 8 texturas en PNG que tienen el canal alpha, pues si no me equivoco hay 8 árboles enfrente de la mansión y cada vez que se mira hacia los árboles me da una bajada importante, por lo que intento desactivarlos cada vez que puedo). Vamos…que la primera vez que los puse entre 20 y 30 para dejarlo mas bonito, al girarme en el juego se me peto el movil por completo y creo que hasta me soltó un…Pero tu estas flipando chaval . COSAS ACONSEJABLES A TENER EN CUENTA. 1- Acostumbraros a que cuando carguéis un objeto, revisar lo que habéis exportado, ya que al exportar un objeto puede haber cosas activadas que si no me equivoco pueden darle una sobrecarga innecesaria al prefabricado. 1-MODEL En la sección de Model ya cada uno que lo ajuste a lo que necesite. 2-RIG Aquí por el momento lo dejare para otro post si la gente lo ve bien ya que esto hay que explicarlo desde el programa 3d también. 3-ANIMATION Si el modelo no contiene animaciones esto desactivado. 4-MATERIAL Aquí hay algunos formatos que exportan las textura y se la aplican al modelo directamente, a mi me gusta desactivar esto y poner yo la textura en el Unity, pero eso ya son manías mías, me imagino que si esta bien configurado no importa mucho. DESACTIVAR LOS OBJETOS QUE NO SE VEAN EN CÁMARA. -Aquí simplemente comentar un par de detalles, cuando preparéis el inicio del juego intentar desactivar todos los objetos que no se vayan a usar nada mas empezar, ya que todos los objetos desactivados no cargan sus scripts, por lo que nos ahorramos bastante procesamiento de primeras, y ya cuando los vayáis necesitando los vais activando poco a poco. (Yo en la escena solo dejo el charácter controller y seguido un script de precarga que me activa la zona de inicio, todo lo demás esta desactivado de primeras). SCRIPTS (UPDATE & START) Intentar no usar muchos scripts que tengan codigo dentro del void Update y optimizar la sección de void Start todo lo que podáis. (Aunque parezca que no hace nada, todos las secciones de “ void Update y void Start “ que suelen salir de base en los scripts, si van a estar vacíos, los borráis por completo, porque aunque no tengas nada dentro si están en el script, ya se gasta un mínimo de recurso en checkearlo y si no están nos ahorramos ese chekeo, sobretodo el update. Y ya con esto pasamos al bloque 2, este bloque es mucho mas cortito que ya se me esta haciendo muy largo esto y no quiero extenderlo mucho mas ^^’ -BLOQUE 2 (Menus Basicos) Hay varios menús básicos que tenéis que revisar para ir aprendiendo a gestionarlos y mejorar la optimización del juego, por el momento comentare lo mas básico de cada uno, pero estos menús hay que aprendérselos bien para poder jugar con lo comentado anteriormente. Buen modelado + buen ajuste en los menús = todo va de puta madre :D (Tener en cuenta que estas opciones, son opciones generales y afectan a todo el juego cuando se compila, es como si fuera un limite, si tenemos una luz con una sombra super ultra realista, y en este menú ponemos que las sombras son super ultra low, se pasara a los parámetros super ultra low del menú al compilarlo). -MENU DE QUIALITY En este menú se controla y se configura que calidad y que modos dispondrá el juego. Por ejemplo: PC : BAJA, MEDIA, ALTA, UTRA. IOS : BAJA, MEDIA. ANDROID : BAJA, MEDIA, (y en cada opción su configuración claro esta) (para juego de móviles, la opción de “ V Sync Count “ es el demonio en persona, eso es lo primero que tenéis que quitar). -MENU DE GRAPHICS Este es otro menú a echarle un ojo también, poco a poco tendréis que ir aprendiendo a gestionarlo para sacarle punta en las compilaciones para móvil. -MENU OCCLUSION Este menú es para acelerar el procesamiento de la cámara, prácticamente lo que hace es desactivar (las caras de los polígonos, collider,etc..) que están fuera de la visión de la cámara, ayudando al procesamiento del escenario. -LIGHTING y MENU LIGHTING Y por fin llegamos a la ultima parte, que me la he dejado para el final porque la considero de las mas importantes. Este menú controla las luces generales de la escena. -Environment Propiedades de entorno. (En este menú se controla una iluminación global que afecta a toda la escena, dándole el tono que necesitemos a todo el decorado) en mi caso suelo darle un color base y ya voy jugando con los shadowmask. (shadowmask se explicara mas abajo) -Realtime lighting Iluminación que se aplica en general a toda la escena como bien pone en tiempo real. (esto en medida de lo posible intentar no usarlo, se puede conseguir casi los mismos resultados jugando un poco con los puntos de luz) -Mixed Lighting Calculo de las luces en modo bake. (Bueno… esta es la opción mas a tener en cuenta para conseguir una buena optimización y buenos resultados de iluminación para nuestra escena, muy… pero que muy importante, aprender a configurar esta parte del menú) De las tres opciones me enfocare exclusivamente en el shadowmask que es el que mejor resultado nos puede dar. Lo primero que tenemos que conocer a la hora de iluminar nuestro decorado, es que lo que mas recurso puede llegar a consumir en un entorno 3d es la iluminación, por lo que un exceso de puntos de luz sobrecargaría todo el procesamiento, ya sea por el radio de la luz en si, como por las sombras que puede llegar a generar. Debido a esto toda la iluminación en Unity tiene 2 opciones. -Realtime (como bien indica, es una iluminación en tiempo real del punto de luz, con todo lo que eso con lleva). -Bake (El bake es la opción de decirle a Unity que genere una textura que se aplicara a todos los objetos que interactuan con dicha luz, creando en la textura todas las sombras que se supone que tendría general el punto de luz, de esta manera se ahora el procesamiento en tiempo real, acelerando bastante el procesamiento del decorado). Esto es un pequeño ejemplo de la sombra de una farola en modo bake (Shadowmask) También comentar que esto tiene sus pro y sus contra. -Pro: Ayuda en el procesamiento del calculo de iluminación de los punto de luz. -Contra: Lo malo que tiene el bake, es que solo se puede aplicar a objetos estáticos. (Aunque como siempre digo, todo es cuestión de saber jugar con los menús, vamos a poner el ejemplo del típico juego de terror en una casa con una linterna). -Iluminación Environment : luz azulada muy oscura para dejar intuir el escenario (MODO BAKE) -Iluminación decorado : algunos puntos de luz con sus sombras en algunas lámparas, el televisor, etc, etc..(MODO BAKE) -Iluminación de linterna : le damos un punto de luz que no tenga mucho radio y las sombras en calidad media, para ir iluminando por donde vaya mirando el personaje (MODO REALTIME) Lightmapping Setting Esto son las propiedades textura que crea el modo bake. (Importante saber gestionar este menú para darle la calidad que queremos a los shadowmask). -Other Setting Como bien indica el menú, niebla y los halos. -------------------------------------------------------------------------------------------------------------------------------------------------- -Bueno señores, por el momento con esto ya se despide un servidor, espero que no se haya echo muy pesado el post, porque creo que me he emocionado un poco de mas y no soy de escribir mucho xD. Si lo veis bien, lo iremos puliendo con el tiempo, agregando y organizando poco a poco las secciones que falten por explicar, para que podamos tener un buen post de ayuda para la comunidad sobre este tipo dudas.
  10. 5 points
    Hola. estoy terminando uno de mis proyectos. se trata de un juego de naves, un matamarcianos (shoot'em up)... con toques de rouge lite. Falta terminar los modos de juego extras (modo arena, modo survival, y modo bossRush). El modo historia esta acabado, con 25 escenarios y 10 escenas especiales.... no es necesario pasar por todas para llegar al final, puedes elegir multiples caminos. (no es lineal). De momento tiene mas de 30 enemigos diferentes (contando los bosses). 16 skills diferentes (armas secundarias) y multiples mejoras para la nave. Banda sonora original con mas de 40 temas. A ver que os parece... vuestros comentarios seran bien recibidos. trailer gameplay: special scenes trailer: boss trailer:
  11. 5 points
    Unity cada vez que creas un nuevo script, sea del tipo que sea, siempre consulta un archivo plantilla para generarlo. Por eso siempre tenemos añadido, por ejemplo, la función Start y Update, o creada la clase en función del nombre que le pongas al Script. Pero eso puedes modificarlo fácilmente. Simplemente dirígete a la siguiente ubicación: Será diferente según la versión de Unity que uses. Ahí podemos ver todos las plantillas, simplemente abrimos la que queramos modificar. Ahora podéis añadir una cabecera de Copyright o quitar las funciones Start y Update (que si no hay que tenerlas vacías). Ya las añadirás tu cuando las tengas que usar. Espero que os sea útil. Hasta la próxima
  12. 5 points
    Buenas, si alguien lo recuerda, este juego lo empece hace mucho, lo deje abandonado y no pude resucitarlo al tratarse de versiones tan antiguas de Unity. Actualmente estoy haciendo un reboot, de momento y a modo de demo técnica, os muestro este pequeño video de ejemplo:
  13. 4 points
    Finalmente, liberamos la herramienta! pueden acceder a ella totalmente gratis! http://www.modelatorsystem.com
  14. 4 points
    ¡Buenas! Mi experimento de carreras en TuCiudadTM. La idea es poder generar una escena aproximada de cualquier parte del mundo. La gracia es poder correr por tu ciudad o hacer misiones que te envían a sitios conocidos. Apóyanos siguiéndonos en Twitter: https://twitter.com/yourcityracing (venga que es 1 click!)
  15. 4 points
    Cuando decidí dedicarme a crear videojuegos una de mis preocupaciones principales era mi escaso conocimiento matemático. Internet estaba lleno de mensajes asegurando que no es necesario saber matemáticas para crear videojuegos y aunque, pueda ser cierto en determinados casos, creo que aprender las nociones básicas te van a ayudar a saber lo que estás haciendo y sobre todo a construir mejores juegos. Como veréis no es necesario un conocimiento matemático avanzado para entender gran parte de los cálculos habituales. En esta serie de publicaciones voy a hablaros de algunos conceptos matemáticos básicos que se usan constantemente en videojuegos: Trigonometría Vectores Matrices Funciones Trigonometría La trigonometría, como su nombre indica (tri-tres; gono-ángulo; metría: medida), es la ciencia destinada al estudio de las medidas de los ángulos. Si por ejemplo quieres girar un personaje en tu juego necesitarás un ángulo de giro. Para poder medir un ángulo (o cualquier cosa en general) necesitamos una unidad de medida, vamos a ver las dos principales en el caso de los ángulos: Grado Cuando vas a comerte una pizza lo primero que haces (después de cocinarla claro) es partirla en diferentes trozos. Imagina que la cortamos en 8 trozos, siempre en 8 trozos porque nos encanta el tamaño de cada trozo. Si quisieras medir el ángulo de cada trozo podrías crear tu propia unidad de medida basada en tu especial devoción por los 8 trozos. Llamémosle pizzo a esta medida. Entonces si tu cortas tu pizza en 8 trozos, cada trozo tendría un ángulo de 1 pizzo. Podríamos pedir que se estableciera como medida oficial el pizzo pero me temo que ya tenemos una medida general que puedes usar en su lugar: el grado. Si en lugar de 8 trozos partimos la pizza en 4 trozos iguales y establecemos que cada trozo vale 90 grados, tendríamos la definición de grado. La definición es la siguiente: cada una de las partes que resultan en dividir en noventa partes un ángulo recto. Aquí podemos recordar los tipos de ángulos rápidamente. Radián Una vez hemos recordado la unidad familiar que es el grado, vamos a ver el radián que es el que usaremos de forma habitual. Pero antes de entrar en el radián, debemos conocer el número Pi. ¿Qué es Pi? El número Pi es uno de los más importante en las matemáticas. Su definición es la siguiente: Pi es la relación entre la longitud de una circunferencia y su diámetro. Pero ¿qué significa esto? Pues básicamente quiere decir que sí dibujamos una circunferencia de diámetro 1 y medimos su longitud, obtenemos Pi. Con esta imagen lo entenderás mucho mejor. Si pintamos el borde de una rueda de diámetro 1 y giramos mientras pintamos el suelo midiendo la longitud de la mancha de pintura, tenemos Pi, que es un valor constante (e infinito): 3.14159… De forma habitual se trabaja con radio = 1 en lugar de diámetro = 1. Por lo que la longitud de la circunferencia es este caso sería el doble de Pi (2 π). Como apunte este número es conocido como Tau y su valor es 6.28318… Pero, ¿qué relación tiene esto con un radián? Si seguimos con el ejemplo de la pizza anterior, imagina que te ha venido la inspiración y has cortado la pizza de tal forma que la longitud del arco de cada trozo que has partido mide exactamente 1. Vamos a verlo gráficamente: La pizza tiene radio = 1 y cortamos (no tendrías que cortarla realmente porque es minúscula pero bueno) un trozo cuya longitud de arco es exactamente 1 (arco azul en la imagen). Pues bien, el ángulo que se forma, nombrado “a” en la imagen, mediría exactamente 1 radián. ¿Que pasa si seguimos cortando trozos con longitud de arco 1? Pues tenemos que el ángulo que se forma con media circunferencia (“a” en la imagen) es π radianes. Y el de la la circunferencia completa sería 2π (Tau) radianes. Nota: los dibujos son solo explicativos, las distancias dibujadas no usan medidas reales. Seno, Coseno y Tangente Una vez conocemos el concepto de radián vamos a experimentar un poco con las circunferencias. ¿Qué pasaría si formamos un cuadrado cortando el eje x e y de la siguiente forma? ¿Como calculamos el valor de “x” y de “y”? ¿Que son x e y? Pues aunque resulte sorprendente esos valores son el seno y el coseno del ángulo “a”: La definición nos dice que el coseno de "a" es la abscisa de su punto asociado y el seno de a es la ordenada de dicho punto. Creo que es mucho más entendible con la imagen anterior. A medida que el ángulo cambia, sus valores en x e y modifican su valor. Aquí podemos verlo mejor: La tangente como ves es la recta que toca en un solo punto la circunferencia en función del ángulo. Teorema de Pitágoras En este punto vamos a hablar de otro término muy importante en matemáticas y que usaremos en los siguientes publicaciones, el Teorema de Pitágoras. Este teorema dice que dado un triángulo rectángulo, podemos relacionar su hipotenusa(h) con sus lados (x e y) de la siguiente forma: Despejando tendríamos: ¿Pero qué uso tiene esto? Pues en el siguiente episodio hablaremos de su uso con Vectores. Imagina que tienes un personaje en un escenario y quieres saber a cuánta distancia está un determinado enemigo. Deberás plantearlo con el teorema de pitágoras, donde la “h” es la distancia entre tu personaje y el enemigo. Tendrías que calcular la “x” e “y” para posteriormente poder despejar “h”. Pero vamos a verlo con un ejercicio simplificado: Imagina que tenemos el siguiente triángulo. Para calcular h haríamos lo siguiente: ¿Y si quiero conocer el ángulo? Para conocer el ángulo necesitamos profundizar nuestro conocimiento en las razones trigonométricas. Vamos a verlo siguiendo el mismo ejemplo: Para calcular θ vamos a necesitar calcular primero el seno del ángulo. Pero ¿cómo hacemos esto sin conocer el propio ángulo? Anteriormente vimos que: Esto es así siempre y cuando el radio (la hipotenusa) fuera 1. Pero ¿qué pasa si como en este caso la hipotenusa es 7.81? Solo tendremos que dividir la variable entre la hipotenusa de la siguiente forma: Vale ya sabemos calcular el seno sin tener el ángulo: Una vez tenemos el seno necesitamos conocer el concepto de función trigonométrica inversa. No os asustéis porque el concepto es muy simple. Necesitamos algo que multiplicado por el seno (que ya lo conocemos) nos de el ángulo. Veremos más a fondo este término cuando veamos las matrices. En este caso las función trigonométricas inversas las conocemos y son las siguientes: Nota: en español también se les llama cosecante (arco seno), secante (arco coseno) y cotangente (arcotangente) Ya conocemos cómo obtener el ángulo: Ya tenemos el valor en radianes del ángulo. Si necesitamos pasar de radianes a grados, podemos usar las siguientes fórmulas: Aquí podemos ver gráficamente las razones trigonométricas que hemos visto aquí: Espero que os sea de ayuda y perdonad si he cometido algún error o he explicado algo de forma muy torpe. No soy ni mucho menos un experto matemático, mi intención es que todos podáis acercaros y verlas un poco más fácil. Cualquier duda estaré encantado de ayudar. En la próxima parte veremos Vectores y pondremos en práctica todo lo aprendido aquí pero dentro de Unity. Hasta la próxima.
  16. 4 points
    Es un pequeño juego 2D creado para la JAM de UnitySpain. Tienes que guiar al personaje por el bosque hasta que llegue a casa. El juego es tranquilo, se trata de ir encontrando los diferentes caminos y esquivar los peligros que se encuentra como los lobos o las lanzas. Creo que le dedique mas o menos unas 16 horas, y estoy contento con el resultado, tanto que me quedo con el proyecto para irlo evolucionando poco a poco, ya ire compartiendo los cambios y los "improvements". Cualquier idea, o crítica, que querais aportar sera muy bienvenida. Por ahora esta disponible en itch.io: https://uadla.itch.io/way-home
  17. 4 points
    Hola @nomoregames, primero que nada decirte que esto no es con ánimo de ofender ni de crear controversia. Este tipo de dudas son básicos de la programación, no es algo de unity sino de el lenguaje. Yo te aconsejo leerte un libro de c# o hacerte un curso donde aprendas al menos lo básico y no andes dando palos de ciego hasta encontrar la respuesta. No me molesta para nada que hagas estas preguntas, pero me parece que se crea contenido innecesario, soy consciente de que nadie nace sabiendo pero si no nos intentamos educar seguiremos en ese bucle de por vida. Digo esto por tu bien y por el entusiasmo que veo que tienes con la creación de videojuegos, puedes explotar ese potencial. Hay muchos cursos de programación en Youtube, también puedes utilizar webs como codeAcademy o KhanAcademy que son gratuitas y super buenas. Es un mundo muy bonito y que si le echas ganas puede sorprenderte más de lo que imaginas.
  18. 4 points
    Me alegro de que os guste!! Si tenéis cualquier duda, estoy por aquí (pero en el Telegram suelo contestar antes 😉).
  19. 4 points
    Acá les dejo el twitter de este señor: https://twitter.com/tuxedolabs?lang=es Sus videos y artículos son muy buenos, 100% recomendado. Tiene proyectos que integran: Geometría compleja basada en mini voxels (más tirando a átomos que al cubo de minecraft). Físicas rígidas, blandas, flexibles y de flotabilidad. Partículas, Iluminación completamente dinámica. Destrucción. Audio (para manejar todo el tema de las físicas + destrucción). Shaders. Efectos volumétricos. y más :) ... Realmente impresionante, se me hace que este tipo va a quebrar la internet en unos años. Les dejo algunos tweets: El juego que está creando (muy linda idea): Esas partículas :P
  20. 4 points
    Mira que fue una chorrada que se me ocurrio y es lo que mas exito tiene y mas gracia le hace a la gente. Gracias Pere por tus animos, quizas cuando crezca un poco el bicho pueda dedicarle algo de tiempo hacwr videojuegos, pero ahora lo veo complicado. Mas que por el niño por el trabajo, en el anterior si no habia incidencias el fin de semana podia llevarme el portatil y dedicarle tiempo a los videojuegos. Espero que a lo termines y verlo por aqui para probarlo. Os dejo otro gameplay muy gracioso de um chino, esta to loco!! Saludos!!
  21. 4 points
    Cuando tienes una gran cantidad de sprites en tu proyecto, es una buena práctica (por no decir que es obligatorio) organizarlas todas en torno a un Sprite Atlas. Esto te ayudará a ahorrar memoria en tiempo de ejecución además de a reducir los tiempos de acceso a ellas. Para crear un Sprite Atlas, puedes hacerlo desde botón derecho en vista de proyecto y Create/SpriteAtlas. Una vez creado simplemente tienes que seleccionarlo y agregar todos los sprites que necesites. Puedes probar las opciones para ver los resultados. Ten en cuenta que tamaños muy altos de Sprite Atlas no son compatibles con algunos targets. Puedes activar, desactivar o limitar el uso de Sprite Atlas desde ProjectSetting/Editor. Espero que os sea útil. Hasta la próxima
  22. 4 points
    He encontrado esta enorme fuente de información googleando a cerca de mesh deformation, y wow, que mérito tiene la persona que hizo esto. https://catlikecoding.com/unity/tutorials/
  23. 4 points
    https://connect.unity.com/p/spriteanimator-2d-tool Completo sistema para trabajar con Sprite Sheets Visitar en Assets Store https://assetstore.unity.com/packages/tools/sprite-management/spriteanimator-153405
  24. 3 points
    Desarrollo en Unity 2019.3. Una primera aproximación a un FPS sin prácticamente optimización más allá de los lightmaps del entorno. Es posible utilizar diferentes FX dependiendo del material de contacto. He utilizado algunos assets de pago y otros gratuitos en los apartados de diseño solamente. El código y la integración es mío desde cero. El canal de youtube para seguir las actualizaciones es: https://www.youtube.com/user/LosSopranoNet/videos
  25. 3 points
    la verdad que estan chulas las fisicas del cable. creo que esto no cuenta como spoiler del juego... o si? si es asi lo siento, cierrenme el tema. pero me gustaria devatir como creen qye funcionan esas fisicas. creen que la manguera esta formada por pequeñas secciones? o es mas bien varios raycast que dividen la manguera en secciones mas grandes cuando colisiona? y el tramo que tiene enrollado en la mano?? forma parte de la misma manguera? o es un objeto adicional para que de la sensacion de que se enrolla.... y miestras tanto la manguera original crece o disminulle su longitud en relacion con la parte que ha enrollado en la mano? ...claro que la parte que tiene enrollada en la mano tiene fisicas tipo "cloth".... pero no reacciona al escenario... eso es lo que me ha hecho pensar que son dos cosas distintas la manguera y lo enrollado... aunque tamvien cuando la lanza cambia un poco el comportamiento... creo que puede ser todo un unico objeto al que le cambian las "layers" de colisiones depemdiendo el momento ...y depemdiendo de que secciones de la manguera sean les ponen unas layers u otras... puede que todo sea una especie de "cloth" gigante... que cuando ha alcanzado su maxima tension (estirado) manda un mensage al personaje para que haga la animacion de "huy, ya no alcanza mas" ustedes que opinan?
  26. 3 points
    Buenas a todos, Quería presentados mi proyecto Steel Wars Royale en el cual llevo trabajando desde mediados del 2017. Es un proyecto muy ambicioso sobretodo por su complejidad técnica, ya que es un juego 100% online con batállas 1vs1 síncronas y sistema de almacenamiento de datos (BackEnd). Desde el principio, a pesar de tener recursos bastante limitados, he buscado calidad triple A y que al ver el juego de la sensación de que hay un buen estudio de desarrollo detrás. Esto me ha hecho ir mucho más lento de lo que me gustaría. Os dejo un mini trailer casero que yo mismo he hecho: En breves (en 2-3 días si todo va bien) voy a probar el juego con público real por primera vez, en una Alpha Cerrada para la plataforma Android desde Google Play. Me gustaría alcanzar un volumen de unos 50 jugadores, de los cuales ya tengo unos 20-30. Si alguien con Android se anima a ser Tester, es más que bienvenido! Los interesados podéis entrar en www.steelwarsroyale.com y dejar vuestro correo electrónico. Es una lista de correos gestionada con MailChimp. No se va a usar para hacer SPAM ni con otros fines comerciales, se va a usar únicamente para dar información del juego y avisar de sus testeos y lanzamiento. En cualquier momento os podéis quitar de la lista de correo pulsando abajo de cualquier e-mail "cancelar suscripción". Muchos de vosotros no seréis el target de audiencia para este tipo de juegos F2P de móvil, pero vuestras opiniones y feedback serían de gran ayuda. ¡Gracias de antemano a todos los interesados! Información más técnica para developers: Para el desarrollo del juego he usado el motor Unity3D. Para el sistema de BackEnd he usado el BaaS Gamesparks. He orientado el juego a ser 100% Data driven, es decir, en el arranque del juego se conecta al backend y adquiere todos los metadatos al vuelo (unidades, stats, recompensas, tiempos etc.). Esto me permite modificar gran parte del juego sin necesidad de subir una Build nueva a las stores. Si quiero modificar los stats de una unidad, o si quiero modificar el % de drop de undiades legendarias etc. lo hago todo desde el back-end. El poder hacer estas modificaciones al vuelo se estila mucho en juegos de móvil F2P (para un buen sistema de Live-Ops). Para el multijugador síncrono, he usado una tecnología que a día de hoy es privada. Es un motor determinista de Photon llamado Photon Quanqum. Conseguir esta tecnología (por el momento, sin coste alguno) ha sido complicado. Para ello me he tenido que reunir un par de veces con Christof Wegmann, fundador y CTO de Exit Games (Photon). Quantum es bastante peculiar por que requiere escribir la lógica de juego (movimiento, colisiones etc.) en unas librerías a parte con su propio motor (basado en ECS) que luego se insertan en Unity mediante DLL's. Es decir, Unity en este caso es un render-dummy, la lógica de juego/batalla está escrita en el motor Photon Quantum. Si tenéis dudas o preguntas, me las dejáis por aquí escritas
  27. 3 points
  28. 3 points
    Y aquí estamos con más novedades. El "esperado" ciclo día/noche y cambio atmosférico dinámico:
  29. 3 points
    ¿Has probado a juguetear con los distintos parámetros que tiene el NavMeshAgent? https://docs.unity3d.com/ScriptReference/AI.NavMeshAgent.html En el siguiente vídeo de Brackeys muestra un poco alguno de estos parametros
  30. 3 points
    Hola! El curso tiene ya 3 niveles con un total de mas de 130 videos actualemte y aun quedan 3 niveles mas. los invito a que se unan, estoy empezando el nivel 4 del curso. saludos
  31. 3 points
    Espero que no se considere como spam, pero estoy grabando mis progresos aprendiendo Unity a través de un juego de cartas. Está claro que si lo veis las vacas sagradas, me atizais en el lomo, pero igual viene bien para los que son tan inutiles como yo. Pues eso. Aquí lo dejo, por si van apareciendo novatillos en esto. A darle duro.
  32. 3 points
    ¡Buenas! En este post @seimus comentaba sobre una herramienta para exportar un tilemap como PNG, y @pioj también estaba de acuerdo con la idea así que hice una pequeña herramienta y la subí al github. La verdad es que la he testeado muy poco pero en principio debería adaptarse a cualquier tamaño, yo la he estado testeando con sprites de 32x32. Os dejo un vídeo y el enlace a github! https://github.com/leocub58/Tilemap-to-PNG-Unity Espero les sirva de ayuda, yo la verdad es que lo he hecho por simple aburrimiento jajajaja. ¡un saludo!
  33. 3 points
    Buenas tardes a tod@s, Quería plantearos una nueva forma de organizar y mostrar contenidos de la web proporcionándole mayores interacciones y facilidad de visualización de contenidos. Actualmente el sistema foro, desde mi punto de vista, ha quedado limitado y no se adapta a las "nuevas exigencias" y hábitos de los nuevos usuarios que están llegando y que llegarán en el futuro. Los foros tienen una forma de distribución de contenidos basado en subcontenidos en el que el usuario debe ir navegando a través de diferentes topics/contenidos hasta llegar al apartado que le interese y donde se le indica que existe nuevo contenido a través del simple cambio de icono. Como todos sabréis estos últimos años han ido cayendo en desuso y es una realidad de que la mayoría de sistemas de foro integrados en páginas web se parecen más a lo que vemos en redes sociales que al estilo clásico que de hecho todavía se sigue utilizando en UnitySpain (aunque bastantes novedades como sistema de notificaciones). No nos engañemos, antes de que los foros se pusieran de moda como una forma de comunicación existían las listas de correos, las cuales hoy en día son una ventana al pasado y de lo que creo que los foros, tal y como los conocemos, les espera el mismo destino. Los nuevos usuarios, y los que vendrán los próximos años, están habituados a utilizar otros sistemas de comunicación muchos más versátiles, cargados y destacando contenidos multimedia por delante del simple texto y mostrando de forma ordenada "el contenido más nuevo" en detrimento de lo más antiguo para facilitar de un vistazo lo último publicado, comentado, etc. Es mejor mostrar un vídeo o una imagen de lo que acaban de publicar que el simple texto "este es mi proyecto rts", porque atrae mayor interés, o no, según el caso de lo mostrado. No es solamente una nueva forma de mostrar contenidos, sino que abre un nuevo abanico de posibilidades de interacciones entre los usuarios. Ciertamente el foro actualmente tiene algunas funcionalidades que podríamos calificar de sociales, pero la forma de distribución de contenidos no se asemeja a lo que está demostrado que funciona, que incentiva a la comunicación entre usuarios y que mantienen una conexión constante a la web. Podría detallar cada una de las nuevas funcionalidades o estilos de contenidos a los que hago referencia, pero creo que todos conocemos y reconocemos la utilidad de redes sociales como Twitter o Facebook. Cada usuario tendría su propio espacio (estilo muro o blog), podría subir archivos e imágenes y disponer de su propio portafolios y unirse y crear grupos, los cuales podrían sustituir a lo que actualmente conocemos como cada foro. La página principal mostraría directamente los últimos contenidos publicados, comentarios y actividades, no teniendo el usuario que navegar entre subcontenidos para encontrar lo último publicado (siendo algo más llamativo que el recent topics). No digo que este sistema de comunicación y muestra de contenidos sea mejor, sino que es diferente y se adapta a lo que hoy es el resto de la WWW. Por todo ello, creo que podríamos plantearnos cambiar el foro por un sistema como el que os comento utilizando software como Buddypess, elgg u otro que cumpla la misma función. A continuación os dejo algunas imágenes y enlaces para que podáis ver algunos ejemplos de lo que os he relatado. Espero vuestros comentarios sobre esta idea y el debate que aquí se abra. Esto no quiere decir que sea un debate para cambiar lo existente sí o no, sino de abrir esta posibilidad y comentar los pros y los contras del posible cambio. https://olympus.crumina.net/members/dan_cortese/friends/ https://buddy.ghostpool.com/ http://themekitten.com/demo/atlass2/activity/ https://seventhqueen.com/themes/kleo/members/kleoadmin/groups/
  34. 3 points
    La última actualización que ya puse vía Telegram. Así se ve la evolución:
  35. 3 points
    No está pensado para eso, le estás haciendo un mal terrible al pobre componente. Entiendo el truco, pero no te conviene usar algo así para esto. Hasta que te das cuenta de que el CC no lo podés rotar ... si querés siempre un personaje que tenga el Up = Vector3.up, estonces está bien. Primero lo básico, ir a la documentación: https://docs.unity3d.com/ScriptReference/CharacterController.html Para el callback OnControllerColliderHit tenés un ejemplo que hace exactamente eso: https://docs.unity3d.com/ScriptReference/CharacterController.OnControllerColliderHit.html Y si nada te funciona, bueno, simplemente obtener del asset store el mejor character controller: https://assetstore.unity.com/packages/tools/physics/character-controller-pro-159150
  36. 3 points
    Es lo primero que he hecho pero no me entero porque no explican las cosas paso por paso, por ejemplo, ¿cómo se llega a esta ventana?: Te dejo el link de esta página, no lo compartas, es ultra secreto, lo saque de la deep weeb pero aporta una información vital sobre AnimatioView Link del infierno Link del Infierno X2 También quiero que sepas que existe una web a dia de hoy algo conocida, desarrollada especialmente para buscar eso que no sabemos ni como se llama Link a la página mágica.
  37. 3 points
    Hola @nomoregames te aconsejo que antes de empezar a intentar realizar un juego al 100% aprendas, técnicas, formas, algoritmos que suelen utilizar los desarrolladores de juegos. Aprendizaje Básico: Entender las estructuras de datos simples de C# Entender los delegados y eventos Aprender sobre NameSpace, Clases, Estructuras y Niveles de Accesibilidad. Aprender sobre Clases Abstractas Aprender sobre funciones Virtuales Aprender a utilizar Switch Aprender a utilizar Enumeradores Aprender a utilizar Linq, ventajas y desventajas Entender los vectores Aprender y utilizar vectores de dirección Entender las posiciones, rotaciones, escalas tanto globales como locales Aprender el ciclo de vida de una objecto en C# Aprender el ciclo de vida de un componente Entender MonoBehaviour Aprender a realizar Herencias Aprender a serializar clases Aprender a utilizar BinaryWriter y BinaryReader. Aprender a trasladar objetos a diferentes velocidades. Aprender lo básico sobre componentes físicos (Rigidbody) Aprender fórmula de tiro parabólico. Aprender fórmula de curva bézier. Aprender sobre Raycast, Box , Sphere, Line, Ray y todas sus variantes. Aprender sobre prefabs y el nuevo flujo de trabajo con nested-prefabs. Aprender a utilizar Singleton Aprender a utilizar Atributos de clases. Aprender a utilizar Scriptable Object para la fragmentación de comportamiento datos. Aprender sobre Listas, Arreglas Aprender sobre variables de sólo lectura Aprendizaje Avanzado: Aprender sobre funciones arrow Aprender sobre funciones lambda Aprender a utilizar correctamente Dispose y Garbage Collection Aprender a utilizar Dots. Aprender a utilizar HLSL (Surface Shaders) Aprender a utilizar Partículas Aprender a utilizar Sockets Aprender a utilizar WebClients Aprender a utilizar Threads Aprender algoritmos de búsquedas de camino Pathfinding como A* Actividades: Crear un sistema simple de WayPoints Crear un sistema de seguimientos de WayPoints mediante direcciones y fuerza Hacer un seguimiento de cámara simple Simular la gravedad de una caja sin rigidbody. Calcular la fuerza exacta para lograr el salto de 1 unidad con rigidbody. Generar un Cubo mediante Código con MeshRenderer. Guardar y Cargar datos en formato binario. Simulador de vuelo de un avión sin Rigidbody. Simulador de vuelo de un helicóptero sin Rigidbody. Simulador de vuelo de un avión con Rigidbody. Simulador de vuelo de un helicóptero con Rigidbody. Movimiento simple de jugador 2D sin rigidbody. Movimiento simple de jugador 2D con rigidbody. Movimiento simple de jugador 3D sin rigidbody. Movimiento simple de jugador 3D con rigidbody. Movimiento simple de jugador 3D con CharacterController. Detectar si el Jugador está en contacto con el suelo. Calcular el tiempo que el jugador estuvo en el aire. Calcular el tiempo que el jugador estuvo en el suelo. Calcular la fuerza necesaria vertical y horizontal para que un objeto sin Rigidbody recorra 10 unidades con una fuerza gravitatoria de -10 en el eje Y. Detectar si el Jugador está en contacto con la pared (que se encuentre por delante). Detectar si el Jugador está en contacto o próximo a un objeto sobre su cabeza. Evitar que el Jugador salte si no tiene el espacio suficiente. Generar zonas con diferentes comportamientos físicos, como deslizarse, alentar, acelerar, rebotar. Controlar la velocidad de Jugador para que recorra 100 unidades en línea recta siempre al mismo tiempo. Diseñar UI mediante editor (Edit Mode). Diseñar UI mediante código (Runtime). Proyectos para aprender sobre mecánicas: Intenta replicar las mecánicas de la forma más exacta posible, luego modificarlas para experimentar y entender el por que se llegó a la decisión de mantener esos valores. Memo Puzzle Rompecabeza Pong: https://es.wikipedia.org/wiki/Pong Snake: https://es.wikipedia.org/wiki/La_serpiente_(videojuego) Tetris Arkanoid Pacman Space Invaders Super mario bros (Mecánicas) The legend of zelda (Mecánicas) Infinity Runner (Mecánicas) Half-Life 1 (Mecánicas) Proyectos NO RECOMENDADOS: RPGs MMO ROL el clásico "GTA" Juegos Multiplayer como BF, Fornite, etc.. Links para estudio y practicar: son los que me acuerdo que leí en algún momento y me han servido, los de CEDV son muy buenos, lamentablemente ahora se pasaron a Unreal, pero siguen estando las ediciones del 2015 https://openlibra.com/es/book/download/desarrollo-de-videojuegos-un-enfoque-practico-3a-ed/ https://openlibra.com/es/book/download/desarrollo-de-videojuegos https://openlibra.com/es/book/download/logica-del-videojuego http://cedv.uclm.es/libro2015/M4.pdf Esto está destinado a todos los usuarios que se encuentren estancados.
  38. 3 points
    WIP. (8/12/19) español: Hola gente! estoy desarrollando un sistema procedural, para la creación de edificios de polígonos bajos. actualmente el sistema cuenta con: - creación de estilos nuevos. - opción para agregar o quitar guías de puntos y lineas. - selección de estilos para dibujar. - menú interactivo de muestra para los estilos creados. - selección de texturas para las paredes y el tejado. - modificación de texturas (escala y posicion). - altura base del modelo. - altura total del modelo. - generar o borrar el tejado. - creación, eliminación y manipulación de nodos. - menú interactivo para crear o eliminar el estilo seleccionado, y eliminar el modelo actual en el que estas dibujando. en manos de un buen diseñador, esta podría ser una gran herramienta! ¿que opinan al respecto? espero que les guste esta idea! https://www.youtube.com/watch?v=RnpPpRkUDpk
  39. 3 points
    Hola Os informo de que Vuforia se está poniendo las pilas con las licencias. Si publicáis un app que les llama la atención, no podréis usar la licencia de developer y os pedirán que paguéis por la licencia. El problema es, si habéis publicado con la de developer, no podréis comprar la standard sino la Pro que vale una pasta al año. Os recomiendo que si empezáis un proyecto de AR, os miréis y lo hagáis con el ARFoundation de Unity. Saludos
  40. 3 points
    El Standard Shader de las últimas versiones de Unity soporta varios métodos. La propia doc de Unity es bastante decente en este sentido: Llaman bump mapping al normal mapping, pero dejan claro que es algo informal, y que "normal mapping" es un tipo de bump mapping. El Standard Shader ahora soporta "height maps" y "occlusion maps", que son también técnicas de bump mapping. Además no son exclusivas. Normal Maps (o en unity, simplemente "Bump maps"): Afectan al ángulo de la luz al rebotar sobre la superficie, y nos permite dar sensación de relieve que se comporta corectamente respecto a la iluminación. En esta página hay un apartado llamado "What’s the difference between Bump Maps, Normal Maps and Height Maps?" Unity acepta texturas black and white y las convierte internamente a RGB (normales X, Y, Z) para los normal maps. Height Maps (o Parallax Maps): Al contrario que los normal maps, que trabajan sobre la luz, los Height Maps calculan realmente el pixel desplazado donde estaría de acorde al relieve, haciendo que píxeles más cercanos aparezcan más grandes respecto a la cámara. Además, las partes con más relieve taparán a las de menos relieve. Es más costosa para la GPU. Se usan a menudo junto a Normal Maps. La fuente es una textura en grises. Occlusion Maps: Afectan a la cantidad de luz indirecta que debe recibir cada parte del material. Recomiendo encarecidamente leer las tres páginas. Aquí debajo tenemos: 1) Albedo 2) Albedo + Normal 3) Albedo + Normal + Height Observa, sin embargo, que ninguna de estas técnicas permite que los bordes de los polígonos presenten relieve. Esto no se puede hacer en una GPU, y el ejemplo de la bola que muestras arriba parece otra técnica llamada "displacement mapping", que Unity no soporta de serie.
  41. 3 points
    ¡Hola! Os traigo uno de mis assets gratis más descargados: Basic Motions Pack. Se trata de un pack de animaciones 3D de movimiento básicas para que las apliquéis a los personajes de vuestros juegos y apps. Asset Store Link (Gratis) Lista de animaciones: - Idle01- Idle02- Idle01 - Idle02 (transición)- Idle02 - Idle01 (transición)- Jump (inicio - en el aire - aterrizar)- Caminar- Correr- Correr hacia atrás- Sprint Totalmente gratis y lo podéis usar en cualquier tipo de proyecto, incluso comercial. Cualquier duda o sugerencia: contact@keviniglesias.com Más assets como este: www.keviniglesias.com Asset Store Publisher Vídeo de muestra con algunos ejemplos:
  42. 3 points
    Un mini juego para Halloween para probar el AR Foundations de Unity 2019.2. La publicaré en breve. Espero os guste.
  43. 3 points
    Vertex Displacement Este ejemplo servirá de introducción para el desplazamiento de vértices. Vamos a crear un nuevo shader, con su material correspondiente y lo vamos a aplicar en una esfera añadida a la escena. Colocamos la esfera visible para la cámara y comenzamos. Para el desplazamiento de vértices vamos a usar la primera de las entradas del Master Node, ya sea el PBR Graph o el Unlit Graph. Para este ejemplo usaremos el PBR Graph pero es indiferente. Para poder mover los vértices, simplemente tenemos que usar el nodo Position para saber la posición y sumarle el desplazamiento. En este caso usaremos un desplazamiento en dirección a su Normal. Tendremos que asegurarnos de que el espacio en el que estamos trabajando está en relación al objeto y no al mundo. Esto podemos configurarlo en la variable Space del nodo. Con esto tendríamos un desplazamiento simple de los vértices. Pero es un desplazamiento constante, vamos a añadirle ruido y movimiento con los nodos Noise y Time que vimos anteriormente. Ahora tenemos un efecto mucho mejor. Pero el movimiento está basado totalmente en el ruido que obtenemos, sin tener en cuenta cual es la posición actual del vértice. Para que tenga en cuenta la posición del vértice y se modifique en función de esta, simplemente sumamos a la Posición el Tiempo y lo conectamos con el Ruido. Ahora hemos conseguido el efecto que queríamos. Cada vértice se mueve en función de su posición y del ruido que generamos. Si queremos cambiar la intensidad podemos usar el nodo Remap. Este nodo dado un valor mínimo y máximo de entrada, interpola el valor entre dos valores de salida mínimo y máximos. Por ejemplo en este caso, la salida del Simple Noise está entre 0(negro) y 1 (blanco). Estos dos valores serían la entrada al Remap. Si los valores de salida fueran 0 y 10, en los valores en los que el ruido entrase con valor 0.7,saldría interpolado entre 0 y 10, es decir saldría como 7. Como vemos, ahora el efecto se intensifica en función de la salida que establezcas en el Remap. Recuerda guardar las variables en la Blackboard para poder cambiar los valores desde el propio material posteriormente. Para acabar podemos hacer lo que queramos con el color. Podríamos simplemente asignarle una textura o crear un portal como en los anteriores casos. En este caso para no alargarlo, vamos a usar un simple Voronoi junto a un Color para dar el efecto que vimos en el gif. Es prácticamente lo mismo que hicimos en el anterior shader, colocamos el Lerp y le seteamos los dos colores. Espero que os sea útil y cualquier cosa no dudéis en preguntar.
  44. 3 points
    Portal Effect El siguiente efecto es un portal muy simple inspirado un poco en la serie Rick and Morty: Para este efecto, a diferencia del anterior, vamos a crear un Shader Unlit Graph. La diferencia es que el PBR Graph incluye cálculos de iluminación avanzados entre otras cosas, cosa que el Unlit no. Este nodo Master como vemos, sólo tiene entradas para color y alpha. Una vez creado el shader, vamos a añadir un Quad a la escena con un nuevo material con nuestro shader. Colocamos la cámara para poder verlo y hacemos el Quad del tamaño que desees hacer el portal. Podrás cambiarlo posteriormente. Una vez creado abrimos el shader. Lo primero que queremos es crear una máscara circular para darle el efecto ovalado y no tener el rectángulo actual. Esto es simple, simplemente creamos un nodo de forma tipo elipse(Procedural/Shape/Elipse). Cambiamos el tamaño a 1 en ambas dimensiones y colocamos la salida del nodo en el Alpha del Master. Como en el anterior shader, sacamos un integer del AlphaClip y lo colocamos a 1. Si guardamos y probamos podemos ver que ahora es una elipse en vez de un rectángulo (cambia el color en el Unlit Master directamente si no lo consigues ver). Para seguir vamos a hacer uso de dos nodos, que combinados, dan justo el efecto que buscamos. El primero de ellos es un nodo de ruido,Voronoi. La explicación de Voronoi se saldría del objetivo de este tutorial asique si te interesa te dejo un enlace de un artículo que lo explica muy bien: https://www.abc.es/ciencia/abci-diagrama-voronoi-forma-matematica-dividir-mundo-201704241101_noticia.html Junto al nodo de Voronoi vamos a usar un nodo de movimiento de UV, en este caso por Twirl que hace que las UV giren. Uniendo el nodo de Twirl al nodo de obtendremos lo siguiente: Puedes cambiar las variables de entrada de ambos nodos para que configurar el efecto a tu gusto. También sería una buena práctica crear propiedades para poder configuraras luego desde editor. Ahora solo falta que gire, para conseguir este efecto necesitamos acudir a otro modificador de UV, en este caso el nodo Rotate. Este nodo se coloca en la entrada de UV del Twirl y nos permitirá controlar el giro de este. Podremos controlar el giro con la entrada Rotation del nodo Rotate. Llegados a este punto vamos a hacer uso de un nodo muy importante, que quizás se me olvidó comentar en la lección pasada. Es el nodo Time, el cual nos permite usar diferentes tipos de tiempo según lo necesitemos. Creamos entonces un nodo Time y conectamos la salida Time (el tiempo por defecto) a la entrada de Rotation. Como ves, si queremos controlar el tiempo simplemente podemos guardar una variable que multiplique el tiempo y esa salida la conectamos al Rotate. Puedes experimentar con los demás tipos de tiempo para ver lo que ocurre con cada uno. Ahora ya solo necesitamos añadirle color. Puedes notar que el Voronoi tiene dos salidas, te animo a que pruebes el efecto con ambas, ya que son el mismo concepto pero de diferentes estilos. Yo me voy a quedar para este con la salida Cells, que le da un toque más estilizado. Al igual que con el anterior, vamos a hacer uso del nodo Lerp que nos ayudará a convertir los colores negros y blancos en los colores que nosotros queramos. Creamos dos colores, para poder editarlos más adelante y los colocamos en las entradas A y B del nodo de Lerp. Con esto el efecto estaría terminado. Vamos a añadirle unos detalles extra para mejorar el efecto. Podemos sacar un nodo Step del Voronoi. En este caso he usado la salida por defecto para poder apurar más el Step. Ponemos un valor pequeño en la entrada del Step para darle un toque sutil simplemente. Lo multiplicamos por el color que quieras, en mi caso blanco y posteriormente lo añadimos a lo que teníamos hasta ahora. Siéntete libre de modificar los valores a tu gusto para darle el tu propio toque. Espero que os sea útil. Cualquier duda que tengas no dudes en dejarla. Hasta la próxima.
  45. 3 points
    Hola, un vídeo en el que explico como crear objetos recolectables. He intentado que sea lo mas configurable posible. Por ejemplo, se pueden indicar objetos a activar en los objetos que se cogen, y el player (responsable del inventario) puede contener objetos de diversos tipos, y a cada tipo se le puede asignar la instanciación de un objeto nuevo cuando se use.... No se si me explico, pero a mi me han funcionado muy bien, así que espero que ayude a todos los que estan empezando. Saludos!
  46. 3 points
    Acá les dejo un excelente tutorial ( en tres partes ) a modo de introducción al nuevo Input system. Uno de los mejores que vi, los demás videos parecen copy+paste, además de que todos ponen las expresiones lambda sin ni siquiera saber que hacen (o por lo menos da esa sensación). Parte 1: introducción y Setup Basicamente de Input.GetKeyDown(KeyCode.w) a keycoard.wKey.isPressed Parte 2: Binding y Composite Acá explica como se pueden especificar bindings (conexiones entre acciones y dispositivos físicos) visibles en el inspector. Un "Composite" es lo mismo pero para con más de un binding. Parte 3: Input System Asset Se migra todo lo expuesto en la clase a un Asset propio del nuevo sistema, con la ventaja de setear varios ActionMaps (por ej uno para un menu, otro para gameplay, etc) con sus acciones y sus bindings.
  47. 3 points
    @Rootet en tu script hay cositas que están bien otras que están mal, por ej: 1) Update para inputs, FixedUpdate para físicas: if (Input.GetMouseButtonDown(1)){ if (corriendo){ } else{ rigi.velocity = new Vector2(velocidad * 1.25f, rigi.velocity.y); } } En update, estás modificando una velocidad, cosa que debés hacer en FixedUpdate, esto se lee como "Si apreto el botón derecho y corriendo es false la velocidad X es el 25% más grande" y esta actualización sucede en un solo cuadro, no cuadro a cuadro. Además si la velocidad es un 25% más grande se supone que corriendo ahora debe ser true pero no, se setea true si apretás el otro botón (en FixedUpdate). ───────────────────────────────────────────────────────────────────────────────────────────────────── 2) Quién es responsable de corriendo? if (Input.GetMouseButtonDown(0)){ if(corriendo){ if ((enSuelo || !dobleSalto)){ sonido.Play(); //Empujón hacia arriba //Opción 1. Metodo up de Vector2 rigi.AddForce(Vector2.up*fuerzaSalto); //Otra opción //Aplicamos una fuerza de 0 en X y de fuerzasalto en Y //rigi.AddForce(new Vector2(0,fuerzaSalto)); if(!dobleSalto && !enSuelo){ dobleSalto=true; } } } else{ corriendo=true; NotificationCenter.DefaultCenter().PostNotification(this, "PersonajeEmpiezaACorrer"); } } Cuando apretás el botón izq y no está corriendo se da la primer vuelta (el else), es decir que se pone corriendo = true. En el siguiente cuadro GetMouseButtonDown no se dispara (por razones obvias) entoces el "if(corriendo)" no se da. Sí se va a dar el "if(corriendo)" en el proximo click. Además, ¿quién pone corriendo en false? Y volviendo al punto 1, solo si corriendo es falso la velocidad aumenta. Una vez que diste click izquierdo corriendo nunca vuelve a false (?). Puede ser que me haya olvidado de algo, muchas veces contesto a la ligera. ───────────────────────────────────────────────────────────────────────────────────────────────────── █████████████████████████████████████████████████████████████████████████████████████████████████████ Podés resolver el problema parcheando if's y demás, pero te diría que de entrada la estructura es muy confusa para una tarea tan simple, tomalo como una oportundad de mejora y experimentá con una nueva, que tenga más lógica y sobretodo que alguien externo al código lo vea y lo entienda al instante, pensá que esto es un salto y una funcionalidad de correr, practicamente no es nada. La lógica que te recomiendo para una mezcla Update + FixedUpdate en un platformer (y con cualquier personaje) es la siguiente (seguramente hay cosas que no definí, solo una idea muy por arriba): // inputs - esto expandilo a todas las inputs que estás esperando, lo mismo con ejes // En este ejemplo está solo correr "Run" (que elegí la leftShift) bool runPressed = false; bool runReleased = false; bool running = false; bool isGrounded = false; void Update() { // Update puede pasar 100 veces más rápido que FixedUpdate (50 fps por default), así que // todos los KeyDown se acumulan, no se setean, así no perdés ninguno en el camino // por acumular me refiero a usar una simple OR runPressed |= Input.GetKeyDown( KeyCode.LeftShift ); runReleased |= Input.GetKeyUp ( KeyCode.LeftShift ); } void FixedUpdate() { //Detectar suelo, determinar direcciones de movimiento, ángulos, etc // Por supuesto acá es donde decís "suelo = true o false" isGrounded = IsGrounded(); // el vector objetivo cuadro a cuadro, no necesariamente el aplicado Vector2 targetVelocity = Vector2.Zero; // bien general un "if( suelo ) .... if( isGrounded ) { //Todo lo que pasa si y solo si el jugador está grounded // en este caso la input a evaluar es run así que if( runPressed ) { running = true; targetVelocity.x = ... } else if( runReleased ) { running = false; targetVelocity.x = ... } } else //Todo lo que pasa si y solo si el jugador NO está grounded { //en el aire no puede correr running = false; targetVelocity.y = ... } //Una vez determinado el estado se aplica el vector obtenido a la velocidad (de la forma que quieras). rb.velocity = ...(dependiendo de targetVelocity) // IMPORTANTE --> Resetear inputs, FixedUpdate ya las usó runPressed = false; runReleased = false; } Animación y movimiento poco tienen que ver, si no ves los efectos en pantalla tratá de exagerar los valores, en vez de 1.25f poné 5f. Igualmente creo que sí, desde el animator podés setear la velocidad del clip (revisá las referencias de Animator o google más rápido), aunque no recuerdo, estoy completamente seguro que para el sistema Legacy (viejo) se puede hacer, pero con el componente Animation. Saludos
  48. 3 points
    Efectivamente, ahora mismo eso no es posible con clases C# serializadas, pero la buena noticia es que a partir de Unity 2019.3 lo va a ser gracias a un nuevo atributo llamado SerializeReference. Esto es algo que los que desarrollamos herramientas llevábamos AÑOS esperando que Unity implementase, así que hay cierta expectación con el tema. Más información aquí: https://forum.unity.com/threads/serializereference-attribute.678868/
  49. 3 points
    Os presento mi 2º (segundo) juego: "area51invasion" Link al juego: https://play.google.com/store/apps/developer?id=Raven+Games+Spain Consiste en aplastar a los invasores para que no roben a los aliens del área 51. Partidas de 15 segundos. La gente no saca más de 30-40 puntos. ¿Cuál es vuestro récord? Extras Hecho desde cero en 9 horas. 8 horas fueron en el apartado gráfico.
  50. 3 points
    ¡Buenas! Me estoy planteando dar una pequeña charla introductoria sobre narrativa procedimental y generación de tramas argumentales en videojuegos, y me preguntaba si existe un interés general por ello. la charla entraría sobretodo en el ámbito de aplicaciones de la IA en el desarrollo de videojuegos y sería un poco hablar de como se encuentra el estado actual y cuales son las soluciones y algoritmos más utilizados para ello. Muchas gracias y espero vuestro feedback!!
UnitySpain © Todos los derechos reservados 2020
×
×
  • Create New...