Jorge Vallejo Blog

Blog del creativo, ilustrador y profesor de videojuegos Jorge Vallejo

Crear un videojuego para móvil II con Unity: Mecánicas de giro

YouTube player

En el segundo vídeo de la serie de recreación de un videojuego para moviles android con Unity veremos como crear mecánicas de giro, que serán la base de todo el juego.

El reto:

El jugador debe tener un reto al que enfrentarse, en este caso ponemos aprueba su velocidad y su capacidad de calculo para que las bolas no choquen con los objetos, frente a otros juegos de móvil donde desplazamos el elemento principal, aquí lo rotamos, al existir dos bolas complicamos el movimiento, ya que tendremos que movernos hacia la derecha y hacia la izquierda.

En este tipo de videojuegos minimalistas para móviles, es importante tener una mecánica clara, bien definida y sencilla de entender, la complejidad del juego vendrá de un factor externo al jugador: los niveles.

En este vídeo tutorial trabajaremos diferentes elementos base de Unity para la recreación de un videojuego para móvil android , tipo Duet:

– Colocación de los distintos elementos

– Diseño base usando solo recursos de Unity

– Diferenciar tiempo de juego de tiempo de edición

– Buenas practicas de programación [SerializeField]

– Mecánicas de giro

– Programación de el giro

Crear un videojuego para móvil I con Unity

He creado una serie de vídeos Unity Do el camino del videojuego donde veremos paso a paso , y explicando cada parte cómo crear un videojuego para móvil, concretamente para la plataforma android desde 0 y utilizando Unity y C#

YouTube player

En este vídeo recrearemos el videojuego para móviles Duet con Unity y C# :

-Cómo preparar un proyecto de Unity para exportarlo a Android

-Configuración del proyecto para Android

-Creando un GameManager

-Creación de los controles con Event Trigger

-Comunicación GameManager y Event Trigger

-Comprobación de los eventos por consola

Lo interesante de recrear un proyecto es ir desglosando cada paso, tratando de crear una buena arquitectura en el control del juego e ir aumentando su complejidad progresivamente, trataremos de utilizar las herramientas más adecuadas , por ejemplo utilizaremos un tipo de collection menos conocido como queue para gestionar los textos, o usaremos AudioMixer para el control de sonidos.

No te pierdas este y otros contenidos creados para enseñar a todo el que lo desee a diseñar y programar videojuegos y suscribirte al canal.

https://www.youtube.com/channel/UChMzt1jSTzii0hoY1ABHPpQ

Nace Unity Do , el camino del videojuego

Llevaba un tiempo pensando en crear un canal de youtube donde volcar mi conocimiento sobre programación y Unity, como docente de videojuegos, hay muchas cosas que me dejo en el tintero en las clases, por falta de tiempo.

Unity a sufrido constantes mejoras en los últimos años, algunas de las cuales se han vuelto muy interesantes pero demasiado especificas , por ejemplo el nuevo sistema para animación 2D, por eso en el canal Unity Do, puedo explorar los nuevos paquetes, las actualizaciones, assets y tambien hacer hincapie en la programación y el diseño de videojuegos.

¿Por qué es necesario crear un canal como Unity Do?

Como su nombre indica UnityDo es un guiño a las artes marciales, como Judo, Taekwondo , Karate Do.. en ese caso el do significa camino, una filosofia de entrenamiento y mejora continua, que es precisamente la quiero inculcar en el canal.

Por lo tanto Unity Do, es el camino de Unity, el camino del videojuego, y mi intención es conseguir fomentar la programación y el desarrollo de videojuegos en castellano, ya que hay muy buenos canales en ingles, pero creo que en español , que tambien les hay muy buenos, nos falta ser un poco mas desprendidos con el conocimiento e ir más alla de lo basico.

