jueves, 23 de junio de 2016

Como crear textos al agarrar objetos en tiempo real en Unity | How to create texts when grabbing objects in real time in Unity

Español | English



Un efecto clásico. En muchos juegos de Arcade o de plataforma tenemos este pequeño detalle que tal vez algunos ignoran, un pequeño texto cuando agarramos un objeto (o un simple "+1" al agarrar una moneda). Así que me decidí por averiguar cómo funciona.

La idea básica es simple: hacer que un texto se muestre cuando el jugador colisione con cierto objeto, el texto debía aparecer un poco más arriba del jugador para poder apreciarlo bien. Pero también, el texto debía aparecer un poco más adelante, ya que el jugador esta constantemente en movimiento, por lo que el texto va a estar, adelante y por arriba del jugador.

¿Pero cómo le decimos donde aparecer al texto, si en Unity el GUI y el "mundo" se manejan por separado? Para aclarar el problema, si un objeto esta en la posición 100 horizontal, no hay forma de llevarle esas coordenadas al texto que va a aparecer en la interfaz. Además se suma el hecho de que la cámara se mueve constantemente con nosotros.

Para esto debemos ajustar algunas propiedades del Canvas. El Canvas es el lugar en donde tienen que estar los elementos del GUI (como los botones o textos, etc). Estos se pueden crear y hasta tener más de uno en la misma escena. (Nota: Al crear un botón o cualquier elemento del GUI, Unity por defecto crea un Canvas si no había uno existente).

Luego de modificar el Canvas vamos a crear una "Sorting Layer" y finalmente, vamos, por código, a indicarle al texto donde tiene que aparecer.



La opción que vamos a cambiar es "Render Mode". Vamos a utilizar la opción "Screen Space- Camera", lo que hace cada opción de la lista es ofrecernos distintas formas en las que podemos utilizar el Canvas; si queremos que este por encima de la cámara, si queremos que este fija en el espacio del juego o si queremos que trabaje en el espacio de la cámara.

Lo que vamos a hacer nosotros es trabajar en el espacio de la cámara. Lo siguiente será arrastrar nuestra cámara a la casilla de "Render Camera" para asignarla.


Las Sorting Layers son capas de prioridades, se usan principalmente para indicar que elementos se muestran al fondo y cuales más adelante. Hacemos Click en Sorting Layer y luego en "Add Sorting Layer".

Primero clickeamos en el "+" y luego la nombramos, finalmente debemos volver a la propiedad de Canvas para asignarle esa capa que le creamos.

El Canvas esta listo. Este trabajo fue hecho para que el Canvas trabaje en el espacio del juego pero los elementos que muestre estén "una capa adelante", con lo cual no se va a superponer con otros objetos del juego.

Lo siguiente a hacer es crear dentro de este Canvas un texto de UI, haciendo click derecho en el Canvas/UI/Text.

Por último, vamos a crear el Script que le va a indicar a ese texto donde tiene que aparecer y que tiene que decir.

Las variables a utilizar son:

Public Text cartel;
(Nota: Luego hay que arrastrar un elemento Texto a la casilla de la variable pública)

Voy a utilizar un corutina por 2 razones: 
  1. Quiero poder llamar a esta función poniendo como parámetro el texto que quiero que muestre.
  2. Quiero crear un delay para que el texto no desaparezca enseguida.


IEnumerator Show_Sign(string texto)
    {
        cartel.gameObject.SetActive(true);
        cartel.text = texto;
        cartel.color = new Color(1, 1, 1, 1);
        cartel.gameObject.transform.position = new Vector3(player.position.x + 1, player.position.y + 1, 0);
        yield return new WaitForSeconds(0.2f);
        cartel.gameObject.SetActive(false);
     }

La función se basa en activar y desactivar el texto que habíamos creado, luego le dice cual es el texto que tiene que mostrar y le asigné el color blanco. Luego, le indico que tiene que estar 1 unidad más arriba y adelante de la posición del jugador. Por último, le digo que haga un delay hasta la próxima instrucción que es para desactivar este texto.

