Таймер
Для любого материала, использующего таймеры или ожидание, я нахожу Сопрограммы в большинстве случаев лучшие варианты.
Вы можете получить длину аудиоклипа, а затем ждать его
public AudioClip clip;
private void Start()
{
StartCoroutine(Wait(clip.length));
}
private IEnumerator Wait(float seconds)
{
yield return new WaitForSeconds(seconds);
// start fadeout here
}
или вы можете подождать, пока он не закончит играть
public AudioSource source;
// or wherever you start the music adioclip
private void Start()
{
source.Play ();
yield return new WaitUntil(()=> !source.isPlaying);
// start fadeout here
}
Затухание
Здесь многое зависит ... Вы действительно переключаете Scene
s с помощью LoadScene
и т. Д. Или вы просто хотите включить / отключить определенный контент в одной сцене?
А у вас есть 3D-объекты с материалами и средствами визуализации или только 2D-контент с использованием компонентов Unity.UI?
Самым простым решением наверняка было бы поместить один оверлейный холст с желаемым цветом в качестве изображения и просто постепенно увеличивать и уменьшать его. Это на самом деле уже доступно в AssetStore и в основном делает
- Использует Overlay Canvas поверх всего с определенным цветом и анимирует его альфа-значение (снова используя сопрограмму)
- Обеспечивает, чтобы холст был
DontDestroyOnLoad
, поэтому он не удаляется при переключении сцен
- FadeIn the Canvas / Image => Затухает текущая сцена
- Загрузить другую сцену
- FadeOut the Canvas / Image => Исчезает в новой сцене
Вот исходный код (только немного его почистил)
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Fader : MonoBehaviour
{
private string _fadeScene;
private float _alpha;
private CanvasGroup _myCanvas;
private Image _bg;
private float _lastTime;
private bool _startedLoading;
private float _fadeInDuration;
//Set callback
private void OnEnable()
{
SceneManager.sceneLoaded -= OnLevelFinishedLoading;
SceneManager.sceneLoaded += OnLevelFinishedLoading;
}
//Remove callback
private void OnDisable()
{
SceneManager.sceneLoaded -= OnLevelFinishedLoading;
}
public void InitiateFader(CanvasGroup canvasGroup, Image image, string scene, Color fadeColor, float fadeInDuration, float fadeOutDuration)
{
DontDestroyOnLoad(gameObject);
_fadeInDuration = fadeInDuration;
_fadeScene = scene;
//Getting the visual elements
_myCanvas = canvasGroup;
_bg = image;
_bg.color = fadeColor;
//Checking and starting the coroutine
_myCanvas.alpha = 0.0f;
StartCoroutine(FadeIt(FadeDirection.Out, fadeOutDuration));
}
private enum FadeDirection
{
In,
Out
}
private IEnumerator FadeIt(FadeDirection fadeDirection, float fadeDuration)
{
var timePassed = 0.0f;
switch (fadeDirection)
{
case FadeDirection.Out:
do
{
_alpha = Mathf.Lerp(0, 1, timePassed / fadeDuration);
_myCanvas.alpha = _alpha;
timePassed += Time.deltaTime;
yield return null;
} while (timePassed < fadeDuration);
_alpha = 1;
SceneManager.LoadSceneAsync(_fadeScene);
break;
case FadeDirection.In:
do
{
_alpha = Mathf.Lerp(1, 0, timePassed / fadeDuration);
_myCanvas.alpha = _alpha;
timePassed += Time.deltaTime;
yield return null;
} while (timePassed < fadeDuration);
_alpha = 0;
Initiate.DoneFading();
Debug.Log("Your scene has been loaded , and fading in has just ended");
Destroy(gameObject);
break;
}
}
private void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode)
{
//We can now fade in
StartCoroutine(FadeIt(FadeDirection.In, _fadeInDuration));
}
}
и
public static class Initiate
{
private static bool areWeFading;
//Create Fader object and assing the fade scripts and assign all the variables
public static void Fade(string scene, Color col, float fadeOutDuration, float fadeInDuration)
{
if (areWeFading)
{
Debug.Log("Already Fading");
return;
}
var init = new GameObject("Fader", typeof(Canvas), typeof(CanvasGroup), typeof(Image), typeof(Fader));
init.GetComponent<Canvas>().renderMode = RenderMode.ScreenSpaceOverlay;
var fader = init.GetComponent<Fader>();
areWeFading = true;
fader.InitiateFader(init.GetComponent<CanvasGroup>(), init.GetComponent<Image>(), scene, col, fadeOutDuration, fadeInDuration);
}
public static void DoneFading()
{
areWeFading = false;
}
}
чем Вы называете это в выделенном компоненте, например, для возможности сделать это, например. в кнопке onClick
public class DemoScript : MonoBehaviour
{
//name of the scene you want to load
public string TargetSceneName;
public Color LoadToColor = Color.black;
public float FadeInDuration = 1.0f;
public float FadeOutDuration = 1.0f;
public void GoFade()
{
Initiate.Fade(TargetSceneName, LoadToColor, FadeOutDuration, FadeInDuration);
}
}
или поскольку он статический, просто используйте
Initiate.Fade(TargetSceneName, LoadToColor, FadeOutDuration, FadeInDuration);
откуда угодно.
Вместо LoadSceneAsync
вы также можете включить или отключить, если вы предпочитаете делать это только в одной сцене.
Однако в VR на самом деле плохая идея - постепенно переходить в черный цвет и позволить пользователю ничего не видеть. Это может привести к дезориентации и кибербезопасности ...