162 lines
5.3 KiB
C#
162 lines
5.3 KiB
C#
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
public static class BgmRuntimeBootstrap
|
|
{
|
|
private const string RuntimeAudioListenerName = "__RuntimeAudioListener";
|
|
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
|
|
private static void Bootstrap()
|
|
{
|
|
var mgr = BgmPlaybackManager.EnsureInstance();
|
|
mgr.EnsurePlaying();
|
|
EnsureAudioListener(SceneManager.GetActiveScene());
|
|
|
|
// Ensure UI binder exists
|
|
if (Object.FindAnyObjectByType<BgmUiBinder>() == null)
|
|
{
|
|
var go = new GameObject("BGM_UI_Binder");
|
|
go.AddComponent<BgmUiBinder>();
|
|
Object.DontDestroyOnLoad(go);
|
|
}
|
|
|
|
RemoveBgmParticlesInLoadedScenes();
|
|
SceneManager.sceneLoaded -= OnSceneLoaded;
|
|
SceneManager.sceneLoaded += OnSceneLoaded;
|
|
}
|
|
|
|
private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
|
{
|
|
EnsureAudioListener(scene);
|
|
RemoveBgmParticlesInLoadedScenes();
|
|
}
|
|
|
|
private static void RemoveBgmParticlesInLoadedScenes()
|
|
{
|
|
var emitters = Object.FindObjectsByType<BgmParticleEmitter>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
|
for (int i = 0; i < emitters.Length; i++)
|
|
{
|
|
var e = emitters[i];
|
|
if (e == null) continue;
|
|
if (!e.gameObject.scene.IsValid() || !e.gameObject.scene.isLoaded) continue;
|
|
Object.Destroy(e.gameObject);
|
|
}
|
|
|
|
var all = Resources.FindObjectsOfTypeAll<Transform>();
|
|
for (int i = 0; i < all.Length; i++)
|
|
{
|
|
var t = all[i];
|
|
if (t == null) continue;
|
|
if (!t.gameObject.scene.IsValid() || !t.gameObject.scene.isLoaded) continue;
|
|
if (t.name.Equals("BgmParticles", System.StringComparison.OrdinalIgnoreCase))
|
|
Object.Destroy(t.gameObject);
|
|
}
|
|
}
|
|
|
|
private static void EnsureAudioListener(Scene scene)
|
|
{
|
|
if (!scene.IsValid() || !scene.isLoaded)
|
|
return;
|
|
|
|
AudioListener[] allListeners = Object.FindObjectsByType<AudioListener>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
|
|
|
AudioListener activeEnabledInScene = null;
|
|
AudioListener activeInScene = null;
|
|
AudioListener anyInScene = null;
|
|
|
|
for (int i = 0; i < allListeners.Length; i++)
|
|
{
|
|
AudioListener listener = allListeners[i];
|
|
if (listener == null)
|
|
continue;
|
|
if (!listener.gameObject.scene.IsValid() || listener.gameObject.scene != scene)
|
|
continue;
|
|
|
|
if (anyInScene == null)
|
|
anyInScene = listener;
|
|
|
|
if (listener.gameObject.activeInHierarchy && activeInScene == null)
|
|
activeInScene = listener;
|
|
|
|
if (listener.gameObject.activeInHierarchy && listener.enabled)
|
|
{
|
|
activeEnabledInScene = listener;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (activeEnabledInScene != null)
|
|
return;
|
|
|
|
if (activeInScene != null)
|
|
{
|
|
activeInScene.enabled = true;
|
|
return;
|
|
}
|
|
|
|
if (anyInScene != null)
|
|
{
|
|
anyInScene.enabled = true;
|
|
return;
|
|
}
|
|
|
|
Camera cameraInScene = FindBestCameraInScene(scene);
|
|
if (cameraInScene != null)
|
|
{
|
|
AudioListener cameraListener = cameraInScene.GetComponent<AudioListener>();
|
|
if (cameraListener == null)
|
|
cameraListener = cameraInScene.gameObject.AddComponent<AudioListener>();
|
|
cameraListener.enabled = true;
|
|
return;
|
|
}
|
|
|
|
GameObject listenerRoot = FindNamedObjectInScene(scene, RuntimeAudioListenerName);
|
|
if (listenerRoot == null)
|
|
{
|
|
listenerRoot = new GameObject(RuntimeAudioListenerName);
|
|
try { SceneManager.MoveGameObjectToScene(listenerRoot, scene); } catch { }
|
|
}
|
|
if (listenerRoot.GetComponent<AudioListener>() == null)
|
|
listenerRoot.AddComponent<AudioListener>();
|
|
}
|
|
|
|
private static Camera FindBestCameraInScene(Scene scene)
|
|
{
|
|
Camera[] cameras = Object.FindObjectsByType<Camera>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
|
Camera first = null;
|
|
for (int i = 0; i < cameras.Length; i++)
|
|
{
|
|
Camera cam = cameras[i];
|
|
if (cam == null || cam.gameObject.scene != scene)
|
|
continue;
|
|
|
|
if (first == null)
|
|
first = cam;
|
|
|
|
if (cam.gameObject.activeInHierarchy && cam.enabled && cam.CompareTag("MainCamera"))
|
|
return cam;
|
|
}
|
|
|
|
if (first != null)
|
|
return first;
|
|
return null;
|
|
}
|
|
|
|
private static GameObject FindNamedObjectInScene(Scene scene, string objectName)
|
|
{
|
|
if (string.IsNullOrEmpty(objectName))
|
|
return null;
|
|
|
|
Transform[] all = Object.FindObjectsByType<Transform>(FindObjectsInactive.Include, FindObjectsSortMode.None);
|
|
for (int i = 0; i < all.Length; i++)
|
|
{
|
|
Transform t = all[i];
|
|
if (t == null || t.gameObject.scene != scene)
|
|
continue;
|
|
if (string.Equals(t.name, objectName, System.StringComparison.OrdinalIgnoreCase))
|
|
return t.gameObject;
|
|
}
|
|
return null;
|
|
}
|
|
}
|