Unity3D VR应用程序:一定时间后淡入另一个场景

时间:2019-03-07 14:21:24

标签: unity3d

我正在尝试开发一个VR应用程序,您可以在其中移动并与音乐互动(移动音频源,等等)。因此,您实际上无法在此应用程序中死亡,这就是为什么触发时淡化为黑色对我无济于事。我正尝试逐渐淡化为黑色,并在一定时间后(特别是音乐结束时)显示字幕。甚至淡出(黑色)和淡入(到包含字幕的另一个场景)也可以解决问题。我对编程了解甚少,所以我真的可以使用一些帮助。 我正在使用Unity3D 2018.2.9f1 该应用程序适用于三星的Gear VR

1 个答案:

答案 0 :(得分:2)

计时器

对于使用计时器或等待的任何事情,我大多数时候都发现Coroutines是最好的选择。

您可以获取音频剪辑的长度,然后等待

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等切换LoadScene,还是只想在一个场景中启用/禁用某些内容?

使用Unity.UI组件,您是否具有包含材质和渲染器的3D对象或仅包含2D内容?

最简单的解决方案肯定是将一个具有所需颜色的叠加Canvas放置为Image,然后简单地将其淡入和淡出。 AssetStore中实际上已经提供了该功能,并且

  1. 在具有特定颜色的所有物体上使用“覆盖画布”,并对其alpha值进行动画处理(再次使用协程)
  2. 确保画布为DontDestroyOnLoad,以便在切换场景时不会将其删除
  3. 淡入画布/图像=>淡出当前场景
  4. 加载其他场景
  5. 淡出画布/图像=>在新场景中淡出

这是源代码(只需将其清理一点)

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;
    }
}

than您可以在专用组件中称呼它,例如为了能够做到这一点,例如在按钮的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中,褪色为全黑并让用户看不到东西实际上是一个坏主意。可能会导致迷失方向和晕车...