Como en cualquier otro proyecto que uno se embarca debe aspirar a lo máximo, mi reto es conseguir tener un dojo virtual, una comunidad de seguidores, que hayan pasado del blanco al negro, de apenas tener un concomiendo a ser capaces de crear grandes videojuegos.

Escenas de paisajes en Unity

Crear escenas de paisajes es una buena practica para entender como posicionar elementos, como crear una composición y como funcionan las luces en Unity, trabajando con un directional light y unas pocas luces mas para matizar es suficiente.

Un protocolo de trabajo, sin utilizar terrains, que serán explicados en otro articulo

Gran Capitán creado en Unity3d
Escena creada con Unity

1) Cambiamos el modo de Color Space a linnear en File-> Build Settings ->Player Settings ->Other Settings -> Linnear

2) Metemos un skybox de un cielo

3) El skybox nos dará una definción aproximada de la hora del día, amanecer, atardecer etc

4) Colocaremos la rotación del directional light basándonos en la hora aproximada del día, si es de noche podemos dar una luz azulada tenue

5) Importar las texturas y crear los materiales colocando sus mapas

6) Importar diferentes modelos para crear una composición general (Montañas, rocas, arboles

7) Colocar los objetos creando la composición, se puede importar una referencia y meterla en un plano, o usar Cinemachine >Storyboard

8) Creada la composición los gameobjects serán marcados como static

9) Los objetos complejos se aumenta su escala en el lightmap en el Mesh Renderer ->Lightmap Settings -> Scale Lightmap (Para que aparezca el objeto tiene q ser static)

10) Si queremos meter reflejos , creamos un Reflexion Probe , y lo colocamos en los objetos que tengan propiedades metalic , specular o roughness

11) Colocamos la cámara creando el cuadro de la composición

12) Bakeamos ->Lighting->Settings->Generate Lighting

13) Podemos meter como máximo un par de point light para crear ambientaciones

14) Corregimos iluminaciones y posiciones

15) Volvemos a Bakear

Resumen de métodos de List I

Voy ha hacer un resumen de los diferentes metodos de List<t> y su aplicación al mundo de los videojuegos con Csharp y Unity

En vez de poner cada uno de los diferentes métodos y traducirlo, voy a ponerlo como preguntas para que resulte más sencillo:

¿Qué es un List?

List<T> son como arrays vitaminados, una lista de objetos con propiedades y métodos propios pensada para realizar tareas habituales en los array pero mas rápidamente. List<T> significa genérico pueden ser de cualquier tipo

¿Cuando usar array y cuando List?

Los arrays son estructuras menos complejas, mas livianas y mas rápidas al ejecutarse que un List, en general diremos que si no se van a realizar tareas como añadir, eleminar o buscar probablemente con utilizar un array será suficiente, por otro lado cuando creamos una clase propia por ejemplo Carta, es cuando solemos utilizar List , quedando List<Carta>=new List<Carta>(); ya que nos permite hacer operaciones muy rapidamente con una pocas lineas de codigo.

Un #list puede no tener un número de elementos definido, funcionando como un papel en blanco, una lista de la compra, donde vamos añadiendo elementos, borrando, buscando.. Ejemplo con clase propia: List<Carta> Baraja

¿Como saber cuantos elementos tiene un List?

Dado el List Baraja, por ejemplo, con el método Count obtendremos el numero de elementos, asi Baraja.Count nos devolvería 40 en una baraja española

He visto que hay otro método llamado Capacity ¿Es lo mismo que Count?

No , Capacity se refiere a la reserva de memoria que hace para no tener que estar modificando el espacio reservado cada vez que se añade o elimina un elemento. Ambos pueden coincidir cuando tienes el mismo numero de elementos que la capacidad.

#Count vs #Capacity en List<T> un estadio tiene capacidad para 100000 (Capacity) pero solo hay 5000 espectadores (Count). Daremos una capacidad cuando ya sabemos el número de elementos que va albergar, reservando memoria.

