UI换了很多,spine主视觉停用

This commit is contained in:
2026-06-15 20:17:25 +08:00
parent 5eec879582
commit 216ab08e8d
3634 changed files with 814422 additions and 382766 deletions
+178 -15
View File
@@ -11,10 +11,16 @@ public class BgmPlaybackManager : MonoBehaviour
{
public static BgmPlaybackManager Instance { get; private set; }
private const string MainSceneName = "Main_main";
private const string GameplaySceneName = "gamePlay_gamePlay";
private const string BeforeEverythingSceneName = "beforeEverything";
[Header("Audio")]
public AudioSource audioSource;
public AudioMixerGroup outputMixerGroup;
public AudioClip clip;
[Tooltip("Optional Music_Data resource path for the lobby BGM. Example: Data/Music/allAlong")]
public string musicDataResourcePath = "Data/Music/allAlong";
[Tooltip("Optional playlist. If empty, will load all clips in Resources/BGM.")]
public List<AudioClip> playlist = new List<AudioClip>();
public int startIndex = 0;
@@ -29,6 +35,7 @@ public class BgmPlaybackManager : MonoBehaviour
private bool isLoading = false;
private int currentIndex = 0;
private Coroutine loadClipRoutine;
public static BgmPlaybackManager EnsureInstance()
{
@@ -38,6 +45,12 @@ public class BgmPlaybackManager : MonoBehaviour
return Instance;
}
public void SetOutputMixerGroup(AudioMixerGroup mixerGroup)
{
outputMixerGroup = mixerGroup;
ApplyOutputMixerGroup();
}
private void Awake()
{
if (Instance != null && Instance != this)
@@ -51,8 +64,7 @@ public class BgmPlaybackManager : MonoBehaviour
if (audioSource == null)
audioSource = gameObject.AddComponent<AudioSource>();
if (outputMixerGroup != null)
audioSource.outputAudioMixerGroup = outputMixerGroup;
ApplyOutputMixerGroup();
audioSource.playOnAwake = false;
audioSource.loop = loop;
@@ -66,11 +78,14 @@ public class BgmPlaybackManager : MonoBehaviour
currentIndex = Mathf.Clamp(startIndex, 0, playlist.Count - 1);
clip = playlist[currentIndex];
}
else if (clip == null)
{
ResolveDefaultClip();
}
if (clip != null)
audioSource.clip = clip;
if (autoPlay)
EnsurePlaying();
SyncPlaybackForScene(SceneManager.GetActiveScene());
}
private void OnEnable()
@@ -81,34 +96,83 @@ public class BgmPlaybackManager : MonoBehaviour
private void OnDisable()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
StopLobbyAudioAndParticles();
}
private void OnDestroy()
{
StopLobbyAudioAndParticles();
if (Instance == this)
{
Instance = null;
}
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (stopOnGameplayScene && scene.name == gameplaySceneName)
SyncPlaybackForScene(scene);
}
private void OnApplicationQuit()
{
StopLobbyAudioAndParticles();
}
private void SyncPlaybackForScene(Scene scene)
{
if (!ShouldPlayInScene(scene.name))
{
StopLobbyAudioAndParticles();
return;
}
// Ensure lobby/select scenes resume BGM after returning from gameplay.
if (autoPlay)
// Allowed scenes should keep the lobby BGM alive.
if (audioSource == null || !audioSource.isPlaying)
EnsurePlaying();
}
private bool ShouldPlayInScene(string sceneName)
{
if (string.IsNullOrEmpty(sceneName))
return false;
if (string.Equals(sceneName, GameplaySceneName, StringComparison.OrdinalIgnoreCase))
return false;
if (string.Equals(sceneName, MainSceneName, StringComparison.OrdinalIgnoreCase))
return false;
if (string.Equals(sceneName, BeforeEverythingSceneName, StringComparison.OrdinalIgnoreCase))
return false;
return true;
}
public void EnsurePlaying()
{
if (!ShouldPlayInScene(SceneManager.GetActiveScene().name))
{
StopLobbyAudioAndParticles();
return;
}
if (audioSource == null)
audioSource = gameObject.AddComponent<AudioSource>();
if (outputMixerGroup != null)
audioSource.outputAudioMixerGroup = outputMixerGroup;
ApplyOutputMixerGroup();
audioSource.loop = loop;
if (audioSource.clip == null && clip != null)
audioSource.clip = clip;
if (audioSource.clip == null)
{
ResolveDefaultClip();
if (audioSource.clip == null && clip != null)
audioSource.clip = clip;
}
if (audioSource.clip == null)
{
EnsurePlaylist();
@@ -121,7 +185,9 @@ public class BgmPlaybackManager : MonoBehaviour
if (audioSource.clip == null && !isLoading)
{
StartCoroutine(LoadClipRoutine());
if (loadClipRoutine != null)
StopCoroutine(loadClipRoutine);
loadClipRoutine = StartCoroutine(LoadClipRoutine());
return;
}
@@ -133,6 +199,11 @@ public class BgmPlaybackManager : MonoBehaviour
{
isLoading = true;
if (audioSource.clip == null)
{
ResolveDefaultClip();
}
// Try Resources first
if (audioSource.clip == null && !string.IsNullOrEmpty(resourcesPath))
{
@@ -149,9 +220,9 @@ public class BgmPlaybackManager : MonoBehaviour
string path = fallbackFilePath;
if (string.IsNullOrEmpty(path))
{
// Default to project root /??/Bansonic OST.mp3
// Default to the checked-in lobby track in Assets/BGM.
var projectRoot = Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
path = Path.Combine(projectRoot, "??", "Bansonic OST.mp3");
path = Path.Combine(projectRoot, "Assets", "BGM", "Bansonic OST.mp3");
}
if (File.Exists(path))
@@ -170,8 +241,19 @@ public class BgmPlaybackManager : MonoBehaviour
isLoading = false;
if (autoPlay && audioSource.clip != null && !audioSource.isPlaying)
if (!ShouldPlayInScene(SceneManager.GetActiveScene().name))
{
StopLobbyAudioAndParticles();
yield break;
}
if (audioSource.clip != null && !audioSource.isPlaying)
audioSource.Play();
if (loadClipRoutine != null)
{
loadClipRoutine = null;
}
}
private void EnsurePlaylist()
@@ -181,6 +263,12 @@ public class BgmPlaybackManager : MonoBehaviour
if (playlist.Count == 0)
{
if (ResolveDefaultClip(out AudioClip defaultClip))
{
playlist.Add(defaultClip);
return;
}
var clips = Resources.LoadAll<AudioClip>("BGM");
if (clips != null && clips.Length > 0)
{
@@ -190,8 +278,60 @@ public class BgmPlaybackManager : MonoBehaviour
}
}
private void ResolveDefaultClip()
{
if (clip != null)
{
audioSource.clip = clip;
return;
}
if (ResolveDefaultClip(out AudioClip resolved))
{
clip = resolved;
audioSource.clip = resolved;
}
}
private bool ResolveDefaultClip(out AudioClip resolved)
{
resolved = null;
if (!string.IsNullOrEmpty(musicDataResourcePath))
{
var musicData = Resources.Load<Music_Data>(musicDataResourcePath);
if (musicData != null && musicData.Clip != null)
{
resolved = musicData.Clip;
return true;
}
}
var musicDatas = Resources.LoadAll<Music_Data>("Data/Music");
if (musicDatas != null)
{
for (int i = 0; i < musicDatas.Length; i++)
{
var data = musicDatas[i];
if (data != null && data.Clip != null)
{
resolved = data.Clip;
return true;
}
}
}
return false;
}
public void PlayIndex(int index)
{
if (!ShouldPlayInScene(SceneManager.GetActiveScene().name))
{
StopLobbyAudioAndParticles();
return;
}
EnsurePlaylist();
if (playlist == null || playlist.Count == 0)
return;
@@ -224,6 +364,11 @@ public class BgmPlaybackManager : MonoBehaviour
{
if (audioSource == null || audioSource.clip == null)
return;
if (!ShouldPlayInScene(SceneManager.GetActiveScene().name))
{
StopLobbyAudioAndParticles();
return;
}
if (audioSource.isPlaying)
audioSource.Pause();
else
@@ -232,9 +377,27 @@ public class BgmPlaybackManager : MonoBehaviour
private void StopLobbyAudioAndParticles()
{
if (audioSource != null)
audioSource.Stop();
if (loadClipRoutine != null)
{
StopCoroutine(loadClipRoutine);
loadClipRoutine = null;
}
isLoading = false;
if (audioSource != null)
{
audioSource.Stop();
}
}
private void ApplyOutputMixerGroup()
{
if (audioSource != null)
{
audioSource.outputAudioMixerGroup = outputMixerGroup;
}
}
public float CurrentTime => audioSource != null ? audioSource.time : 0f;
+8 -1
View File
@@ -12,11 +12,16 @@ public static class BgmRuntimeBootstrap
private static void Bootstrap()
{
var mgr = BgmPlaybackManager.EnsureInstance();
var controller = SceneObjectLookupCache.FindAny<btmandtopController>();
if (controller != null && controller.bgmMixerGroup != null)
{
mgr.SetOutputMixerGroup(controller.bgmMixerGroup);
}
mgr.EnsurePlaying();
EnsureAudioListener(SceneManager.GetActiveScene());
// Ensure UI binder exists
if (Object.FindAnyObjectByType<BgmUiBinder>() == null)
if (SceneObjectLookupCache.FindAny<BgmUiBinder>() == null)
{
var go = new GameObject("BGM_UI_Binder");
go.AddComponent<BgmUiBinder>();
@@ -31,6 +36,8 @@ public static class BgmRuntimeBootstrap
private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
EnsureAudioListener(scene);
var mgr = BgmPlaybackManager.Instance ?? BgmPlaybackManager.EnsureInstance();
mgr.EnsurePlaying();
RemoveBgmParticlesInLoadedScenes();
}
+12 -7
View File
@@ -124,10 +124,14 @@ public class BgmSpectrumVisualizer : MonoBehaviour
source.GetSpectrumData(spectrum, 0, fftWindow);
for (int i = 0; i < bars; i++)
int barCount = bars;
int barDenominator = Mathf.Max(1, barCount - 1);
int spectrumDenominator = Mathf.Max(1, spectrumSize - 1);
for (int i = 0; i < barCount; i++)
{
float t = (float)i / (bars - 1);
int idx = Mathf.Clamp(Mathf.RoundToInt(Mathf.Lerp(1, spectrumSize - 1, t * t)), 1, spectrumSize - 1);
float t = (float)i / barDenominator;
int idx = Mathf.Clamp(Mathf.RoundToInt(Mathf.Lerp(1, spectrumDenominator, t * t)), 1, spectrumDenominator);
float v = Mathf.Max(0f, spectrum[idx] - noiseFloor) * amplitude;
float baseHeight = Mathf.Clamp01(v) * maxHeight;
@@ -179,12 +183,13 @@ public class BgmSpectrumVisualizer : MonoBehaviour
DestroyImmediate(child.gameObject);
}
int barCount = bars;
spectrum = new float[Mathf.Max(64, spectrumSize)];
barRects = new RectTransform[bars];
barHeights = new float[bars];
barBasePos = new Vector2[bars];
barRects = new RectTransform[barCount];
barHeights = new float[barCount];
barBasePos = new Vector2[barCount];
for (int i = 0; i < bars; i++)
for (int i = 0; i < barCount; i++)
{
var bar = Instantiate(barPrefab, transform);
bar.gameObject.SetActive(true);
+46 -19
View File
@@ -49,6 +49,8 @@ public class BgmUiBinder : MonoBehaviour
public string gameplaySceneName = "gamePlay_gamePlay";
[Tooltip("Main menu scene name where spectrum should be hidden.")]
public string mainSceneName = "Main_main";
[Tooltip("Startup/EULA scene name where spectrum should be hidden.")]
public string beforeEverythingSceneName = "beforeEverything";
public bool hideSpectrumInMainScene = true;
public float musicPicFadeDuration = 0.3f;
public bool useUnscaledTime = true;
@@ -93,15 +95,15 @@ public class BgmUiBinder : MonoBehaviour
}
private string _cachedGameplaySceneName;
private bool _isGameplayScene;
private bool _spectrumHiddenInGameplay = false;
private bool _shouldHideSpectrumForCurrentScene;
private bool _spectrumHiddenForCurrentScene = false;
private void OnEnable()
{
SceneManager.sceneLoaded += OnSceneLoaded;
_cachedGameplaySceneName = gameplaySceneName;
_isGameplayScene = SceneManager.GetActiveScene().name == _cachedGameplaySceneName;
_spectrumHiddenInGameplay = false;
_shouldHideSpectrumForCurrentScene = ShouldHideSpectrumInScene(SceneManager.GetActiveScene().name);
_spectrumHiddenForCurrentScene = false;
_buttonsBound = false;
Bind();
ApplyDefaultMusicPicVisibility(SceneManager.GetActiveScene().name);
@@ -109,7 +111,7 @@ public class BgmUiBinder : MonoBehaviour
{
var mgr = BgmPlaybackManager.EnsureInstance();
if (outputMixerGroup != null)
mgr.outputMixerGroup = outputMixerGroup;
mgr.SetOutputMixerGroup(outputMixerGroup);
mgr.EnsurePlaying();
}
}
@@ -121,8 +123,8 @@ public class BgmUiBinder : MonoBehaviour
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
_isGameplayScene = scene.name == _cachedGameplaySceneName;
_spectrumHiddenInGameplay = false;
_shouldHideSpectrumForCurrentScene = ShouldHideSpectrumInScene(scene.name);
_spectrumHiddenForCurrentScene = false;
_buttonsBound = false;
Bind();
ApplyDefaultMusicPicVisibility(scene.name);
@@ -134,10 +136,15 @@ public class BgmUiBinder : MonoBehaviour
hasExplicitMusicRoot = false;
Canvas sceneCanvas = FindSceneCanvas();
var controller = Object.FindAnyObjectByType<btmandtopController>();
var controller = SceneObjectLookupCache.FindAny<btmandtopController>();
if (controller != null && controller.bgmMixerGroup != null)
{
outputMixerGroup = controller.bgmMixerGroup;
if (Application.isPlaying)
{
var mgr = BgmPlaybackManager.Instance ?? BgmPlaybackManager.EnsureInstance();
mgr.SetOutputMixerGroup(outputMixerGroup);
}
}
if (controller != null && controller.musicPicRoot != null)
@@ -146,7 +153,7 @@ public class BgmUiBinder : MonoBehaviour
return;
}
RectTransform persistentMusic = null;
var persistentCanvasGo = GameObject.Find(musicPicCanvasName);
var persistentCanvasGo = SceneObjectLookupCache.Find(musicPicCanvasName);
if (!keepMusicPicAcrossScenes && persistentCanvasGo != null)
{
if (Application.isPlaying)
@@ -202,7 +209,7 @@ public class BgmUiBinder : MonoBehaviour
if (musicRoot == null)
{
var canvas = Object.FindAnyObjectByType<Canvas>();
var canvas = SceneObjectLookupCache.FindAny<Canvas>();
if (canvas != null)
musicRoot = canvas.GetComponent<RectTransform>();
}
@@ -332,7 +339,7 @@ public class BgmUiBinder : MonoBehaviour
}
if (timeRoot == null)
{
var timeGo = GameObject.Find(timeRootName);
var timeGo = SceneObjectLookupCache.Find(timeRootName);
if (timeGo != null) timeRoot = timeGo.transform;
}
@@ -385,16 +392,17 @@ public class BgmUiBinder : MonoBehaviour
}
private bool _buttonsBound = false;
private string _cachedMusicRootNameNormalized;
private void Update()
{
if (!Application.isPlaying)
return;
if (_isGameplayScene && !_spectrumHiddenInGameplay)
if (_shouldHideSpectrumForCurrentScene && !_spectrumHiddenForCurrentScene)
{
HideSpectrumInGameplay(_cachedGameplaySceneName);
_spectrumHiddenInGameplay = true;
HideSpectrumInGameplay(SceneManager.GetActiveScene().name);
_spectrumHiddenForCurrentScene = true;
}
if (!_buttonsBound)
@@ -583,6 +591,9 @@ public class BgmUiBinder : MonoBehaviour
private GameObject FindByNameContains(string name)
{
if (string.IsNullOrEmpty(name)) return null;
string target = name.Replace(" ", "");
var exact = SceneObjectLookupCache.Find(name);
if (exact != null) return exact;
var all = Object.FindObjectsByType<Transform>(FindObjectsInactive.Include, FindObjectsSortMode.None);
for (int i = 0; i < all.Length; i++)
{
@@ -590,7 +601,6 @@ public class BgmUiBinder : MonoBehaviour
if (t == null) continue;
if (!t.gameObject.scene.IsValid() || !t.gameObject.scene.isLoaded) continue;
var n = t.name.Replace(" ", "");
var target = name.Replace(" ", "");
if (n.Contains(target))
return t.gameObject;
}
@@ -693,7 +703,7 @@ public class BgmUiBinder : MonoBehaviour
return;
var currentCanvas = musicRoot.GetComponentInParent<Canvas>();
var persistent = GameObject.Find(musicPicCanvasName);
var persistent = SceneObjectLookupCache.Find(musicPicCanvasName);
Canvas persistentCanvas = null;
if (persistent == null)
{
@@ -774,7 +784,7 @@ public class BgmUiBinder : MonoBehaviour
if (musicRoot != null && hasExplicitMusicRoot)
SetMusicPicVisible(shouldShow, true);
if (sceneName == "gamePlay_gamePlay")
if (ShouldHideSpectrumInScene(sceneName))
{
CleanupSpectrumRoots(true);
HideSpectrumInGameplay(sceneName);
@@ -884,8 +894,7 @@ public class BgmUiBinder : MonoBehaviour
private void HideSpectrumInGameplay(string sceneName)
{
bool shouldHide = sceneName == gameplaySceneName ||
(hideSpectrumInMainScene && sceneName == mainSceneName);
bool shouldHide = ShouldHideSpectrumInScene(sceneName);
if (!shouldHide) return;
var all = Resources.FindObjectsOfTypeAll<RectTransform>();
@@ -908,6 +917,23 @@ public class BgmUiBinder : MonoBehaviour
}
}
private bool ShouldHideSpectrumInScene(string sceneName)
{
if (string.IsNullOrEmpty(sceneName))
return false;
if (string.Equals(sceneName, gameplaySceneName, StringComparison.OrdinalIgnoreCase))
return true;
if (hideSpectrumInMainScene && string.Equals(sceneName, mainSceneName, StringComparison.OrdinalIgnoreCase))
return true;
if (string.Equals(sceneName, beforeEverythingSceneName, StringComparison.OrdinalIgnoreCase))
return true;
return false;
}
private System.Collections.IEnumerator ShowLobbyMusicPicNextFrame()
{
int tries = 0;
@@ -956,3 +982,4 @@ public class BgmUiBinder : MonoBehaviour
return list;
}
}