Приложение Unity3D VR: исчезает в другой сцене через определенное время - PullRequest
2 голосов
/ 07 марта 2019

Я пытаюсь разработать приложение для виртуальной реальности, в котором вы можете перемещаться и взаимодействовать с музыкой (перемещение источников звука и т. Д.). Таким образом, вы не можете умереть в этом приложении, и именно поэтому исчезновение черного на курке не поможет мне. Я пытаюсь добиться постепенного исчезновения черного и показывать титры через определенное время (особенно, когда музыка заканчивается). Может быть, даже затухание (чёрное) и затухание (в другую сцену, содержащую титры) сделают свое дело. Я очень мало знаю о программировании, поэтому я мог бы действительно использовать некоторую помощь. Я использую Unity3D 2018.2.9f1 Приложение для Samsung Gear VR

1 Ответ

2 голосов
/ 07 марта 2019

Таймер

Для любого материала, использующего таймеры или ожидание, я нахожу Сопрограммы в большинстве случаев лучшие варианты.

Вы можете получить длину аудиоклипа, а затем ждать его

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 и в основном делает

  1. Использует Overlay Canvas поверх всего с определенным цветом и анимирует его альфа-значение (снова используя сопрограмму)
  2. Обеспечивает, чтобы холст был DontDestroyOnLoad, поэтому он не удаляется при переключении сцен
  3. FadeIn the Canvas / Image => Затухает текущая сцена
  4. Загрузить другую сцену
  5. 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 на самом деле плохая идея - постепенно переходить в черный цвет и позволить пользователю ничего не видеть. Это может привести к дезориентации и кибербезопасности ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...