Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 06/15/2020 in all areas

  1. 4 points
    Finalmente, liberamos la herramienta! pueden acceder a ella totalmente gratis! http://www.modelatorsystem.com
  2. 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?
  3. 2 points
    Hola Cerpion, Lo primero: No es terrible hacer referencia a otros scripts, pero en un mundo ideal, generalmente es preferible hacer referencias a abstracciones de tus scripts. Esto nos permite que sea más fácil reutilizar y cambiar nuestro código en un futuro. Ahorita me explico más: Supón que tienes un script llamado Player, y un script llamado Joystick, que a su vez tiene un método llamado GetMovement. Algo así: public class Player:MonoBehaviour { //Esta es una manera de obtener la referencia, aquí aparecería un campo para asignar el Joystick en el inspector: public Joystick playerJoystick; //La otra manera sería: private void Start() { playerJoystick = GetComponent<Joystick>(); } } public class Joystick:MonoBehaviour() { public Vector2 GetMovement() { //Supón que aquí regresaramos un movimiento de verdad en lugar de ceros. return new Vector2(0,0); } } Y eso funciona en general. Pero en un futuro tal vez vayas a querer tener players controlados por la computadora, o diferentes scripts para diferentes tipos de control, o qué sé yo que te depare el futuro. Para estar preparado para el futuro, y que te sea más fácil agregar y cambiar cosas, es mejor que nuestras referencias sean más abstractas, que Player en lugar de referirse a un Joystick haga referencia a, por ponerle un nombre, un MovementProvider. Hay dos formas de hacerlo. Una es con clases abstractas: public class Player:MonoBehaviour { //En lugar del Joystick, hacemos referencia a un MovementProvider, que puede ser un Joystick, pero también otra cosa que se te ocurra. public MovementProvider playerMovement; private void Update() { //Aquí usarías el vector que regresa GetMovement de para mover tu jugador alguna manera playerMovement.GetMovement(); } } //La palabra abstract aquí significa que el script no puede ser usado por sí solo, necesita que otro clase herede de ésta para usarlo. public abstract class MovementProvider:MonoBehaviour { //La palabra abstract aquí significa la funcionalidad de este método debe ser definida en las clases que hereden de ésta. public abstract Vector2 GetMovement(); } //Nota como no heredamos de MonoBehaviour esta vez, sino de la clase abstracta MovementProvider. //Cualquier otro script puede hacer lo mismo y definir su propia función para GetMovement public class Joystick:MovementProvider { //Override significa que estamos sobrescribiendo la funcionalidad definida en el padre, en este caso en MovementProvider. //Es cierto que, de hecho, MovementProvider no definió ninguna funcionalidad, lo dejó abstracto, pero igual hay que ponerlo. public override Vector2 GetMovement() { return new Vector2(0,0); } } Y dos es con algo llamado interfaces: public class Player:MonoBehaviour { public IMovementProvider playerMovement; private void Start() { //Como no podemos obtener la referencia a IMovementProvider desde el inspector, hay que obtenerla de otra manera. Puede ser así: playerMovement = GetComponent<IMovementProvider>(); //Si el componente está en otro GameObject, podríamos poner un campo de tipo GameObject en el inspector y luego: playerMovement = otherGameObject.GetComponent<IMovementProvider>(); } private void Update() { //Aquí usarías el vector que regresa GetMovement de para mover tu jugador alguna manera playerMovement.GetMovement(); } } //Las interfaces definen un conjunto de métodos y propiedades que debe implementar una clase. //La ventaja de las interfaces es que puede aplicarse más de una a la misma clase, la desventaja es que no salen en el inspector. //Es común poner una I en el nombre para identificar que es una interfaz. public interface IMovementProvider { Vector2 GetMovement(); } //Nota como avisamos que implementamos la interfaz. Si hay más interfaces, se pueden seguir agregando separadas por comas. public class Joystick:MonoBehaviour, IMovementProvider { //Con las interfaces no tenemos que usar override, basta que el método sea público. public Vector2 GetMovement() { return new Vector2(0,0); } } Respecto a tu segundo punto, generalmente, entre más puedas dividir tus scripts, mejor. La idea es que, entre menos cosas distintas haga un script, más probable es que los puedas reutilizar en varias partes diferentes. Y es menos probable que los tengas que modificar cuando otra cosa cambie en tu código. Cualquier cosa que quede sin explicarse bien, o cualquier duda, tú dime con confianza. Ahm, espero no haber sido demasiado teórico o demasiado confuso; esto de lo que hablé viene de unos principios de programación llamados SOLID, que son muy útiles como guía para facilitarte la vida, pero que luego uno no sabe explicarlos bien porque ya se acostumbró tanto que ya ni piensa en ellos. Por último, estas recomendaciones que te di, no dejes que te atoren mucho; se aprende haciendo y además, en esto de hacer juegos, todo mundo acaba haciendo montón de excepciones a este tipo de reglas. PD Eso del game manager y las referencias estáticas yo realmente te recomendaría evitarlo siempre que puedas. Hay razones para hacerlo, como si nomás es un prototipo rápido, o un juego móvil simple, o ciertas cosas que es mucho más complejo hacer de otra forma. Pero, generalmente, ese patrón de organizar tu código que algunos llaman singleton, acaba dándote muchos más problemas de los que arregla. En el momento en el que decides, por ejemplo, que tu juego es multijugador, tienes que ponerte a rescribir código en todos los lados que usan esa referencia estática, en código que escribiste hace mucho tiempo y que vas a tener que releer completito para entender cómo cambiarlo.
  4. 2 points
    Vale muchas gracias. Si, soy noob pero estoy aprendiendo mucho y me ayuda a desconectar de mis problemas 🥰
  5. 2 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.
  6. 2 points
    Hola developers, les traigo un tutorial explicando las corrutinas #1. Primero una explicación de como funcionan y luego ejemplos prácticos de como podemos implementarlas: Saludos! www.gamebelieve.com.ar
  7. 2 points
    Github es un repositorio online, no es una web de descarga como mega. Su función principal es el manejo de versiones, la idea de tener alojado un proyecto en un repositorio es poder trabajar conjuntamente con otras personas sin influir en su trabajo ni ellos en el tuyo. Otra utilidad es alojar proyectos en desarrollo, y a medida que lo actualizas las personas que tienen clonado el repositorio pueden también actualizarlo. Por ejemplo, yo tengo un servidor privado de GIT (no GitHub) llamado bonobo en una rasperry pi conectada 24/7, a su vez tengo PC y mac, y mi hermano (el cual es mi compañero de equipo, yo programo y el hace todo el arte) tiene PC y Portátil, tenemos en todas las computadoras el proyecto. Cuando yo trabajo hago un comit (se suben SOLO los archivos que se han modificado) y así mantenemos el proyecto actualizado en todos los dispositivos. Esto permite que el trabaje en su campo y yo en el mío, y los archivos nunca van a entrar en conflicto. Mi consejo es que no uses GitHub para proyectos de Unity, cuando se suben más de X mb en un solo commit te da problemas, y cuando el proyecto supera los 5gb te obligan a pagar la suscripción. Lo que si aconsejo es utilizar su software Github Desktop (es para manejar todo el repositorio en un programa, sin necesidad de comandos), es muy bueno, simple y sirve con cualquier sistema GIT. Mi otro consejo es que te hagas el repositorio tú, creando un servidor web local (en mi caso como ya dije lo tengo un una rasperry pi) pero también puedes hacerlo en tu PC instalando los paquetes de windows IIS. Una vez instalado descarga el servidor Bonobo, lo instalas en la carpeta del servidor web y ya tendrías tu repositorio online privado. Como mencioné anteriormente, utiliza el software de GitHub desktop, es realmente cómodo e intuitivo y te permite trabajar con bonobo, además a la hora de crear nuevos repositorios puedes seleccionar por defecto un .gitignore de Unity que lo que hace es ignorar los archivos que genera el Unity por defecto, así evitas subir archivos que te hacen más pesado el proyecto. Si necesitan más ayuda con esto puedo crear un tópic y explicarlo o un vídeo de YT. ¡Un saludo!
  8. 2 points
    😳 por favor, que alguien expulse a este señor de la comunidad 😂 yo tambien creo que una de las partes mas satisfactorias de la programacion es el solucionar problemas, el buscar la solucion, ...no buscarla en internet, sino comerte la cabeza y encontrar tu propia solucion... y darle al "play" y ver que funciona.... eso es lo mejor que hay. pero por otra parte tambien quiero terminar algo, para demostrarme a mi mismo que puedo terminarlo... aunque mientras vas avanzandolo (el proyecto) te va pareciendo cada vez menos atractivo... te va pareciendo muy pobre, con un arte bastante cutre.... y se te van quitando las ganas de continuarlo... pero aun asi voy a intentar acabarlos y publicarlos.... aunque sea gratis. es por ejemplo lo que me pasa con mi juego de naves 2d (star crash, hay un post en "proyectos") ...al principio lo empeze como un proyecto para crear mi propio "pathFinding" (que funcion muy bien, porcierto) hice un mapa que se generase proceduralmente (con cubos) y enemigos que patruyaban y si te veian te podian perseguir y buscar por el mapa... luego me puse a hacer que disparasen y les meti una imagenes de naves.... y dije: "ah, pues este juego puede estar guai asi, siendo una especie de shootem'up con exploracion y tal".... y segui avanzandolo, meti un monton de escenarios distintos (procedurales) meti skills y un menu donde conseguirlas y mejorarlas... hice mogollon de enemigos diferentes.... y parecia medio guai el juego... pero poco a poco me parecia que el aspecto grafico era bastante simplon... o que no tenia el suficiente atractivo.... pero como ya lo tenia muy avanzado pues dije: "venga, este hay que acabarlo" menu principal, sistema de guardar y cargar, un pequeño tutorial... pequeñas mejoras graficas... pero cada vez me parece mas soso... ademas a temporadas hago este y a temporadas hago otros... como tengo varios a medias pues puedo ir cambiando y asi no me "saturo" todo el rato con el mismo... .... y al final no se que queria decir... pero si... completar un proyecto se puede hacer largo, arduo, y desmotivador.... sobretodo si ves que no es muy bueno... o si lo comparas con juegos de exito (cosa que es un error) pero creo que el mero hecho de terminar un juego completo ya es en si un exito. por eso quiero empezar a acabar algunos proyectos. y valla parrafada mas larga he soltado...
  9. 2 points
    Hola, tuve que lidiar con esto recientemente. Andá a los clips de animación importados, y modificá el offset del Root Transform Position (Y). Si tu personaje ya está animado y modifica alguna propiedad de su root bone (por ej al hacer un salto), podés forzar que el cambio sea nulo (altura, plano XZ o rotación) con solo poner Bake into pose. Por ej, si aplicás esto a la posición Y, la altura del root será 0 (además podés seleccionar qué referencia usar).
  10. 2 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.
  11. 1 point
    Muchas gracias por la ayuda, demoré en entender el código, aun me falta mucho por aprender. Este tipo de programación tiene un nombre en concreto?
  12. 1 point
    Tutorial Modelado 3D Hola amigos de unity, les comparto uno de mis tutoriales , para convertir una imagen a un modelo 3d, es un tutorial de eso modelado 3d, también aprovechar para invitarlos a mi canal para más tutoriales, gracias. Si desean les comparto el modelo final también en fbx para el unity, bueno sin más nos vemos pronto.
  13. 1 point
    Buenas tardes, os comento mi problema, que llevo bastantes días intentando resolverlo y no hay forma... Estoy creando personajes y animaciones con Blender, utilizando rigify, y luego los exporto a Unity. A priori, una vez exportados, no aparecen problemas con el rig y todo parece correcto. Pero el problema surge una vez que meto las animaciones y el personaje en el Character Controller, el personaje se despega del suelo y se sitúa a varios metros de altura del suelo, y después con las animaciones ya se acaba de descontrolar....va dando botes y cambiando de altura. Para probar, utilice también algunos personajes de mixamo, poniéndoles mis propias animaciones, y funcionan perfectamente. Parece que el problema sólo surge con mis personajes, y no parece que este en el rig, porque si funciona con esos otros personajes... No doy con el problema, no sé si esta en algo que importó mal a unity o qué... Muchas gracias de antemano! Un saludo!
  14. 1 point
    hola se puede hacer de muchas maneras, esta es una: //esta funcion te devuelve un punto(vector3) dentro de un circulo (horizontal) //dalndole el centro del circulo=circlePos (vector3), y el radio del circulo=circleRad (float) Vector3 randomPointInsideCircle(Vector3 circlePos, float circleRad) { float ang = Random.Range(0f, 360f); //un angulo aleatorio entr 0 y 360 ang *= Mathf.Deg2Rad;// convertie el angulo en radianes (seno y coseno de unity funciona en radianes) Vertor3 pos = new Vector3(Mathf.Sin(ang), 0, mathf.Cos(ang));//crear un vector de la direccion del angulo float length = Random.Range(0f, circleRad); //un valor aleatorio entre cero y el radio del circulo pos *= length; //hacer que el vector mida esa longitud aleatoria pos += circlePos; //sumar la posicion del centro del circulo para que el punto este "alrededor" suya return pos; //devolver la posicion } esta es otra: Vector3 randomPointInsideCircle(Vector3 circlePos, float circleRad) { Vertor3 pos = new Vector3(Random.Range(-1f, 1f), 0, Random.Range(-1f, 1f)); //crear un vector aleatorio (-1/+1, 0, -1+1) pos.Normalize(); //hacer que el vector mida 1. (apunte hacia donde apunte) float length = Random.Range(0f, circleRad); //un valor aleatorio entre cero y el radio del circulo pos *= length; //hacer que el vector mida esa longitud aleatoria. (esto funciona porque antes media 1) pos += circlePos; //sumar la posicion del centro del circulo para que el punto este "alrededor" suya return pos; //devolver la posicion }
  15. 1 point
    Hola chicos necesito ayuda: Cómo hago para que mi personaje deje de moverse mientras realiza el ataque? Este es mi código: el trigger de atacar se llama "Ataque" y la animación de atacar se llama "Atacar" public class MiClase : MonoBehaviour { Animator anim; Rigidbody2D rb; public float fuerzaSalto; public bool enSuelo; public Transform refPie; public float velX = 10f; CircleCollider2D attackCollider; void Start () { anim = GetComponent<Animator> (); rb = GetComponent<Rigidbody2D> (); attackCollider = transform.GetChild (0).GetComponent<CircleCollider2D> (); attackCollider.enabled = false; } void Update () { float movX; movX = Input.GetAxis ("Horizontal"); anim.SetFloat ("absMovX", Mathf.Abs (movX)); rb.velocity = new Vector2 (velX * movX, rb.velocity.y); enSuelo = Physics2D.OverlapCircle (refPie.position, 1f, 1 << 8); anim.SetBool ("enSuelo", enSuelo); if (Input.GetButtonDown ("Jump") && enSuelo) { rb.AddForce (new Vector2 (0, fuerzaSalto), ForceMode2D.Impulse); } AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo (0); bool Ataque = stateInfo.IsName ("Atacar"); if (Input.GetKeyDown ("f") && !Ataque) { anim.SetTrigger ("Ataque"); } { } if (movX < 0) transform.localScale = new Vector3 (-5, 5, 1); if (movX > 0) transform.localScale = new Vector3 (5, 5, 1); { Camera.main.transform.position = new Vector3 (transform.position.x, 0, -20); } } }
  16. 1 point
  17. 1 point
  18. 1 point
    Noooo, no era mi intención ofenderte, en serio. No estoy juzgándote, ni diciendo que todo sea imaginación tuya ni nada por el estilo. Se dé primera mano, la poca importancia que se le dan a los trastornos mentales... viví toda la infancia siendo el "tonto" el que no se entera. Con el tiempo, se dieron cuenta de que esa "tontería", no era ni más ni menos que un trastorno mental. Ante el desconocimiento de los demás, ante su negativa a entender que me costara más entender lo que ellos comprendían tan fácilmente siempre ponía el mismo ejemplo: tú a un cojo no le dirás que se ponga a correr, ese cojo puede llegar perfectamente a los mismos objetivos que el "normal", solo que a su tiempo y modo... pues lo mismo con el TDAH. No es bueno, para nada, ir gritándolo... no todo el mundo es capaz de comprender esas dificultades, y se alejan de ti como si apestaras... por eso es mucho mejor no ir diciéndoselo a todo el mundo... ese es un consejo. Y te aseguro, que de enfermedades mentales... sé un rato XD... he pasado por más psicólogos que el demente que ideó el hobbit. Dicho esto, pido disculpas si te he ofendido... solo pretendía compartir mi experiencia... si quieres que lo hablamos mejor, te mando mi Gmail y lo hablamos en privado... en serio que no quería menospreciarte
  19. 1 point
    hola creo que lo que dice @nomoregames es que poner una enfermedad como excusa es algo contraproducente para ti mismo.... si te excusas diciendo que no puedes porque tienes tal enfermedad pues entonces tu mismo te estas poniendo trabas a ti mismo.... ...porque entonces, como tienes tal enfermedad, para que hacer nada.... con esto no quiero menospreciar tu enfermedad.... sino que quiero decir que no deves dejar que la enfermedad te diga lo que puedes y lo que no... que la enfermedad decida por ti... pero si incluso he visto en internet un señor sin brazos que toca la guitarra... sin brazos!!! y la toca mejor que yo!!!.. que me pegue tocando en un grupo (amateur) 8 años... bueno.... si te he parecido un "borde" lo siento... en esta pagina estamos para ayudar y para aprender. no dejes que te asustemos.... que aqui somos todos buena gente.... y no te des por vencido con la programacion.... cuesta.... pero cuando vas aprendiendo es muy satisfactorio... si sigues sin conseguir que funcione lo que quieres haces pues comentanos... y si tienes cualquier otra duda pues lo mismo.... habres un nuevo post en la categoria que corresponda, y estaremos encantados de contestar. PD. si vas a "postear" codigo hay arriba (del editor donde escribes el post) hay un simbolo asi "<>" con ese boton abres un panel de texto donde puedes pegar tu codigo.... y abajo de ese panel hay un menu desplegable donde puedes elegir "C" como lenguaje que estas usando.... y asi el codigo queda como el que te ha posteado @nomoregames un saludo y sigue dandole!
  20. 1 point
    Buenas @Flauros, yo también tengo TDA (sin la h) y: depresión, insomnio, ansiedad social, dislexia, migraña y una tontería encima de las que asustan.... Con esto quiero decir, que eso no tiene por que ser un problema, yo yebo un año en unity, apenas se nada, y todavía no me he rendido... me cuesta, pero no me he rendido. Que tengas tdha no significa nada... y te digo (por experiencia propia), que abanderarse con un (TENGO TDAH) solo ayudara a auto limitarte. Tu no eres tu enfermedad, tu eres tu, y como tu eres tu, de ti depende entender o no las cosas, eso si, a tu ritmo. Dicho esto (que espero te aya resultado algo inspirador), me he explicado como el mismísimo culo, así que aquí va mi pseudo masterclass Sustituye tu código por el siguiente public class MiClase : MonoBehaviour { Animator anim; Rigidbody2D rb; public float fuerzaSalto; public bool enSuelo; bool underAttack = false; //añadido public Transform refPie; public float velX = 10f; CircleCollider2D attackCollider; void Start () { anim = GetComponent<Animator> (); rb = GetComponent<Rigidbody2D> (); attackCollider = transform.GetChild (0) .GetComponent<CircleCollider2D> (); attackCollider.enabled = false; } public void OnAttack () { underAttack = true; } public void NotAttacking () { underAttack = false; } void Update () { float movX; movX = Input.GetAxis ("Horizontal"); anim.SetFloat ("absMovX", Mathf.Abs (movX)); rb.velocity = new Vector2 (velX * movX, rb.velocity.y); enSuelo = Physics2D.OverlapCircle (refPie.position, 1f, 1 << 8); // cuando el pie está cerca del suelo anim.SetBool ("enSuelo", enSuelo); if (Input.GetButtonDown ("Jump") && enSuelo) { rb.AddForce (new Vector2 (0, fuerzaSalto), ForceMode2D.Impulse); } AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo (0); bool Ataque = stateInfo.IsName ("Atacar"); //animacion de ataque if (Input.GetKeyDown ("f") && !Ataque) { if (underAttack == false) anim.SetTrigger ("Ataque"); } //girarse if (movX < 0) transform.localScale = new Vector3 (-5, 5, 1); if (movX > 0) transform.localScale = new Vector3 (5, 5, 1); //camara { Camera.main.transform.position = new Vector3 (transform.position.x, 0, -20); } } } Luego en la animación de ataque, nada mas iniciar, pones lo siguiente te aparecerá lo siguiente en el inspector Seleccionas la función OnAttack(), luego, al final de la animación de ataque haces lo mismo, solo que esta vez seleccionas NotAttacking().. y ala, a disfrutar Luego ya te explico mejor para que es cada cosa, pero ahora no tengo tiempo Suerte!
  21. 1 point
    hola primero esta comprobando que "enSuelo" sea "true".... y dentro de esa comprobacion tienes otra donde compruebas que "enSuelo" sea false? creo que por ahi va el error.. creo que esa segunda comprobacion deveria ir fuera... y entonces deverias comprobar tambien en esa que se este pulsando el boton saltar.... y entomces dentro de esa comprobacion tendrias que aplicar lo mismo que dentro de la otra: fuerza de salto... sonido...
  22. 1 point
    bua, tranki.... errores de esos mil.... lo chungo es cuando llevas nosecuantas horas buscando el error y de repente te das cuenta que es una tonteria asi.... la cara de tonto que se me queda es peor que la de Tobey Maguire en su papel de Peter Parker hablando con Mary Jane en la primera peli de Spiderman
  23. 1 point
    la verdad que hay proyectos muy buenos en esta nuestra comunidad... ...no se que hace el mio entre ellos ...en el primer video. 😅
  24. 1 point
  25. 1 point
    Buenas @Igor El problema de usar unity colaborate es la limitación que presenta en cuanto a la cantidad de personas que pueden trabajar en un mismo proyecto (que son 3)
  26. 1 point
  27. 1 point
  28. 1 point
    Hacé un tatetí y presentalo, luego un tetris y presentalo, luego X y presentalo, te vas a dar cuenta que esas preguntas son producto de la falta de resultados. Y ojo que yo soy el peor en dar este consejo, estoy igual que vos, terminé con varios proyectos en la nada, pero un poco intencionalmente, nunca prentendí terminar nada. Más bien lo hice para chocarme con los problemas del desarrollo, esto siempre me interesó más que el juego en sí, incluso te diría que me aburre un poco la parte de desarrollo de juegos.
  29. 1 point
    Me uno a este tema puesto que me siento representado en todos los sentidos, estas viendo la tele o realizando otra actividad y de pronto te viene a tu cabeza una idea, (general casi siempre) la cual vas puliendo días tras días mientras haces las tareas o obligaciones diarias. Las mecánicas, tema, la forma de de todo y como funcionaria. Básicamente piensas en ello en todos lados. ¿pero esto como funciona?..... ahh de tal manera y tal. Empiezas el proyecto y sueles dedicar todas las horas que puedes. Poco a poco te vas desmoralizando, irritando y desmotivando viendo simplemente como una mecánica no es todo lo fluida que esperas, o algunos problemas (el PJ no mira en la dirección correcta mientras hace tal animación), vamos problemones. Lo vas dejando y mosqueando con el proyecto mientras le insultas, eso solo es mi caso, y básicamente lo dejas. Yo siempre me quedo con todo lo aprendido y que para el próximo proyecto se solucionar esos problemas. Pero no los termino estoy al 60 o 70 en varios casos pero nada.
  30. 1 point
    Yo creo que la base de un proyecto es su organización. En muchos casos empezamos un proyecto que tenemos en nuestra cabeza y le ponemos todo el empeño, cuando estamos desarrollándolo nos damos cuenta que hay mecánicas que no funcionan como pensábamos o cosas que habíamos pasado por alto. Para solventar esto lo mejor es tener un entorno organizado, empezando por crear un buen GDD. Si estamos creando el proyecto entre varias personas crear un repositorio online, utilizar aplicaciones como Trello para la creación y administración de tareas. Algo que también considero muy importante es la administración de tu tiempo, en varias ocasiones me he encontrado desarrollando aplicaciones para mi empresa, estudiando para la universidad y haciendo X proyecto por mi cuenta, durmiendo muy pocas horas y dejando todo para el final. Esto causa que todo sea un caos, si te pones un horario y no te lo saltas verás como todo te sale más fácil y fluido. Por ejemplo, yo solo dedico 4 horas al dia a mis proyectos personales, y lo cumplo a raja tabla como si fuera un horario de trabajo, si te pasas de esas horas jodes todo el horario y empieza un efecto dominó. Otro tema importante es administrar tu productividad, utiliza un sistema de time tracking y corrige tus horarios y tareas con los datos generados. Y lo más importante es mentalizarte, mentalizarte de que tienes que terminarlo si o sí, no hay de otra. Estos son cosas que a mi me han funcionado, yo sé que hay mucha gente que trabaja distinto pero para mi esta es la forma de obligarme a terminar los proyectos. Un saludo y espero haberte ayudado. PD: me parece el mejor post que has hecho, es un tema que se habla muy poco y es una problemática muy grande entre los desarrolladores independientes.
  31. 1 point
    yo mirando a la pantalla yo aguantándome aguantad aguantad yo en el suelo muriéndome de la risa 🤣🤣😂 si fuera por mi ponía algo de tolkien, pero como dijo @lightbug, mandabais a un matón a mi casa. Jejeje. Bromas a parte: gracias, tomo nota de lo de apuntarlo en una pizarra, llega un punto en el que parece que no abalanzas nada por mucho que hagas y teniendo un soporte visual sobre el que basarse, se hace menos cuesta arriba.
  32. 1 point
    saludos joven padawan. yo tambien he comenzado miles de proyectos.... ahora estoy a punto de terminar uno... y tengo otros bastante avanzados... y creo que tambien los voy a terminar 😲 ...casi no me lo creo ni yo.... yo no tengo un metodo especifico de trabajo... voy haciendo cada dia un poco lo que me apetece.... y voy dejando lo que menos me apetece para el final... ahora estoy un poco en esa parte... haciendo cosas que no me apetecen pero hay que hacerlas... pero como tengo varios proyectos pues cuando me canso un poco pues cambio a otro proyecto... y luego a los dias vuelvo a seguir con lo que me falta... y sobre todo... utiliza la fuerza... es util ir apuntando en un cuaderno, hoja, pizarra o algun lado todas las pequeñas parte que tienes que ir haciendo (divididas en tareas muy pequeñas) de forma de que puedas ir tachandolas cuando las haces y asi ver tu avance... y tambien para qur puedas ir añadiendo tareas que se te vallan ocurriendo, o cosas en las que no havias caido, o nuevas caracteristicas que quieras añadir.... y asi tendras una vision mas global de como avanza el proyecto. a que deves dar prioridad? pues si lo que quieres es acabar un proyecto tu prioridad deve ser esa, acabarlo. "hazlo o no lo hagas, pero no lo intentes." -yoda. si te atascas no tengas miedo de preguntar, el miedo lleva a la ira, la ira lleva al odio, el odio lleva al sufrimiento, ...y que vende Darth Vader en su heladeria? exacto, helado oscuro. edit: no pongais cosas de star Wars que empiezo que si lado oscuro por aqui que si la fuerza por alla... y no me controlo
  33. 1 point
    Hola, abrí la previsualización, en las opciones de importación, si tocás el offset y el modelo sube o baja, entonces funciona. Eso seguramente pase porque se este ajustando la animación de un solo clip (o de algunos sí y de otros no), pero cuando el animator pase a usar el otro clip vuelva a la posición de este último. Osea, la posición del personaje es la misma (la del character controller, esta no cambia), pero si tenés diferencias entre las animaciones te van a aparecer inconsistencias. Por eso siempre es recomendable crear las animaciones respetando el pivot (puede haber excepciones, como el salto por ej) . Estas opciones te deberían dar la posibilidad de "re-calcular" dicho pivot, medirlo desde los pies, usar centro de masa, etc.
  34. 1 point
    No, funciona siempre, incluso para Generic también. Si usas o no root motion no influye en este caso, el clip se ve afectado por el offset siempre. Por ej, si vas a tener un personaje controlado por scripts (sin root motion), para idle, walk y jump (o similar) yo usaría un BakeIntoPose de posición Y basado en Feet. Te soluciona cualquier diferencia de altura automaticamente, haciendo root = posición entre pie izq y der. Si creaste el clip pensando en esto (como debería ser) podés usar Original también, debería dar el mismo resultado (o muy parecido).
  35. 1 point
    @francoe1 es ese modelo de la imagen tuyo? sea como fuere me ha sorprendido la genial idea de ponerle un hueso extra para las hombreras. lo usare de ahora en adelante (con personajes que lleben armaduras con hombreras o similar) gracias. te iba a dar un "like" pero no se puede dar a los administradores.... 😔 asi que te lo doy asi... todo para ti: ❤️
  36. 1 point
    Me ha gustado mucho la demo, faltan cosas por pulir pero pinta muy bien. El estilo artístico y la estética están geniales, las mecánicas de juego son tambien interesantes. Ánimo y mucho éxito. No soy muy de plataformas de habilidad, me van más juegos de aventura y exploración pero lo he apuntado en mi wishlist :).
  37. 1 point
    prueba a meter una capsula o cubo con las dimensiones de tu personage.... si el cubo o capsula tambien se "meten" en el suelo la culpa NO es de la animacion si no de las fisicas... en ese caso deveras explicar como haces laa fisicas del salto y la deteccion del suelo.... usas rigidbody, ....character controller... o lo haces con vectores para el movimiento y raycast para la deteccion.... yo suelo hacerlo siempre de la ultima manera calculando yo el movimiento y la colision... asi tienes mucho mas control sobre lo que quieres que pase. si no es culpa de las physics.... si el cubo o capsula no se meten en el suelo pero el personaje si... entonces es por la animacion... tendras que modificarla un poco.... es mejor que cuando hagas una animacion de personaje (en tu programa de modelado/animacion) el personaje se mantenga siempre centrado, (en el 0, 0, 0) ...que corra, salte, ataque sin moverse del sitio
  38. 1 point
    Excelente el efecto, seguramente sean unos 500 hinge joints. A quién le importa la optimización, estamos en 2020, eso se arregla con más Hardware 😅. Me enteré por este hilo que salió el "The last of us 2" y me sorprendió como en los relacionados de Youtube me aparecían "Esto es tan malo que ni puedo terminarlo" o "esto es basura", o similar. Me fui a metacritic y noté que tiene un 40/100 😮 (de usuarios, obviamente).
  39. 1 point
    Mirá los métodos públicos: https://docs.unity3d.com/ScriptReference/Animator.html Play Plays a state. PlayInFixedTime Plays a state. CrossFade Creates a crossfade from the current state to any other state using normalized times. CrossFadeInFixedTime Creates a crossfade from the current state to any other state using times in seconds. Si te sirve el "Animation" dale pa' lante. Una vez escuché a Ian Dundore (uno de los cracks de optimización en Unity) decir que el componente Animation es simple, versátil, rápido y excelente en muchas situaciones (más de las que uno se espera), que no se lo va a remover de Unity.
  40. 1 point
    no entiendo bien lo que quieres. puedes igual quitar el valor quebse llama "has exit time" (o algo asi) de la transicion del animator... y entonces la transicion sera instantanea.... pero tendras que usar un bool o un trigger del animator como condicion, eso si. o puedes usar el componente viejo "animation" que no tiene transiciones. directamente le dices la animacion que quieres que reproduzca.... creo que incluso le puedes indicar el frame en el que quieres que este la animacion... no se si esto te vale porque no se si he entendido bien lo que quieres.
  41. 1 point
    Hola! Hacía bastante tiempo que no escribía en mi blog y este fin de semana me he animado. Para quien le pueda interesar, dejo por aquí este tutorial recién sacado del horno sobre Unit Testing en Unity y cómo usar la herramienta Test Runner: https://histeriagamedev.wordpress.com/2020/06/20/unit-testing-en-unity/ Espero que os guste y, si es así, difundid a quien queráis:) Saludos!
  42. 1 point
    Primero decir... chorrimangera, enserio, aveces pienso que solo queréis matarme de la risa. Soy de la opinión de @francoe1... pero me pregunto como abran echo las colisiones tan tan precisas.
  43. 1 point
    De hecho hay varias maneras, una podría ser settear el botón en el script manager al iniciar la escena usando algo como esto: void Start() { var myManager = (*nombredelScript*)FindObjectOfType(typeof(*nombredelScript)); myManager.musicBtn = gameObject.GetComponent<Button>(); } Agrega este script en tu botón (GameObject). Puede que tengas que cambiar algunas cosas, pero la lógica sería la misma.
  44. 1 point
    En este vídeo volvemos a probar el generador en otra ciudad (A Coruña). Se añade la hierba, algunos objetos más, el minimapa y algunos otros detalles. ¡También estrenamos logo!
  45. 1 point
    Lleva ya unos cuantos meses, no recuerdo cuantos. Es obligatorio subir ambos apks 32 y 64
  46. 1 point
    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.
  47. 1 point
    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!!
  48. 1 point
  49. 1 point
    Hola, ahora que he empezado el proceso de subir un segundo juego a la playstore le he encontrado utilidad a los post que escribí al subir el primero, ya que me están facilitando mucho el trabajo. Os dejo los enlaces con una pequeña explicación y espero que puedan ser de ayuda a todos aquellos que hacen sus primeras subidas a la tienda de Google. Como subir un juego a la playstore. Aparte de describir el proceso, se indica lo que tendríamos que tener preparado previamente, como los iconos, o una descripción corta y una larga, pantallas, un vídeo… Como firmar un apk de unity para subirlo a la play store. Lo más importante: NO PERDÁIS NUNCA DE LOS JAMASES LA FIRMA. Incorporando Google logros con Google Play Services. Aparte de publicar el juego creo que es una buena idea aprovechar las diversas posibilidades que nos ofrece Google, los logros es una de ellas, y pueden ayudar a motivar al jugador. Como crear un tablero de puntos para Unity con Google Leaderboard. Otro de los servicios que nos ofrece Google y podemos aprovechar: el tablero de puntos! Són post muy simples, donde se explica el proceso más sencillo. Por ejemplo en el de subida no pasamos por Alpha y Beta, ni creamos un grupo de usuarios Betas. Espero que sirvan a todos aquellos que suben su primer juego! Suerte… y a por los Euruuuuuuus!!!
  50. 1 point
    ACTUALIZACIÓN - He añadido un par de animaciones más. - Ahora tanto el pelo como la armadura y la mandíbula se pueden quitar y dejar el esqueleto desnudo. Descarga desde el Asset Store de Unity (con escena de ejemplo, Prefabs listos y compatible con Mecanim) Descarga la versión suelta (sólo el modelo, animaciones y texturas)
UnitySpain © Todos los derechos reservados 2020
×
×
  • Create New...