miércoles, 27 de julio de 2016

Como crear un fondo rotativo para Infinite Runners en Unity | How to create a scrolling background for Infinite Runners in Unity


Español | English



En este tutorial voy a enseñar como crear un fondo rotativo, esto es, un fondo que se mueva a medida que el jugador avanza. Este tutorial esta pensado para los juegos de estilo Infinite Runner, por lo tanto, se toma en cuenta que:
  1. El jugador siempre esta en movimiento
  2. El movimiento del jugador es constante

Aunque también se va a ver como crear este fondo para los casos en los que nuestro jugador este quieto o nuestro jugador haya variado la velocidad. Este tutorial sirve tanto para juegos 2D o 3D

Primero necesitamos un fondo, para ser más ilustrativo, voy a usar imágenes muy simples.


Este fondo de barras va a ser lo que vamos a utilizar, el hecho de que haya un rectángulo rojo es para poder distinguir mejor, nuestro fondo puede tener algún elemento que sea distintivo y sirva para marcar (un árbol, un edificio, etc).


Lo que vamos a hacer es importar esta imagen a Unity y asignarla como "Textura". Luego vamos a modificar el "Wrap mode" que por default esta en "Clamp" hacia "Repeat".

 Lo siguiente que vamos a hacer es crear un nuevo Material. Para eso vamos a dar clic derecho en el inspector/crear/material al que vamos a nombrar "fondo".Lo próximo va a ser modificar el Shader este nuevo material, lo queremos en Texture, para eso vamos a seleccionar de menú desplegable donde dice "Shader" y elegir "unlit/Texture"



Y arrastramos el fondo que importamos hacia el cuadrado al costado para indicarle al material su textura. Lo próximo es crear un Quad en el inspector, que va a ser donde vamos a colocar nuestro fondo, para eso vamos a GameObject/3D Object/Quad. Si queremos podemos remover el componente "Mesh Collider" de este, ya que no lo vamos a utilizar.

Luego, hay que asignarle a este Quad el nuevo material que creamos con nuestro fondo, para eso, seleccionamos al Quad y arrastramos el material que creamos hacia la pestaña Mesh Renderer/Materials/Element0 y luego podemos agrandar o achicar el Quad para que muestre lo que queremos del fondo.

La siguiente parte es de programación, lo que vamos a hacer es modificar el Offset del eje X del material dentro del Quad, eso va a rotar la imagen. A continuación muestro una imagen sin offset y una imagen con Offset:

Sin Offset (el fondo original):


Imagen con Offset;





Como podemos ver, la imagen se "corrió" hacia el costado y como a la derecha de la imagen no hay nada, se repite la imagen de nuevo, si este offset es continuo, se crea el efecto de que el fondo se esta moviendo.

Vamos a crear un Script llamado "Background_scroll" 

primero empezamos declarando las variables que vamos a utilizar:

public MeshRenderer mr;
public float scroll_vel = 0.4f; //el valor se pude cambiar a lo que más convenga.

Si se quiere simplemente que el fondo se mueva infinitamente sin importar que el jugador este quieto o no debemos escribir dentro de Update():

mr.material.mainTextureOffset = new Vector2( (Time.time * scroll_vel)% 1, 0);

lo que hace esto es indicarle al Mesh Renderer del Quad que su Material va a tener un offset de Time.time * scroll_vel  % 1

La parte más importante de todo está en el "%1", ya que Time.time va a ser cada vez más grande y lo que nosotros queremos es crear un offset entre el valor 0 (no offset) a 1 (una vuelta completa) por eso, se utiliza la congruencia con módulo 1 (los restos de dividir Time.time *scroll_vel con 1), ya que siempre van a estar entre 0 y 1.

Como dije antes, si solo se quiere que el fondo se mueva constantemente sin importar el jugador, ese es el código, faltaría únicamente desde el inspector arrastrar el Script hacia el Quar y arrastrar al Quad hacia "Mesh Renderer" para que se agarre a si mismo.

Si queremos que la velocidad varíe, necesitamos conocer la velocidad, para eso voy a asumir que la velocidad del jugador esta con acceso public static, en un Script "jugador". Entonces lo que haremos es modificar scroll_vel dependiendo de la velocidad del jugador.

declaramos la variable vel en Update(), ya que necesitamos que se actualice constantemente
vel = jugador.velocidad //referencia hacia una variable que indica la velocidad del jugador

Y simplemente, dentro de Update vamos a crear unos Ifs para variar dependiendo de la veloidad

If ( vel == 0 ){
    scroll_vel = 0; //para detener el scroll.
}