List<T> puede modificar Capacity cuando el número de elementos la supera, “crece” para albergar los nuevos elementos. En una fiesta has reservado para 4 personas pero vienen 5 el restaurante te da otra mesa

¿Se puede ajustar Capacity al numero exacto de elementos que tiene el List?

Si, hay un metodo especifico para eso : TrimExcess () , el cual ajusta Capacity para que sea igual a Count.

Vas a dar una fiesta para 20 personas #capacity pero solo vienen 16 #count , con Sillas.TrimExcess () ajusta #capacity al #count para que no sobren sillas (más memoria de la necesaria)

Unity crear arrays o matrices

¿Qué es una matriz o array de elementos?

Podemos definir un array como una lista de elementos ordenados, de tal forma que iremos guardando datos en diferentes “cajas” las cuales están ordenadas y numeradas con un indice único que empieza en 0 en csharp y Unity la crearemos definiendo:

Primer el ámbito de aplicación, si es publica o privada

Después el tipo de variable o clase por ejemplo int

Después los corchetes que van a servir para identificar el array o matriz, de tal forma que mientras int numero solo puede contener un número int[] Numeros va a poder contener una cantidad de elementos que debemos dar al crear la matriz, reservando en memoria espacio para esos elementos.

Podemos darle el nombre que queramos, aun que yo aconsejo poner la primera letra en mayúsculas y en plural para que de una forma sencilla distingamos una matriz de otro tipo de variables.

En general determinaremos cuantos elementos va a contener el array ya que necesariamente necesita saberlos para funcionar, si no sabemos el numero de elementos que va a contener hay otras estructuras como los List que lo permiten.

Con new llamamos al constructor del array ya que en csharp los arrays o matrices funcionan como objetos, con sus propias propiedades y métodos , para dar un numero de elementos debemos usarlo, finalmente una matriz de tipo int solo podrá contener int, por eso escribimos int[20], reservando memoria para 20 enteros.

Para acceder a un elemento usaríamos Numeros[indice] , por ejemplo Numeros[0] nos devuelve el elemento que este guardado en la “caja” 0

Si definimos la matriz utilizando el constructor, en este caso al ser números enteros todos los elementos tendrían un valor inicial de 0.

Podemos también definir una matriz de esta otra forma:

En vez de usar el constructor utilizamos una colección de elementos, la cual se define con llave { elementos separados por comas y fin de llave }

Automáticamente la matriz se define con seis elementos como si se hubiese utilizado new int[6]

Numeros[0] , nos devolvería en este caso 1

Unity eliminar duplicados en un cadena

Existen diferentes formas de conseguir eliminar duplicados en una cadena, las formas más sencillas sería utilizar otros métodos como puede ser importar System.Linq la cual nos permite “limpiar” de duplicados con su método Distinct.

Sin embargo como ejercicio para comprender el funcionamiento de los arrays creo que puede ser muy útil hacerlo nosotros mismos, ya que tendremos que ver previamente como saber si un elemento está en un array y como añadir un elemento a un array.

Primer vamos con ¿Cómo saber si un elemento está en un array?

bool LetraEstaEnMatriz(char letra, char[] Letras){
		for (int i = 0; i < Letras.Length; i++) {
			if (letra == Letras [i]) {
				return true;
			}
		}
		return false;
	}

Creamos una función que devuelve un bool y recorremos el array comparando letra a letra, al hacer return si encuentra una letra se sale de la función por lo que no continua el for

La siguiente función a implementar es la que nos añade un elemento a un array , lo normal es añadirlo al final del array, la ventaja de crear nuestra propia función es que podriamos cambiar este orden si quisieramos.

char[] AñadeLetraAMatriz(char letra,char[] Letras){

		//se aumenta la matriz
		char[] Copia_letras=new char[Letras.Length+1];

		for (int i = 0; i < Letras.Length; i++) {
			Copia_letras [i] = Letras [i];

		}
		//queda la ultima
		Copia_letras[Letras.Length]=letra;
		Letras = Copia_letras;
		return Letras;
	}

