Foros - Stratos

Programadores => General Programadores => Mensaje iniciado por: Totemalf en 09 de Septiembre de 2013, 08:41:46 PM

Título: Fundido a negro al cambiar de nivel
Publicado por: Totemalf en 09 de Septiembre de 2013, 08:41:46 PM
Buenas una vez más,
a ver si algún usuario de unity puede decirme como conseguir el efecto de fundido a negro para cambiar de nivel. Unity hace el cambio de escena muy brusco y yo quiero algo más suave, pero no encuentro info al respecto. Tambien estoy mirando en unityspain, pero a ver.

Un saludo y gracias!
Título: Re:Fundido a negro al cambiar de nivel
Publicado por: [EX3] en 10 de Septiembre de 2013, 12:56:34 AM
Buenas.

No habia hecho esto antes en Unity3D pero creo que esta seria una buena forma de hacerlo.

He escrito un script para hacer el fundido a negro y que tras terminar haga la llamada a la carga del nivel. La idea es que lo añadas a un GameObject de tu escena para despues llamarlo enviandole un mensaje.

El codigo del script:
[FadeInLevelLoader.cs]
using UnityEngine;
using System.Collections;

public class FadeInLevelLoader : MonoBehaviour {
   
   Texture2D texture;
   Rect area;
   Timer timer;
   float alpha = 0f;
   bool load = false;   
   string levelName;
   
   public int Delay = 25;      // Intervalo de tiempo en milisegundos que determina la velocidad del fundido a negro.
   // Este campo se muestra en el inspector de Unity3D al seleccionar el GameObject que lo contiene.
   
   // Use this for initialization
   void Start()
   {
      texture = new Texture2D(1, 1);
      area = new Rect(0, 0, Screen.width, Screen.height);
      timer = new Timer();
   }
   
   // Update is called once per frame
   void Update()
   {
      if (load) {
         if (timer.Value >= Delay)
         {
            alpha += 0.025f;
            if (alpha > 1f)
            {
               Application.LoadLevel(levelName);
            }
               
            timer.Reset();
         }
      }
   }
   
   void OnGUI()
   {
      if (load)
      {
         // Dibuja un quad mediante la API de GUI:
         texture.SetPixel(0, 0, new Color(0, 0, 0, alpha));
         texture.Apply();
         GUI.skin.box.normal.background = texture;
         GUI.Box(area, GUIContent.none);
      }
   }

   // Metodo al que se invocara mediante un mensaje para iniciar el fundido a negro y la carga del nivel:
   public void LoadLevel(string level)
   {
      load = true;
      levelName = level;
      timer.Reset();
   }
}

Y el codigo de la clase Timer que uso yo para controlar los intervalos tiempos en mis proyectos y que usa el script anterior:
[Timer.cs]
using System;

/// <summary>
/// Cronometro de tiempo para calculos de intervalos.
/// </summary>
public class Timer
{
    #region Miembros privados
    private int delta;
    private int pauseDelta;
    private bool isPaused = false;
    #endregion

    #region Propiedades
    /// <summary>
    /// Indica si el cronometro esta en pausa.
    /// </summary>
    public bool IsPaused
    {
        get { return isPaused; }
    }

    /// <summary>
    /// Devuelve los milisegundos transcurridos desdel ultimo reinicio o desde que se creo el cronometro.
    /// </summary>
    public int Value
    {
        get
        {
            return (isPaused ? pauseDelta : System.Environment.TickCount) - delta;
        }
    }
    #endregion

    #region Constructores
    /// <summary>
    /// Crea una instancia de un cronometro.
    /// </summary>
    public Timer()
    {
        this.Reset();
    }
    #endregion

    #region Metodos y funciones
    /// <summary>
    /// Reinicia el cronometro a 0.
    /// </summary>
    public void Reset()
    {
        isPaused = false;
        delta = System.Environment.TickCount;
    }

    /// <summary>
    /// Pausa o reactiva el cronometro.
    /// </summary>
    public void Pause()
    {
        isPaused = !isPaused;
        if (isPaused)
            pauseDelta = System.Environment.TickCount;
        else
            delta += System.Environment.TickCount - pauseDelta;
    }
    #endregion
}


Ahora añade un GameObject vacio a la escena, llamalo "Loader", y agregale el script FadeInLevelLoader. Despues, cuando quieras cargar un nuevo nivel, haz esta llamada:
GameObject.Find("Loader").SendMessage("LoadLevel", "Nombre del nivel");

Esto iniciara el fundido a negro y al terminar iniciara la carga del nuevo nivel. Para que te sea más facil reutilizar en otros niveles este sistema, crea un prefab con ello, asi las proximas veces solo tendras que añadir el prefab a la escena y listos.

Salu2...
Título: Re:Fundido a negro al cambiar de nivel
Publicado por: Totemalf en 10 de Septiembre de 2013, 11:34:14 AM
Wow!
Fantástico, y en c#... y con comentarios... me viene de lujo para colocarlo ahora y para aprenderlo después, muchas gracias EX3.

Un saludo!!
Título: Re:Fundido a negro al cambiar de nivel
Publicado por: Totemalf en 10 de Septiembre de 2013, 01:33:28 PM
Funciona Deluxe! He aquí la prueba:
https://dl.dropboxusercontent.com/u/5843458/Menuprueba/Menu.html
Título: Re:Fundido a negro al cambiar de nivel
Publicado por: [EX3] en 11 de Septiembre de 2013, 01:10:05 AM
Cita de: Totemalf en 10 de Septiembre de 2013, 11:34:14 AM
Wow!
Fantástico, y en c#... y con comentarios... me viene de lujo para colocarlo ahora y para aprenderlo después, muchas gracias EX3.
De nada, me alegro de que te sea útil :)

Salu2...