Contenido

Fondo móvil

Introducción

Si queremos animar nuestras colinas de manera que el conjunto de imágenes de fondo de sensación de profundidad y movimiento, y además queremos que sean infinitos o scrollables, vamos a necesitar varias cosas:
  • Una escena nueva para no modificar las anteriores
  • Puesto que los fondos se irán moviendo a la izquierda o a la derecha, un fondo duplicado que cada colina que irá "entrando" a medida que "sale" el otro de la escena
  • Cada vez que una colina "salga" completamente de la escena, debe reposicionarse al otro lado, de modo que cuando la copia empiece a "salir", la otra empiece a "entrar".
  • Un script que se encargue de gestionarlo todo

Escena y Objetos

Según lo expuesto anteriormente:
  • Duplica la escena FondoPorCapas y llámala FondoMovil.
  • Haz doble clic en la escena FondoMovil para acceder a ella.
  • Renombra Colina 1 a Colina 11, duplícala y llama a la copia Colina12.
  • Ajusta Colina 12 (Con la Move Tool y la tecla V) para que quede a la izquierda de Colina 11.
Repite el proceso anterior de modo que la Colina 2 tenga una copia a la derecha, y la Colina 3 una copia a la izquierda:

Script

Por último, necesitaremos un script que se encargue de:
  • Capturar los objetos necesarios (fondo y colinas)
  • Calcular el ancho total del juego
  • Mover las colinas 1 y 3 hacia la izquierda y la colina 2 a la derecha, todas ellas con distintas velocidades
  • Comprobar cuando alguno de las colinas se sale por los lados (según el ancho del juego) y recolocarla
Si bien el código se podría hacer mucho más conciso y optimizado mediante listas y bucles, se prefiere dejar de la siguiente manera de modo que el alumno entienda mejor el proceso de movimiento y reposición de cada colina. Fíjate bien en los comentarios para entenderlo correctamente. Crea un nuevo script llamado Fondo dentro de Assets > Scripts, añádeselo al objeto Fondos y agrega el siguiente código:

using UnityEngine;

public class Fondo : MonoBehaviour {

    //Declaro las variables necesarias
    [Range(0.05f,0.15f)]
    public float velocidad1, velocidad2, velocidad3;
    private GameObject fondo, colina11, colina12, colina21, colina22, colina31, colina32;
    private float anchoJuego;

	void Start () {

        //Capturo el objeto del fondo y, partir de sus límites (bounds) el ancho del juego
        fondo = GameObject.Find("Fondo");
        anchoJuego = fondo.GetComponent<SpriteRenderer>().bounds.extents.x * 2;

        //Capturo las 6 colinas implicadas
        colina11 = GameObject.Find("Colina 11");
        colina12 = GameObject.Find("Colina 12");
        colina21 = GameObject.Find("Colina 21");
        colina22 = GameObject.Find("Colina 22");
        colina31 = GameObject.Find("Colina 31");
        colina32 = GameObject.Find("Colina 32");

    }

	void Update () {

        //COLINA 1
        //Calculo el vector de movimiento en X en base a la velocidad y el deltaTime
        Vector2 movimiento1 = new Vector2(Time.deltaTime * velocidad1, 0);

        //Muevo las dos copias de Colina 1 con ese vector
        colina11.transform.Translate(movimiento1);
        colina12.transform.Translate(movimiento1);

        //Si la colina 11 se sale completamente de la escena por la derecha, la recoloco a la izquierda de colina 12
        if (colina11.transform.position.x > anchoJuego)
        {
            colina11.transform.position = new Vector2(-anchoJuego + 0.01f, colina11.transform.position.y);
        }

        //Si la colina 12 se sale completamente de la escena por la derecha, la recoloco a la izquierda de colina 11
        if (colina12.transform.position.x > anchoJuego)
        {
            colina12.transform.position = new Vector2(-anchoJuego + 0.01f, colina12.transform.position.y);
        }


        //COLINA 2
        //Calculo el vector de movimiento en X en base a la velocidad y el deltaTime
        Vector2 movimiento2 = new Vector2(-Time.deltaTime * velocidad2, 0);

        //Muevo las dos copias de Colina 2 con ese vector
        colina21.transform.Translate(movimiento2);
        colina22.transform.Translate(movimiento2);

        //Si la colina 21 se sale completamente de la escena por la izquierda, la recoloco a la derecha de colina 22
        if (colina21.transform.position.x < -anchoJuego)
        {
            colina21.transform.position = new Vector2(anchoJuego - 0.01f, colina21.transform.position.y);
        }

        //Si la colina 22 se sale completamente de la escena por la izquierda, la recoloco a la derecha de colina 21
        if (colina22.transform.position.x < -anchoJuego)
        {
            colina22.transform.position = new Vector2(anchoJuego - 0.01f, colina22.transform.position.y);
        }


        //COLINA 3
        //Calculo el vector de movimiento en X en base a la velocidad y el deltaTime
        Vector2 movimiento3 = new Vector2(Time.deltaTime * velocidad3, 0);

        //Muevo las dos copias de Colina 32 con ese vector
        colina31.transform.Translate(movimiento3);
        colina32.transform.Translate(movimiento3);

        //Si la colina 31 se sale completamente de la escena por la derecha, la recoloco a la izquierda de colina 32
        if (colina31.transform.position.x > anchoJuego)
        {
            colina31.transform.position = new Vector2(-anchoJuego + 0.01f, colina31.transform.position.y);
        }

        //Si la colina 32 se sale completamente de la escena por la derecha, la recoloco a la izquierda de colina 31
        if (colina32.transform.position.x > anchoJuego)
        {
            colina32.transform.position = new Vector2(-anchoJuego + 0.01f, colina32.transform.position.y);
        }

    }
}
NOTA: Habrás podido observar que agregamos 0.01f al valor de anchoJuego a la hora de recolocar las colinas. Este valor corresponde a 1px y nos asegurará que no queda hueco entre ambas colinas debido al renderizado (siempre que usemos velocidades bajas). Si ahora ajustas las 3 velocidades (yo he usado valores muy pequeños, 0.05, 0.06 y 0.04), podrás ver el efecto deseado:

Ver vídeo

Fondos móviles