Плавный переход между сценами Fade InOut

Играя в игры, Вы наверняка замечали, что перед загрузкой следующей карты, с начала мы видим плавное затемнение экрана. А после загрузки, наоборот. В Unity, когда вызываешь функцию загрузки сцены, изображение на экране просто «замирает», пока идет загрузка. Нам нужно написать скрипт так, чтобы загрузка начиналась только после затемнения экрана, кроме того, необходимо так-же, чтоб затемнялись все элементы UI, которые всегда поверх обычных игровых объектов. Дополнительно наш скрипт будет скрывать курсор экрана, если сцена еще не готова, хотя это не всегда удобно, кому не нужно, исправить просто.

Создаем С# скрипт FadeInOut

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class FadeInOut : MonoBehaviour {
	
	public static bool sceneEnd;
	public float fadeSpeed = 1.5f;
	public int nextLevel;
	private Image _image;
	private bool sceneStarting;

	void Awake ()
	{
		_image = GetComponent<Image>();
		_image.enabled = true;
		sceneStarting = true;
		sceneEnd = false;
		Cursor.visible = false;
	}

	void Update ()
	{
		if(sceneStarting) StartScene();
		if(sceneEnd) EndScene();
	}

	void StartScene ()
	{
		_image.color = Color.Lerp(_image.color, Color.clear, fadeSpeed * Time.deltaTime);

		if(_image.color.a <= 0.01f)
		{
			_image.color = Color.clear;
			_image.enabled = false;
			sceneStarting = false;
			Cursor.visible = true;
		}
	}

	void EndScene ()
	{
		_image.enabled = true;
		_image.color = Color.Lerp(_image.color, Color.black, fadeSpeed * Time.deltaTime);

		if(_image.color.a >= 0.95f)
		{
			Cursor.visible = false;
			_image.color = Color.black;
			Application.LoadLevel(nextLevel);
		}
	}
}

Разберемся, что и как. Переменная sceneEnd используется для перехода на следующую сцену, в любом другом скрипте достаточно написать:

FadeInOut.sceneEnd = true;

И всё.

nextLevel - здесь нужно указать следующую сцену, конкретно id. Если хотите указывать по имени, тогда надо изменить переменную:

public string nextLevel;

Далее, Cursor.visible это показывать или не показывать курсор, если Вам нужно чтобы курсор был виден всегда, то удалите соответствующие строки.



Настроим саму сцену. Создаем GameObject -> UI -> Image. Нажмите на переключатель 2D в окне редактора, это нужно чтобы удобней было редактировать элементы UI, после, переключите обратно. И еще надо перекрасить сразу наше изображение в черный цвет.


Не забудьте повесить скрипт на изображение.

Надо растянуть изображение на весь экран и установить якоря, чтобы картинка меняла разрешение, в зависимости от разрешения экрана.


Осталось убрать галочку с Image иначе будет мешать работать дальше.

Плавный переход между сценами Fade InOut

Всё, можно пробовать!

Осталось уточнить некоторые детали. Чтобы всё работало как полагается, на сцене либо не должно быть других элементов UI, либо наша картинка должна быть поверх всех остальных элементов, например:


Вот, как-то так...

Комментариев 4

Офлайн
myroslav 19 марта 2016
Офигенный сайт, спасибо! Когда буду иметь прибыль из собственных игр - обязательно брошу вам Донат! Спасибо за большую работу!
Офлайн
Louren325 21 апреля 2017
Хороший скрипт, но пришлось повозиться с ним:
Если пытаться быстро сменить уровень (до полной прогрузки), то экран начинал темнеть, останавливался на половине и ничего дальше не происходило.
Прочитал в вашем https://null-code.ru/solution/95-plavnoe-zatemnenie-ekrana-zalivka-cvetom.html что переход возможен только когда предыдущий запрос полностью выполняется.
Покопался и пришёл к выводу, что всё ломается если переменная sceneStarting имеет состояние true. Немного изменил код. Переменную sceneStarting сделал
public static bool sceneStarting, это позволило в других скриптах использовать код вида
if (Input.GetKey (KeyCode.Tab) && FadeInOut.sceneStarting == false)
{
FadeInOut.sceneEnd = true;
}
Что не позволит менять уровень раньше полной прогрузки UI и запарывать переход.

Версия юнити http://puu.sh/vqYCN/d056eae706.png
Если будет интересно - могу записать видео, как всё багается с точной копией этого скрипта.
Офлайн
Зачем так мучиться?
Можно просто создать экранный эффект с шейдером, меняющий изображение с камеры путём вычитания из пикселей экрана некоторое значение(float BlackAmoung), ведь известно, что для каждого пикселя(1- белый, 0- черный)

Код для шейдера:
Shader "ER_Shaders/Fogging"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_blackAmoung ("BlackAmoung", Range(0,1)) = 0.5
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"

uniform sampler2D _MainTex;
fixed _blackAmoung;

float3 BlackOutFunc(float3 baseColor, float black)
{
float3 conColor = float3(baseColor.r - black, baseColor.g - black, baseColor.b - black);
return conColor;
}

fixed4 frag (v2f_img i) : Color
{
fixed4 renderTex = tex2D(_MainTex, i.uv);
renderTex.rgb = BlackOutFunc(renderTex.rgb, _blackAmoung);
return renderTex;
}
ENDCG
}
//Creator - ERESTOgameCompany
}
}

Для управления шейдером копируем это:
using System;
using UnityEngine;

public class Fogging : UnityStandardAssets.ImageEffects.ImageEffectBase {

[ExecuteInEditMode]
public float BlackAmoung = 0f;
private bool isBlinkOp = false;

private void Update()
{
BlackAmoung = Mathf.Clamp(BlackAmoung, 0f, 1f);
}

public void BlackOut()
{
BlackOut(1f);
}


public void BlackOut(float speed)
{
if (BlackAmoung < 1f)
{
BlackAmoung += speed * Time.deltaTime;
}
}

public void Blinking()
{
Blinking(1f);
}

public void Blinking(float speed)
{
if (BlackAmoung == 0f)
{
isBlinkOp = false;
}
else if (BlackAmoung == 1f)
{
isBlinkOp = true;
}

if (isBlinkOp == false)
{
BlackAmoung += speed * Time.deltaTime;
}
else
{
BlackAmoung -= speed * Time.deltaTime;
}
}

private void OnRenderImage (RenderTexture source, RenderTexture destination)
{
material.SetFloat("_blackAmoung", BlackAmoung);
Graphics.Blit (source, destination, material);
}
//Creator - ERESTOgameCompany
}

Blinking - метод, имитирующий эффект моргания;
BlackOut - метод, имитирующий эффект затемнения.
Офлайн
ERESTOgameCompany,
я бы вообще наверно создал бы анимацию и на конце поставил событие с переходом сцены )
Информация
Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.
  • Яндекс.Метрика