c# - 如何在加载时淡出和破坏音频
问题描述
我有一个基本脚本,允许音乐从场景 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 的检查员
任何帮助表示赞赏并提前感谢
解决方案
主要问题:附加此脚本的游戏对象被破坏
当您切换场景时,附加了此脚本的
ScriptManager
GameObject 将被销毁!因此可能根本就不会被调用。OnSceneLoaded
然后我不会使用该字段
public GameObject theManager;
......您已经拥有该字段public AudioSource music;
,所以我宁愿music.gameObject
在需要GameObject
参考时使用。只是为了避免错误。最后,我不会只为一次性事件使用不断
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());
}
}
推荐阅读
- microsoft-graph-api - Microsoft Graph API 错误:向中国端点发送请求时出现 PopAuthenticatorInvalidSignature
- api - Google Places API:是否可以访问一个地方的开放或永久关闭日期?
- angular - 如何翻译 .Ts 文件中的动态值?
- ruby-on-rails - 字体真棒图标未在 Rails 应用程序上呈现
- python - Python Pygame字体x坐标
- javascript - 如何使用javascript搜索和替换具有相同字体和颜色的pdf文件中的文本?
- python - 无法在图中插入顶点
- swagger - 在 OpenAPI 2.0(Swagger 2.0)中定义没有任何子属性的对象是否有效?
- sql - 按日期插入查询中的缺失值
- javascript - navigator.sendBeacon() 发送 Ping 请求