Por último, si la velocidad varía, por ejemplo que sea mayor a 0 y menor a 1, vamos a hacer decaer scroll_vel progresivamente. Para esto vamos a utilizar la función Mathf.Lerp(valor inicial, valor final, intervalo de tiempo).

If (vel > 0 && vel < 1)
{
    scroll_vel = Mathf.Lerp(0.4f, 0.2f, 0.5f); //hace decaer scroll_vel de 0.4 a 0.2 progresivamente
}

Debemos utilizar la función Lerp ya que no podemos utilizar cambios bruscos en la velocidad en la cual el fondo se rota.

Y eso es todo, con esto tenemos nuestro fondo rotativo para Infinite Runners.


-L


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

English



In this tutorial I'm going to teach how to create a scrolling backgound, this is, a background which scrolls as the player advances the level. This tutorial was thought for Infinite Runner games, so I take into consideration that:


  1. The player is always moving
  2. The movement speed is constant
Although it will also teach how to do for the case that our player isn't moving or his/her speed varies. This is both for 2D and 3D games

We first need a background, to keep things simple, I'm going to use very simple images:




This bar background will be the one we are going to use, the fact that it has a red rectangle is only to make very visible when we scroll it, your background may have a distinctive element that may be used for this (a tree, a building).

What we are going to do is to Import this image into Unity and assign it as a "Texture". Then, we are going to modify the "wrap mode" which by default is "Clamp" to "Repeat".

The next thing we are going to do is to create a new Material. For that we right click in the inspector/create/Material and we name it "Background". Next, we need to modify the Shader of this new material, we want it in Texture, for that we select from the drop down menu of Shader Unlit/Texture


And we drag the background that we imported to the square at the right to indicate the material its texture. Then we create a Quad in the Inspector, which will be use to place the background, for that we go to GameObject/3D Object/Quad. We can if we want, remove the "Mesh Collider" as we won't use it.

Next, we need to assign the Quad the Material which we created earlier, for that, we select the Quad and drag the Material to where it says "Mesh Renderer/Materials/Element0" and then we can adjust the size of the Quad to let it display the whole background.

The following part is about programming, what we are going to do is to modify the Offset of the X axis of the material inside the Quad, that will scroll the image. I'll now show you the background without offset and with offset:

Without Offset (the original background):


With Offset:




As we can see, the image "scrolled" to the side and as there is nothing at the right of the image, it began to repeat itself, if this offset effect is constant, we can create the effect that the image is scrolling.

Now we create a Script called "Background_scroll"

We first start declarating the variables we are going to use:

public MeshRenderer mr;
public float scroll_vel = 0.4f; //the value in here can vary to whatever you like

If you simply want to scroll the background infinitely without taking care if the player is still or not, we need to write this inside Update():

mr.material.mainTextureOffset = new Vector2( (Time.time * scroll_vel)% 1, 0);

What this does is to tell the Mesh Renderer of the Quad that his Material will have an offset of Time.time * scroll_vel  % 1

The most important part is in the "%1", as Time.time will always be increasing and what we want is to create an offset between 0 (no offset) to 1 (a full turn) that is why the congruence with module 1 is used ( the remainder of dividing Time.time * scroll_vel with 1) as they will always be between 0 and 1.

As I said before, if what you only want is the background to move constantly without taking care if the player is moving or not, that's the code, what it only needs to do left is to drag the Script from the inspector to the Quad and then drag the Quad to itselft where it says "Mesh Renderer" on the Script component.

If we want speed to vary, we need to know the player's current speed, for that I'm going to assume that the players velocity is in a public static float named velocity in a Script called "player". Then what we need to do is to modify scroll_vel depending the speed of the player.


We declare the variable vel in Update(), as we need it to be constantly updating

vel = player.velocity //reference to a value in the player script that indicates the player speed

We then simply make, inside the Update() function some Ifs statements to vary scroll_vel depending on the player's speed


If ( vel == 0 ){
    scroll_vel = 0; //to stop the background from scrolling
}

Lastly, if the player's speed varies, for example is bigger than 0 but less than 1, we need to reduce scroll_vel progresivelly. For this we are going to use the function Mathf.Lerp(initial value, final value, time interval).

If (vel > 0 && vel < 1)
{
    scroll_vel = Mathf.Lerp(0.4f, 0.2f, 0.5f); //reduces in a progressive way the value of scroll_vel
}

We need to use the Lerp function as we can't make abrupt changes to the speed in which the background is scrolling.

And that's all, with this we have our scrolling background for our Infinite Runners




-L

No hay comentarios.:

Publicar un comentario