编队系统大更新 基本快搞好了 准备做敌人和分数
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Centralized judge sound player. Assign four AudioSources (one per judgement) in the Inspector.
|
||||
/// Designed to be low-latency: each judgement has a dedicated AudioSource and PlayOneShot is used.
|
||||
/// Place this component on a persistent gameobject in the scene (or your audio container).
|
||||
/// </summary>
|
||||
public class JudgeSoundManager : MonoBehaviour
|
||||
{
|
||||
public static JudgeSoundManager Instance { get; private set; }
|
||||
|
||||
[Header("AudioSources (assign dedicated AudioSource for each judgement)")]
|
||||
public AudioSource perfectSource;
|
||||
public AudioSource greatSource;
|
||||
public AudioSource goodSource;
|
||||
public AudioSource missSource;
|
||||
|
||||
[Header("Enable/Disable per-judgement playback")]
|
||||
[Tooltip("Toggle whether Perfect sounds are played")]
|
||||
public bool enablePerfect = true;
|
||||
[Tooltip("Toggle whether Great sounds are played")]
|
||||
public bool enableGreat = true;
|
||||
[Tooltip("Toggle whether Good sounds are played")]
|
||||
public bool enableGood = true;
|
||||
[Tooltip("Toggle whether Miss sounds are played")]
|
||||
public bool enableMiss = true;
|
||||
|
||||
[Header("Fallback clips (optional, used if the assigned AudioSource has no clip)")]
|
||||
public AudioClip perfectClip;
|
||||
public AudioClip greatClip;
|
||||
public AudioClip goodClip;
|
||||
public AudioClip missClip;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance == null)
|
||||
{
|
||||
Instance = this;
|
||||
// Do not automatically destroy; leave lifecycle to scene management
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure AudioSources are configured for low latency
|
||||
ConfigureSource(perfectSource);
|
||||
ConfigureSource(greatSource);
|
||||
ConfigureSource(goodSource);
|
||||
ConfigureSource(missSource);
|
||||
}
|
||||
|
||||
private void ConfigureSource(AudioSource src)
|
||||
{
|
||||
if (src == null) return;
|
||||
src.playOnAwake = false;
|
||||
// keep 3D off for UI/flat sounds
|
||||
src.spatialBlend = 0f;
|
||||
// ensure not looping
|
||||
src.loop = false;
|
||||
}
|
||||
|
||||
public enum JudgeResult { Perfect, Great, Good, Miss }
|
||||
|
||||
public void PlayJudgeSound(string result)
|
||||
{
|
||||
if (string.IsNullOrEmpty(result)) return;
|
||||
switch (result)
|
||||
{
|
||||
case "Perfect": PlayJudgeSound(JudgeResult.Perfect); break;
|
||||
case "Great": PlayJudgeSound(JudgeResult.Great); break;
|
||||
case "Good": PlayJudgeSound(JudgeResult.Good); break;
|
||||
case "Miss": PlayJudgeSound(JudgeResult.Miss); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
public void PlayJudgeSound(JudgeResult r)
|
||||
{
|
||||
// honor inspector toggles to allow disabling specific judgement sounds
|
||||
switch (r)
|
||||
{
|
||||
case JudgeResult.Perfect:
|
||||
if (!enablePerfect) return;
|
||||
PlayOnSource(perfectSource, perfectClip);
|
||||
break;
|
||||
case JudgeResult.Great:
|
||||
if (!enableGreat) return;
|
||||
PlayOnSource(greatSource, greatClip);
|
||||
break;
|
||||
case JudgeResult.Good:
|
||||
if (!enableGood) return;
|
||||
PlayOnSource(goodSource, goodClip);
|
||||
break;
|
||||
case JudgeResult.Miss:
|
||||
if (!enableMiss) return;
|
||||
PlayOnSource(missSource, missClip);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayOnSource(AudioSource src, AudioClip fallbackClip)
|
||||
{
|
||||
if (src != null)
|
||||
{
|
||||
// Prefer PlayOneShot so sources can overlap and we don't need to manage clip state
|
||||
if (src.clip != null)
|
||||
{
|
||||
src.PlayOneShot(src.clip);
|
||||
}
|
||||
else if (fallbackClip != null)
|
||||
{
|
||||
src.PlayOneShot(fallbackClip);
|
||||
}
|
||||
}
|
||||
else if (fallbackClip != null)
|
||||
{
|
||||
// no dedicated source provided: play via a temporary one-shot using AudioSource.PlayClipAtPoint at camera position
|
||||
AudioSource.PlayClipAtPoint(fallbackClip, Camera.main != null ? Camera.main.transform.position : Vector3.zero);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user