Jump to content

Blogs

Our community blogs

  1. Diseño, Producción y Publicación.

    justin_worthe_game_image1@2x.png

    Enfrentarnos a estos tres principales pilares del desarrollo muchas veces nos genera incertidumbre, la falta de experiencia nos puede llevar al fracaso y en muchos casos no somos capaces de finalizar esas ideas que tenemos en la cabeza, la razón de este blog viene debido a la consulta realizada por @nomoregames y visto que es un problema recurrente me gustaría compartir con base en mi experiencia.

    Lo más importante es conocer y entender los tres principales pilares. 

    • Diseño: en esta etapa vamos a encargarnos de plasmar todas nuestras ideas, funcionalidades, tecnologías y referencias. No es importante que a la primera el documento quede perfecto, esta etapa lleva mucho tiempo de ajuste y reestructurar, es vital dedicarle el tiempo suficiente, días o semanas para que el documento nos sirva de mapa para la siguiente etapa. 
    • Producción: esta etapa se puede dividir en dos, planificación y ejecución, como todo en la vida, lo más importante es planificar, especificar los recursos necesarios. La ejecución es el trabajo de ir tomando completando de forma secuencial las tareas planificada, sabiendo que nos llevaran a buen puerto.
    • Publicación: la publicación es una de las fases más controversiales, llegar a este punto presenta un gran desafío, debido a este esfuerzo acompañado de frustración y auto superación, al llegar a este punto la ansiedad nos hace cometer graves errores. La publicación del proyecto debe ser premeditada, diseñada y planificada (déjà vu) para lograr captar la atención de los consumidores, para esta etapa es importante captar la esencia del juego, demostrar el potencial y hacer sentir que el consumidor necesita probarlo. En esta etapa es importante buscar información sobre marketing, ventas de productos digitales, etc. 

    Ahora hablaremos un poco más a detalle de como se lleva a cabo lo antes comentado para el desarrollo de videojuegos. Todo empieza desde la experiencia de explorar una idea en nuestra cabeza, en esta etapa está bueno ir escribiendo todo lo que se nos ocurre (no pensar en la implementación), compartirlo con otras personas e ir apuntando sus respuestas/reacciones, a esto se lo conoce como "tormenta de ideas" recomiendo por experiencia que este proceso lo realices sin prisa, intenta ir de a poco, puedes empezar ahora mismo y dedicarle un ratito cada vez que te sientas inspirado, esto no es algo que se realice con un tiempo preestablecido. Verás que con el tiempo la idea principal fue mutando tanto, que puede hasta perder su personalidad, en este punto existen dos alternativas, eliminar todo y empezar nuevamente o seguir adelante con el diseño.

    Para el diseño siempre se habla del GDD pero muchos se preguntan ¿cuál es su estructura?. GDD es un documento que consta de varias partes, dependiendo de la complejidad del proyecto, si bien es algo muy comentado, las grandes empresas siguen otro patrón de diseño algo que para desarrolladores independientes sería impensable, comentando esto se puede decir que el GDD se interpreta como un resumen del juego, tecnología y características, para entender esto más a fondo dejaré de ejemplo los siguientes GDD DIABLO 1  |  GTA. Lo importante del GDD es que se conserve la idea inicial de forma intacta y explique de forma resumida que aspecto lo hace único, que se entienda en principio que este documento sirve como referencia, y a la misma vez para promocionar su desarrollo.

    Como somos independientes no nos basta solo con tener la idea y el diseño, también queremos producirlo. En este punto tenemos que tener mucho cuidado, intentaré describir las señales que puedes interpretar como un fracaso asegurado, pero antes, me gustaría darte una idea del primer paso de la planificación.

    1. Recursos visuales: deberías especificar y detallar los recursos visuales que serán utilizados para lograr el núcleo del juego, esto puede ser, el personaje principal y los secundarios, elementos claves del entorno, elementos requeridos para el gameplay, en este punto evitar pensar en usar "cajas" para remplazar algún modelo del juego, para esta tarea es indispensable buscar referencia, identificar el estilo artístico y otras características sobre las cuales deberían basarse los modeladores y/o diseñadores gráficos.  
    2. Recursos sonoros: deberías buscar múltiples referencia y explicar en forma de Storyboard como se usaría, esto ayuda mucho a la hora de crear conceptos. Esta tarea también se puede realizar a lo último, haciendo pruebas con material ya existente como referencia. 
    3. Diseñadores de Niveles: dependiendo de si el proyecto lo requiera a o no, es importante contar con la planificación de que papel tendrá cada escenario, las mecánicas que se implementarán, el tiempo que el jugador deberá permanecer de forma promedio, esto ayuda al diseñador de niveles poder balancear mecánicas y detalles.
    4. Diseñadores de Mecánica: dependiendo de si el proyecto lo requiera, tener una persona dedicada a explotar las mecánicas del juego siempre es una gran idea. Para esta tarea no es necesario que la sepa programar.
    5. Con lo anterior es importante definir un objetivo como prototipo, esto puede ser el desarrollo de las mecánicas principales.

    ¿Por qué no hable de programación?, en UnitySpain prevalecen los programadores, muchos aún están empezando a aprender y desconocen la magnitud de llevar a cabo un proyecto. La programación es solo una parte de lo que realmente es el producto finalizado, por esta razón decidí dejar este aspecto para profundizar en otra entrega.

    "Las señales del fracaso"

    Si crees que es imposible cumplir con algún punto de lo anteriormente comentado entonces estas en graves problemas, te recomendaría no continuar con la producción, es importante conocer nuestras limitaciones y crear proyectos acordes a nuestras habilidades, también se aplica para cuando estamos dentro de un equipo y las tareas que nos asignan nos terminan abrumando.

     

     - Si les interesa este contenido y quieren saber más sobre algún punto en concreto sepan que estaré pendiente a los comentarios…

     

    - Pequeña aclaración -
    Este blog fue escrito con la intención de introducir algunos vagos conceptos, es una percepción personal basada en mi experiencia, intentaré explicar más a fondo los conceptos que generen incertidumbre. 

  2. UnitySpain - Colaboraciones

    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). 

    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:

    M1L9VqzMRWDYZacxPEmeey6mwS9rDwH1h-GJfD4E

    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:

    hs2dKwNHFZgymUppDNs-zDX6Y8yb8_8V5oqNN6Vx

    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:

    XPHElPEFH1HNkSePMj1yk4jiQEmdmTKitKi6Niad

    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:

    QeR1NhQLBA3iwqnT5NcWMqNSahb9ejUWHUMQlqkt

    Recuerda que puedes cambiar el icono en la siguiente pestaña: 

    ME56yK6_HW-JLdhJnBDdjRAf9kaUTLzmn0u6D7Bh

    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. 

    oUiZCg6fIuPQ5gX6wmzk7Z8NAhMxulnmeXc5sl7T
    bm0pFzFLfM_WrU1_UDsI_dHgjEkA0hLLFaqEzvxh

    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: 

    tZXYFBPSEAz2CLkMPYoe_3Q-JhmmBjI59X_Y7ro3

    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: 

    4EvFvJN7k8Vzy-20U0EcbYyI2KYta2tXnVncQva8

    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?

    image.png

    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. 

    FbYY9o1UhilgTDmS8rGclats0iNNgOcuU-qryeDB

    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:

    ldqOdhJPDew-vNt6v9dzhnjkRPDLnvdBqKMhCPkv

    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: 

    3-d7fYSFp7eb6GAWfYaC3P4VTcnHtWYvoRWU9N8n

    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:

    scQ6-vUAISMlJpHrCdssSjS2ziguBkENBx45InGv
    rHuVSxvRuym9h8zt9F3Ef8X4ZU0OYE6aj2QIrQtw

    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:

    image-1.png

    Podemos implementar rápidamente esto en nuestra clase BasicMath:

    aw8LluoZkWsOSOIsN-qqc0zq081MIqLnhMs-94fe

    Podemos ver que equivale al valor normalized de la clase Vector:

    3Nime0QWw9F_u5piUM-GraW7HiNJfinwrg8gF3BW

    Una vez tenemos el valor normalizado, podemos multiplicarlo por un valor y hacer que el personaje se mueva en función del tiempo:

    7Snu2CpuYttF3G0DfWpbDGHYmWKtW77q-opjAUX8

    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. 

    YjBfutvJFLIUgoIrUN5LwVDpKU4Kw7-LVfvT24gt

    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: 

    l0BqolIglJ_FCbCbCPR_GyzJin9dTIyE_IZd1G0m

    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:

    LjjH8PN5k2uWl02CLbyJH4NXULog7Tn67aIaNgiL

    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. 

    qD3L-vY53LpHckiBiWKyNMf_W5_CjN5xpjitUJno

    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. 

    0Jly3a9bmx9YhtwjfoUTtsq97yK4_hnv5O3YGL34

    Ahora añadimos la función Dot de testeo con lo siguiente:

    vcOkgvZZe--8LeJxdcxnXZRRosx1uK-GstY4WXRC

    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í:

    30amAujwZwTfPCw_H_cn1YhJDqJRlEbXnURGt_No

    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). 

    V3AzenPvHoeA47hPtOj_pLccskaSSnKdiAyDnFwz

    Si damos Play podemos ir moviendo el target y ver como va cambiando el producto escalar. 

    AVz1IQI4OCmIYxOrApCNVbBtLPXAcbj-hX0LNvP6

    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. 

    RYfpMZ2DeB5qQ7h2blFWdNJFqmPRaDU_yHgInjAQ

    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:

    cfYEuh57KHsZnDJVA8nGcoSRelZNls0OZCHe4hhW

    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). 

    8bZmI3U8c6dc0RwDHMkfFvCHw73BskEkR1prafxa

    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.

    68yokUoxLf4mqalto6aSe3fk_H-hbucrqpJRRWKW

    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:

    a1SstPX-BAAogpsi6JIHBIoxA6knwEu17qe-S56a

    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.

×
×
  • Create New...