Un array no permite añadir directamente, lo que hay que hacer es crear una copia previa, dejando un “espacio” para la nueva letra, despues se vuelca todo el array y finalmente se añade la última, volvemos a meter los elementos en el array original con Letras=Copia_letras y finalmente devolvemos el array con las letras

Ahora nos queda la parte final, para eliminar los duplicados, crearemos otra función

char[] SacaLetrasSinRepetir(string _palabra){
		char[] Letras=new char[0];

		for (int i = 0; i < _palabra.Length; i++) {
			for (int j = 0; j < _palabra.Length; j++) {

				if (i != j) {
					if (_palabra [i] == _palabra [j]) {
						if (!LetraEstaEnMatriz (_palabra [i], Letras)) {

							Letras = AñadeLetraAMatriz (_palabra [i], Letras);
						
							break;
						}
					} else {
						if (!LetraEstaEnMatriz (_palabra [i], Letras)) {
							Letras = AñadeLetraAMatriz (_palabra [i], Letras);

						}
					}
				}			
			}

		}
		return Letras;
	}

Primero creamos un array de dimension 0 que esta preparado para ir añadiendo letras, con char[] Letras=new char[0];

Despues recorremos _palabra , aqui hay que tener en cuenta que necesitamos dos bucles anidados para que haga la comparación de una letra con todas las demás.

Si tenemos por ejemplo una cadena “AABB”, lo que debemos hacer es comparar el elemento 0 , es decir A con ABB, despues la segunda A con BB ..

Por eso usamos los dos for, ahora bien una letra siempre será igual a si misma por eso despreciamos el caso i==j quedándonos solo con i!=j

Si la letra coincide es igual a otra, es decir esta repetida, comprobamos que no la tenemos ya en la matriz, con la función LetraEstaEnMatriz (_palabra [i], Letras) como es no , usamos la exclamación para negar el caso quedando

!LetraEstaEnMatriz (_palabra [i], Letras) si entramos en este if significa que no tenemos la letra en Letras por lo que la podemos añadir con la función

Letras = AñadeLetraAMatriz (_palabra [i], Letras); Después tenemos un break; este hace que se salga del primer for, por que ya no necesitamos comprobar más si tenemos una A que es igual a otra la guardamos solo una vez

Nos queda la otra posibilidad que la letra no sea igual, la guardamos en la misma matriz Letras, así tendremos tanto las que se repiten como las que no.

Sólo queda devolver el array que contendrá las letras sin los duplicados con un return

Como siempre digo en mis clases , este es el camino que he elegido yo, no es el único , quizá tu lógica te lleve por otro hasta es posible que el código se pueda optimizar más, para eso debes buscar tu propio camino.

Unity movimiento con Coseno

El uso de Mathf para implementar funciones matemáticas es muy sencillo, y permite hacer muchas cosas curiosas con muy pocas lineas de código.

Uso de Mathf.Cos para la creación de movimiento, ya que la fluctuación del coseno es -1 y 1

En el Update
pos_x += velocidad;
pos_y += velocidad;
transform.position = new Vector2(pos_x, Mathf.Cos(pos_y));

YouTube player

Unity creación de menús por código

Cuando uno se inicia en la programación es una buena practica entender lo más esencial, es por ese motivo que en clase empiezo explicando la creación de menús por código con la función OnGUI, en vez de ir directamente a la creación de menús con Canvas en Unity.

Unas pocas lineas de código son suficientes para poder crear un menú básico , que forme parte de un prototipo inicial y que más adelante se pueda cambiar.

El uso de Arrays para contener los nombres de textos y botones, hace que el proceso de construcción se vuelva todavía mas optimizado.

YouTube player

Remodelación 3D de Cocina con Unity y Blender

Cocina en Unity

