【问题标题】:How to fade out and destroy audio on load如何在加载时淡出和破坏音频
【发布时间】:2019-09-06 12:06:02
【问题描述】:

我有一个基本脚本,允许音乐从场景 2 继续播放到场景 6,但我大部分时间都在尝试让它在音频开始淡出然后在场景 6 被破坏的地方,在加载到场景 7 之前。

我在这里、google、youtube 甚至 Unity 论坛上进行了搜索,但没有任何效果,因为我在搜索中得到的只是如何让音乐继续播放

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Music : MonoBehaviour
{
    // Start is called before the first frame update

    public GameObject theManager;
    public AudioSource music;
    public string loadLevel;
    public float fadeOutTime = 3f;
    bool fading;
    float fadePerSec;

    void Awake()
    {

        DontDestroyOnLoad(theManager);
        SceneManager.sceneLoaded += OnSceneLoaded;
    }

    void OnDestroy()
    {
        SceneManager.sceneLoaded -= OnSceneLoaded;
    }

    void Update()
    {
        if (fading)
        {
            music.volume = Mathf.MoveTowards(
            music.volume, 0, fadePerSec * Time.deltaTime);
        }
    }
    void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        if ((scene.buildIndex != 2) && (scene.buildIndex != 3) && (scene.buildIndex != 4) && (scene.buildIndex != 5) && (scene.buildIndex != 6))
        {
            fading = true;
            fadePerSec = music.volume / fadeOutTime;
            Destroy(theManager, fadeOutTime);
        }

    }
}

这是我项目的 2 个屏幕截图

项目布局

ScriptManager 的检查员

任何帮助表示赞赏并提前感谢

【问题讨论】:

  • if ((scene.buildIndex != 2) && (scene.buildIndex != 3) && (scene.buildIndex != 4) && (scene.buildIndex != 5) && (scene.buildIndex != 6)) 我当然不知道你的构建索引,但如果你说你希望它发生在 Scene6 中 - 我希望基于 0 的 buildIndex 是 5。因此,您的检查可能应该简单地阅读if(scene.buildIndex == 5) { ... },否则它可能已经发生在 Scene2 中(我希望基于 0 的 buildIndex 为 == 1
  • 你也这样做DontDestroyOnLoad(theManager); ..但是你也DontDestroyOnLoad这个类本身......否则切换场景时它会被破坏所以......不再回调?
  • @derHugo 删除 DontDestroyOnLoad(theManager); 意味着音乐不会继续,并且在您关注您的第一条评论时也没有任何变化。这是我的项目布局的构建索引的屏幕截图imgur.com/WihwEn1
  • 我没有说为theManager 删除它.. 但是脚本本身呢? ScriptManager 对象可能会在场景更改时被销毁
  • @derHugo 不,音乐一直持续到场景 7,我希望音乐淡出并在场景 6 上停止

标签: c# visual-studio unity3d audio


【解决方案1】:
  1. 主要问题:附加此脚本的 GameObject 已被销毁

    附有此脚本的ScriptManager GameObject 在您切换场景时被销毁!因此,OnSceneLoaded 可能根本就不会被调用。

  2. 那么我不会使用public GameObject theManager; 字段...您已经拥有public AudioSource music; 字段所以我宁愿在需要GameObject 引用时使用music.gameObject。只是为了避免错误。

  3. 最后,我不会使用Update 方法来不断地检查bool 标志,只是为了一次性事件。我建议宁愿使用Coroutine:

有点像

public class Music : MonoBehaviour
{
    public AudioSource music;
    public string loadLevel;
    public float fadeOutTime = 3f;

    private static Music _instance;

    void Awake()
    {
        DontDestroyOnLoad(music.gameObject);

        // If necessary use a singleton pattern to make sure this exists only once
        if(_instance)
        {
            Destroy(gameObject);
            return;
        }

        _instance = this;

        // Also don't destroy yourself!
        DontDestroyOnLoad(gameObject);

        // Just to be sure before adding a callback you should always remove it
        // This is valid even if it wasn't added yet
        // but it makes sure it is only added exactly once
        SceneManager.sceneLoaded -= OnSceneLoaded;
        SceneManager.sceneLoaded += OnSceneLoaded;
    }

    void OnDestroy()
    {
        SceneManager.sceneLoaded -= OnSceneLoaded;
    }

    private IEnumerator FadeOutAndDestroy()
    {
        var fadePerSec = music.volume / fadeOutTime;
        while(music.volume > 0)
        {
            music.volume = Mathf.MoveTowards(music.volume, 0, fadePerSec * Time.deltaTime);
            
            // yield says: Interupt the routine here, render this frame
            // and continue from here in the next frame
            // In other words: Coroutines are like small temporary Update methods
            yield return null;
        }

        // Now the volume is 0
        Destroy(music.gameObject);

        // and since no longer needed also destroy this object
        Destroy(gameObject);
    }

    void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        if (scene.buildIndex != 7) return;
        
        StartCoroutine(FadeOutAndDestroy());
    }
}

【讨论】:

  • 是的,我明白了,谢谢 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-05
相关资源
最近更新 更多