Lo que no quería hacer era tener que crear y eliminar el texto cada vez que el jugador agarra un objeto, ya que consumía muchos recursos, por eso, es más preferible ya tenerlo creado y simplemente activarlo o desactivarlo.

Ahora podemos llamar a la corutina indicándole que texto mostrar de la siguiente manera:

StartCoroutine(Show_Sign("Calculator!"));

Y así queda creado este efecto clásico pero muy interesante que aporta un agregado más al diseño del juego en general.


-L



------------------------------------------------------------------------------------------

English

A classic effect. In many Arcade or platform games, we have this small detail that many can ignore, a small text when we grab an object ( or a simple "+1" when we grab a coin). So I decided to figure out how it works.

The basic idea is simple: Make a text show when the playe collides with a certain object, the text should appear a little higher than the player so it can be seen clearly. But also, it has to be a little bit more forward as the player is constantly moving. So the text is going to be placed higher and a bit forward than the player.

But how do we tell the text where to go, if in Unity the GUI and the "world" work on different spaces? To make the problem more clear, lets say there is an object in the horizontal position 100, there is no way to send the coordinates to the text which is going to appear on the interface. Plus, there is the fact that the camera moves following the player.

So we need to make some few changes to some of the properties of the Canvas. The Canvas is the place where the elements of the GUI (such as buttons, text, etc) have to be. This can be created and the same scene can have multiple Canvas. (Note: When creating a button or any GUI element, Unity by default creates a Canvas if didn't exist).

After having done the modifications to the Canvas, we are going to create a "Sorting Layer" and finally, by code, we are going to indicate the text where it should appear.



The option we are going to change is "Render Mode". We are going to use the option "Screen Space- Camera", what each option of the list does is to offer us different ways in which we can use the Canvas; if we want it to be above the camera, or we want it with fixed position in the game space or we want it to work in the same space of the camera.

What we are going to do is to work in the same space of the camera. The next thing is to drag the camera to the "Render Camera" box to assign it.

Sorting Layers are layers of priorities, they are used mainly to indicate which elements go to the background and which elements will be above those of the background. We click in Sorting Layers and then in "Add Sorting Layer".




First we click the "+" and then we name the layer, finally we go back to the properties of the Canvas and assign the layer we have just created.

The Canvas is ready. This job was done to allow the Canvas to work in the same space than the camera but making the elements of the Canvas be on a different layer, this will avoid the collision between the elements of the GUI and the rest of objects of the game.

The next thing to do is to create inside the Canvas, a UI text, making right click on Canvas/UI/Text.

Finally, we are going to create the Script that will indicate the text where it should go and what to say.

The variables I'm going to use are:

Public Text mysign;
(Note: Later on, a Text element has to be dragged to the public variable box)

I'm going to use a coroutine because of 2 reasons:

  1. I want to call this function with the text I want to show as a parameter.
  2. I want to create a delay so that the text doesn't disappear right away.


IEnumerator Show_Sign(string mytext)
    {
        mysign.gameObject.SetActive(true);
        mysign.text = mytext;
        mysign.color = new Color(1, 1, 1, 1);
        mysign.gameObject.transform.position = new Vector3(player.position.x + 1, player.position.y + 1, 0);
        yield return new WaitForSeconds(0.2f);
        mysign.gameObject.SetActive(false);
     }


The function is based on toggling on and off the text which we have created, it laters tells the text what should say and I make it white. Then, I tell the text that it should be 1 unit more high and forward than the player's position. Finally, I create a delay for the next instruction, which is to deactivate the text.

What I didn't want to do was to create and eliminate the text every time the player grabs an object, as it would consume a lot of resources, that is why, it is better to have the text already created and simply activate it or deactivate it.

Now, we can call the coroutine indicating what we want it to say:

StartCoroutine(Show_Sign("Calculator!"));

And this is how we create this classic but very interesting effect which adds its own value to the general game design.

-L

No hay comentarios.:

Publicar un comentario