En Blender hice unos modelos sencillos basados en un concepto que la empresa de cocinas nos dio, el mayor reto es decidir entre las múltiples posibilidades que la combinación de colores de muebles, encimera y suelo ofrece, para lo cual al hacer el sistema con Unity puede implementar una selección de materiales y hacer cambios muy rápidos.

Por otro lado para el suelo, miramos diferentes azulejos, que luego hay que tratar en photoshop u otro programa de retoque grafico para hacerlos repetibles tanto horizontal como verticalmente, ya que si la textura está preparada podremos utilizar fácilmente la propiedad tiling del material, la cual nos permite controlar la repetición de la textura.

Ad debug output

The ad is displayed on the page

current post: Remodelación 3D de Cocina con Unity y Blender, ID: 2560

Ad: Anuncio2 (2573)

Display Conditions
general conditions
Adwp_the_query
is_main_query11
page01
numpages01
is_archive1
is_search1
is_home11
is_4041
is_attachment1
is_singular1
is_front_page11
is_feed1




Find solutions in the manual

Diseño y remodelación de baño 3d con Unity

Partiendo de una fotografia del antes y con las medidas exactas he levantado en 3d el baño , añadiendo detalles que lo hacen más creíble.

Para crear la habitación en 3d utilice blender , existe un addon interesante archimesh que nos ayudara a resolver facilmente algunas cuestiones , como la colocación de ventanas y puertas.

Despues el modelo lo podemos importar directamente en unity como .blend para hacer las modificaciones sobre ese archivo, hay que tener en cuenta q una vez importado si añadimos elementos en el .blend estos no apareceran directamente en la escena de unity sino que tendremos que volver a meterla en la escena, por eso es preferible importar el modelo cuando este lo mas acabado posible.

Galería de Youtube

Añadir y quitar elementos de una lista en Unity

Siempre digo que los List son como Arrays o Matrices vitanimadas, ya que tienen implementados sus propios metodos lo que facilitar la labor a la hora de manejarlas.

En c# y Unity para poder utilizar los List tendremos que tener la librería

using System.Collections.Generic;

Depues podemos declarar nuestra lista del tipo que queramos , normalmente usaremos listas con tipos mas complejos que una variable, numero o cadena, es decir, usaremos listas sobre todo con objetos definidos por una clase.

Imaginemos que queremos llevar un registro de los enemigos que hay en el juego,

Tendremos una clase Enemigo

Declaramos nuestro List

public List<Enemigo> enemigos=new List<Enemigo>();

Ahora queremos almacenar un nuevo enemigo, pero no queremos almacenarlo si esta repetido, es decir, solo almacenaremos un enemigo que no este ya en la lista, con arrays seria un proceso mas lento, habria que recorrer el array para saber si esta ya o no, crear una copia del array con una dimensión mayor y volcar de un array a otro.

Con listas es mucho más sencillo, podemos crearnos una función que es publica y que no delvuelve ningun valor void llamada RegitraEnemigo, la cual recibe un parametro de tipo Enemigo llamado e

Lo primero que hace es comprobar si la lista ya contiene a ese enemigo con enemigos.Contais(e) una funcion propia de las listas que devuelve un bool es decir, verdadero o falso, si devuelve false, entonces e no esta en la lista enemigos por lo que lo podemos añadir con enemigos.Add(e) que mete ese enemigo en la lista

public void RegistraEnemigo(Enemigo e){

if (enemigos.Contains (e) == false) {
enemigos.Add (e);
}
}

Por el contrario si lo que queremos es borrar un enemigo que ya esta en la lista , lo que haremos sera comprobar previamente que esta en la lista y después borrarlo.

public void  QuitarEnemigo(Enemigo e){

if (enemigos.Contains (e)) {
enemigos.Remove (e);
}
}

Hay que aclarar que un eliminado de un objeto de un List no lo borrara de la jerarquía , lo que hacemos es borrar la referencia que estaba guardada en la lista para borrarlo de la jerarquía habría que usar Destroy(gameObject);