feat: AudioSettings 独立出配置文件,而不是零散在代码各处。
This commit is contained in:
@@ -2883,6 +2883,7 @@ MonoBehaviour:
|
|||||||
startWithMusic: 1
|
startWithMusic: 1
|
||||||
startMusicWith: 0
|
startMusicWith: 0
|
||||||
logLevel: 0
|
logLevel: 0
|
||||||
|
extendSettings: {fileID: 11400000, guid: de80878c933394e2da0966a1466fd793, type: 2}
|
||||||
--- !u!4 &2093584671
|
--- !u!4 &2093584671
|
||||||
Transform:
|
Transform:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace OCES.Audio
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 音频系统扩展配置,集中管理所有路径和可调参数。
|
||||||
|
/// 资产位置:Assets/Settings/AudioExtendSettings.asset
|
||||||
|
/// 编辑入口:Project Settings > Audio Extend
|
||||||
|
/// 运行时注入:AudioSystem.Awake() 将 Inspector 引用注入 _instance
|
||||||
|
/// </summary>
|
||||||
|
public class AudioExtendSettings : ScriptableObject
|
||||||
|
{
|
||||||
|
// ========== Resource Paths ==========
|
||||||
|
[Header("Resource Paths")]
|
||||||
|
[Tooltip("Resources 子目录:音频配置文件(.bytes)")]
|
||||||
|
public string audioConfigPath = "AudioData";
|
||||||
|
|
||||||
|
[Tooltip("Resources 子目录:音频资源文件(.wav/.ogg)")]
|
||||||
|
public string audioResourcePath = "Audios";
|
||||||
|
|
||||||
|
[Tooltip("Resources 路径:AudioMixer 资产")]
|
||||||
|
public string audioMixerPath = "Audios/Master";
|
||||||
|
|
||||||
|
// ========== AudioMixer Group Paths ==========
|
||||||
|
[Header("AudioMixer Groups")]
|
||||||
|
public string sfxGroupPath = "Master/Regular/SFX";
|
||||||
|
public string voiceGroupPath = "Master/Regular/Voice";
|
||||||
|
public string accentSfxGroupPath = "Master/SFX_Accent";
|
||||||
|
public string musicGroupPath = "Master/Regular/Music";
|
||||||
|
public string ambienceGroupPath = "Master/Regular/SFX/Ambience";
|
||||||
|
|
||||||
|
// ========== AudioMixer Parameters ==========
|
||||||
|
[Header("Lowpass Filter")]
|
||||||
|
public string lowpassParamName = "LowpassFreq";
|
||||||
|
public float lowpassEnabledCutoff = 440f;
|
||||||
|
public float lowpassDisabledCutoff = 22000f;
|
||||||
|
public float lowpassTweenDuration = 0.2f;
|
||||||
|
|
||||||
|
// ========== Audio Import ==========
|
||||||
|
[Header("Audio Import Settings")]
|
||||||
|
public AudioCompressionFormat compressionFormat = AudioCompressionFormat.Vorbis;
|
||||||
|
public uint sfxSampleRate = 22050;
|
||||||
|
public uint musicSampleRate = 44100;
|
||||||
|
public float musicQuality = 0.13f;
|
||||||
|
public float sfxQuality = 0.5f;
|
||||||
|
|
||||||
|
public float decompressThreshold = 5f; // ≤ 此值 → DecompressOnLoad
|
||||||
|
public float streamingThreshold = 15f; // ≥ 此值 → Streaming
|
||||||
|
|
||||||
|
// ========== Fade ==========
|
||||||
|
[Header("Fade")]
|
||||||
|
public DG.Tweening.Ease defaultFadeOutEase = DG.Tweening.Ease.InSine;
|
||||||
|
public DG.Tweening.Ease defaultFadeInEase = DG.Tweening.Ease.OutSine;
|
||||||
|
|
||||||
|
// ── Singleton ──
|
||||||
|
|
||||||
|
public static AudioExtendSettings Instance { get; internal set; }
|
||||||
|
|
||||||
|
// 便利属性:拼接完整路径
|
||||||
|
public string FullAudioResourcePath
|
||||||
|
{
|
||||||
|
get { return Path.Combine(Application.dataPath, "Resources", this.audioResourcePath); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FullAudioConfigPath
|
||||||
|
{
|
||||||
|
get { return Path.Combine(Application.dataPath, "Resources", this.audioConfigPath); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 79becf8778e048058fe7cc1f3a5e021b
|
||||||
|
timeCreated: 1778750086
|
||||||
@@ -20,8 +20,7 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
internal ResourceLoader ResourceLoader;
|
internal ResourceLoader ResourceLoader;
|
||||||
|
|
||||||
const string k_audioConfigPath = "AudioData";
|
[SerializeField] AudioExtendSettings extendSettings;
|
||||||
const string k_audioResourcePath = "Audios";
|
|
||||||
|
|
||||||
SfxSystem m_sfxSystem;
|
SfxSystem m_sfxSystem;
|
||||||
MusicSystem m_musicSystem;
|
MusicSystem m_musicSystem;
|
||||||
@@ -99,14 +98,16 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
public void SetLowpass(bool enable)
|
public void SetLowpass(bool enable)
|
||||||
{
|
{
|
||||||
float target = enable ? 440f : 22000f;
|
float target = enable
|
||||||
|
? AudioExtendSettings.Instance.lowpassEnabledCutoff
|
||||||
|
: AudioExtendSettings.Instance.lowpassDisabledCutoff;
|
||||||
|
|
||||||
// Kill existing tween to avoid stacking
|
// Kill existing tween to avoid stacking
|
||||||
if (this.m_lowpassTween != null && this.m_lowpassTween.IsActive())
|
if (this.m_lowpassTween != null && this.m_lowpassTween.IsActive())
|
||||||
this.m_lowpassTween.Kill();
|
this.m_lowpassTween.Kill();
|
||||||
|
|
||||||
// Get current value as start
|
// Get current value as start
|
||||||
if (!this.m_mixer.GetFloat("LowpassFreq", out float current))
|
if (!this.m_mixer.GetFloat(AudioExtendSettings.Instance.lowpassParamName, out float current))
|
||||||
current = target;
|
current = target;
|
||||||
|
|
||||||
float startLog = Mathf.Log10(current);
|
float startLog = Mathf.Log10(current);
|
||||||
@@ -118,10 +119,10 @@ namespace OCES.Audio
|
|||||||
{
|
{
|
||||||
startLog = x;
|
startLog = x;
|
||||||
float value = Mathf.Pow(10f, startLog);
|
float value = Mathf.Pow(10f, startLog);
|
||||||
this.m_mixer.SetFloat("LowpassFreq", value);
|
this.m_mixer.SetFloat(AudioExtendSettings.Instance.lowpassParamName, value);
|
||||||
},
|
},
|
||||||
endLog,
|
endLog,
|
||||||
0.2f // duration in seconds
|
AudioExtendSettings.Instance.lowpassTweenDuration // duration in seconds
|
||||||
).SetEase(Ease.OutCubic);
|
).SetEase(Ease.OutCubic);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,6 +276,8 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
void Awake()
|
void Awake()
|
||||||
{
|
{
|
||||||
|
AudioExtendSettings.Instance = this.extendSettings;
|
||||||
|
|
||||||
if ((bool)Instance && Instance != this)
|
if ((bool)Instance && Instance != this)
|
||||||
{
|
{
|
||||||
Destroy(gameObject);
|
Destroy(gameObject);
|
||||||
@@ -285,27 +288,29 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
this.ResourceLoader = gameObject.AddComponent<ResourceLoader>();
|
this.ResourceLoader = gameObject.AddComponent<ResourceLoader>();
|
||||||
|
|
||||||
this.m_mixer = this.ResourceLoader.LoadSync<AudioMixer>("Audios/Master");
|
string audioConfigPath = AudioExtendSettings.Instance.audioConfigPath;
|
||||||
|
|
||||||
|
this.m_mixer = this.ResourceLoader.LoadSync<AudioMixer>(AudioExtendSettings.Instance.audioMixerPath);
|
||||||
|
|
||||||
// ── SFX 调度器 ──
|
// ── SFX 调度器 ──
|
||||||
// AudioSystem.cs 中
|
// AudioSystem.cs 中
|
||||||
GameObject sfxPoolRoot = new("SfxSourcePool");
|
GameObject sfxPoolRoot = new("SfxSourcePool");
|
||||||
sfxPoolRoot.transform.SetParent(transform, false);
|
sfxPoolRoot.transform.SetParent(transform, false);
|
||||||
AudioSourcePool sfxPool = new(sfxPoolRoot.transform); // 不传 mixer group,让 SfxSystem 自己设置
|
AudioSourcePool sfxPool = new(sfxPoolRoot.transform);
|
||||||
this.m_sfxSystem = gameObject.AddComponent<SfxSystem>();
|
this.m_sfxSystem = gameObject.AddComponent<SfxSystem>();
|
||||||
this.m_audioObjects = AudioConfigLoader.Load<AudioObjectConfig>($"{k_audioConfigPath}/AudioObject");
|
this.m_audioObjects = AudioConfigLoader.Load<AudioObjectConfig>($"{audioConfigPath}/AudioObject");
|
||||||
this.m_audioObjects.PreParseSwitchMappings();
|
this.m_audioObjects.PreParseSwitchMappings();
|
||||||
this.m_groups = AudioConfigLoader.Load<AudioGroupConfig>($"{k_audioConfigPath}/AudioGroup");
|
this.m_groups = AudioConfigLoader.Load<AudioGroupConfig> ($"{audioConfigPath}/AudioGroup");
|
||||||
this.m_sfxSystem.Initialize(this.m_groups, this.m_mixer, sfxPool); // 传入 pool
|
this.m_sfxSystem.Initialize(this.m_groups, this.m_mixer, sfxPool);
|
||||||
|
|
||||||
|
|
||||||
// ── 音乐与环境音系统 ──
|
// ── 音乐与环境音系统 ──
|
||||||
var segments = AudioConfigLoader.Load<MusicSegmentConfig>($"{k_audioConfigPath}/MusicSegment");
|
var segments = AudioConfigLoader.Load<MusicSegmentConfig> ($"{audioConfigPath}/MusicSegment");
|
||||||
var containers = AudioConfigLoader.Load<MusicContainerConfig>($"{k_audioConfigPath}/MusicContainer");
|
var containers = AudioConfigLoader.Load<MusicContainerConfig> ($"{audioConfigPath}/MusicContainer");
|
||||||
var musicPaths = AudioConfigLoader.Load<MusicPathConfig>($"{k_audioConfigPath}/MusicPath");
|
var musicPaths = AudioConfigLoader.Load<MusicPathConfig> ($"{audioConfigPath}/MusicPath");
|
||||||
var ambiencePaths = AudioConfigLoader.Load<AmbiencePathConfig>($"{k_audioConfigPath}/AmbiencePath");
|
var ambiencePaths = AudioConfigLoader.Load<AmbiencePathConfig> ($"{audioConfigPath}/AmbiencePath");
|
||||||
var musicTransitions = AudioConfigLoader.Load<MusicTransitionConfig>($"{k_audioConfigPath}/MusicTransition");
|
var musicTransitions = AudioConfigLoader.Load<MusicTransitionConfig> ($"{audioConfigPath}/MusicTransition");
|
||||||
var ambienceTransitions = AudioConfigLoader.Load<AmbienceTransitionConfig>($"{k_audioConfigPath}/AmbienceTransition");
|
var ambienceTransitions = AudioConfigLoader.Load<AmbienceTransitionConfig> ($"{audioConfigPath}/AmbienceTransition");
|
||||||
|
|
||||||
//运行时数据验证
|
//运行时数据验证
|
||||||
segments.Validate();
|
segments.Validate();
|
||||||
@@ -317,12 +322,12 @@ namespace OCES.Audio
|
|||||||
// AudioSourcePool 由 MusicSystem 独占一个子节点,与 SFX pool 隔离
|
// AudioSourcePool 由 MusicSystem 独占一个子节点,与 SFX pool 隔离
|
||||||
GameObject musicPoolRoot = new("MusicSourcePool");
|
GameObject musicPoolRoot = new("MusicSourcePool");
|
||||||
musicPoolRoot.transform.SetParent(transform, false);
|
musicPoolRoot.transform.SetParent(transform, false);
|
||||||
AudioMixerGroup musicGroup = this.m_mixer.FindMatchingGroups("Master/Regular/Music")[0];
|
AudioMixerGroup musicGroup = this.m_mixer.FindMatchingGroups(AudioExtendSettings.Instance.musicGroupPath)[0];
|
||||||
AudioSourcePool musicPool = new(musicPoolRoot.transform, musicGroup);
|
AudioSourcePool musicPool = new(musicPoolRoot.transform, musicGroup);
|
||||||
|
|
||||||
GameObject ambiencePoolRoot = new("AmbienceSourcePool");
|
GameObject ambiencePoolRoot = new("AmbienceSourcePool");
|
||||||
ambiencePoolRoot.transform.SetParent(transform, false);
|
ambiencePoolRoot.transform.SetParent(transform, false);
|
||||||
AudioMixerGroup ambienceGroup = this.m_mixer.FindMatchingGroups("Master/Regular/SFX/Ambience")[0];
|
AudioMixerGroup ambienceGroup = this.m_mixer.FindMatchingGroups(AudioExtendSettings.Instance.ambienceGroupPath)[0];
|
||||||
AudioSourcePool ambiencePool = new(ambiencePoolRoot.transform, ambienceGroup);
|
AudioSourcePool ambiencePool = new(ambiencePoolRoot.transform, ambienceGroup);
|
||||||
|
|
||||||
this.m_musicSystem.Initialize(
|
this.m_musicSystem.Initialize(
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace OCES.Audio.Editor
|
||||||
|
{
|
||||||
|
static class AudioExtendSettingsProvider
|
||||||
|
{
|
||||||
|
const string k_assetPath = "Assets/Settings/AudioExtendSettings.asset";
|
||||||
|
|
||||||
|
[SettingsProvider]
|
||||||
|
static SettingsProvider Create()
|
||||||
|
{
|
||||||
|
return new SettingsProvider("Project/Audio Extend", SettingsScope.Project)
|
||||||
|
{
|
||||||
|
label = "Audio Extend",
|
||||||
|
guiHandler = searchContext =>
|
||||||
|
{
|
||||||
|
var settings = AssetDatabase.LoadAssetAtPath<AudioExtendSettings>(k_assetPath);
|
||||||
|
if (settings == null)
|
||||||
|
{
|
||||||
|
EditorGUILayout.HelpBox(
|
||||||
|
$"未找到 AudioExtendSettings.asset\n期望路径: {k_assetPath}",
|
||||||
|
MessageType.Warning);
|
||||||
|
if (GUILayout.Button("创建默认配置"))
|
||||||
|
CreateDefaultAsset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SerializedObject so = new SerializedObject(settings);
|
||||||
|
SerializedProperty prop = so.GetIterator();
|
||||||
|
prop.NextVisible(true); // 跳过 Script 字段
|
||||||
|
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
while (prop.NextVisible(false))
|
||||||
|
EditorGUILayout.PropertyField(prop, true);
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
{
|
||||||
|
so.ApplyModifiedProperties();
|
||||||
|
EditorUtility.SetDirty(settings);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
keywords = new[] { "Audio", "SFX", "Music", "Mixer", "Path", "Import" }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("Tools/Audio/Create AudioExtendSettings Asset")]
|
||||||
|
static void CreateDefaultAsset()
|
||||||
|
{
|
||||||
|
if (!AssetDatabase.IsValidFolder("Assets/Settings"))
|
||||||
|
AssetDatabase.CreateFolder("Assets", "Settings");
|
||||||
|
|
||||||
|
var asset = ScriptableObject.CreateInstance<AudioExtendSettings>();
|
||||||
|
AssetDatabase.CreateAsset(asset, k_assetPath);
|
||||||
|
AssetDatabase.SaveAssets();
|
||||||
|
Debug.Log($"[AudioExtend] 已创建默认配置:{k_assetPath}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 862f5cacec834b47a75da0d8ba2710f1
|
||||||
|
timeCreated: 1778757352
|
||||||
@@ -9,16 +9,9 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
public static class AudioImportTool
|
public static class AudioImportTool
|
||||||
{
|
{
|
||||||
const string k_audioResourcePath = "Audios";
|
|
||||||
const string k_audioConfigPath = "AudioData";
|
|
||||||
|
|
||||||
static string AudioAbsolutePath
|
|
||||||
{
|
|
||||||
get { return Path.Combine(Application.dataPath, "Resources", k_audioResourcePath); }
|
|
||||||
}
|
|
||||||
static string ConfigAbsolutePath
|
static string ConfigAbsolutePath
|
||||||
{
|
{
|
||||||
get { return Path.Combine(Application.dataPath, "Resources", k_audioConfigPath); }
|
get { return Path.Combine(Application.dataPath, "Resources", AudioExtendSettings.Instance.audioConfigPath); }
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("Tools/Audio/Apply Audio Import Settings")]
|
[MenuItem("Tools/Audio/Apply Audio Import Settings")]
|
||||||
@@ -26,7 +19,7 @@ namespace OCES.Audio
|
|||||||
{
|
{
|
||||||
if (EditorUtility.DisplayDialog(
|
if (EditorUtility.DisplayDialog(
|
||||||
"Apply Audio Import Settings",
|
"Apply Audio Import Settings",
|
||||||
$"将对 {AudioAbsolutePath} 下所有文件重新应用导入设置,确认继续?",
|
$"将对 {AudioExtendSettings.Instance.FullAudioResourcePath} 下所有文件重新应用导入设置,确认继续?",
|
||||||
"确认", "取消"))
|
"确认", "取消"))
|
||||||
{
|
{
|
||||||
Run();
|
Run();
|
||||||
@@ -49,8 +42,12 @@ namespace OCES.Audio
|
|||||||
public static void Run()
|
public static void Run()
|
||||||
{
|
{
|
||||||
// 1. 加载配置表
|
// 1. 加载配置表
|
||||||
var audioObjectConfig = AudioConfigLoader.Load<AudioObjectConfig>(ConfigAbsolutePath, "AudioObject.bytes");
|
var audioObjectConfig =
|
||||||
var musicSegmentConfig = AudioConfigLoader.Load<MusicSegmentConfig>(ConfigAbsolutePath, "MusicSegment.bytes");
|
AudioConfigLoader.Load<AudioObjectConfig>(AudioExtendSettings.Instance.FullAudioConfigPath,
|
||||||
|
"AudioObject.bytes");
|
||||||
|
var musicSegmentConfig =
|
||||||
|
AudioConfigLoader.Load<MusicSegmentConfig>(AudioExtendSettings.Instance.FullAudioConfigPath,
|
||||||
|
"MusicSegment.bytes");
|
||||||
if (audioObjectConfig == null || musicSegmentConfig == null)
|
if (audioObjectConfig == null || musicSegmentConfig == null)
|
||||||
{
|
{
|
||||||
Debug.LogError("[AudioImportTool] 配置表加载失败,终止");
|
Debug.LogError("[AudioImportTool] 配置表加载失败,终止");
|
||||||
@@ -59,7 +56,7 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
// 2. 扫描文件
|
// 2. 扫描文件
|
||||||
List<string> supportedExtensions = new() { ".wav", ".ogg" };
|
List<string> supportedExtensions = new() { ".wav", ".ogg" };
|
||||||
DirectoryInfo dir = new(AudioAbsolutePath);
|
DirectoryInfo dir = new(AudioExtendSettings.Instance.FullAudioResourcePath);
|
||||||
FileInfo[] files = dir.GetFiles().Where(f => supportedExtensions.Contains(f.Extension.ToLower())).ToArray();
|
FileInfo[] files = dir.GetFiles().Where(f => supportedExtensions.Contains(f.Extension.ToLower())).ToArray();
|
||||||
int total = files.Length, processed = 0, failed = 0;
|
int total = files.Length, processed = 0, failed = 0;
|
||||||
|
|
||||||
@@ -119,32 +116,37 @@ namespace OCES.Audio
|
|||||||
importer.ClearSampleSettingOverride("iOS");
|
importer.ClearSampleSettingOverride("iOS");
|
||||||
|
|
||||||
AudioImporterSampleSettings settings = importer.defaultSampleSettings;
|
AudioImporterSampleSettings settings = importer.defaultSampleSettings;
|
||||||
settings.compressionFormat = AudioCompressionFormat.Vorbis;
|
settings.compressionFormat = AudioExtendSettings.Instance.compressionFormat;
|
||||||
|
|
||||||
settings.sampleRateSetting = AudioSampleRateSetting.OverrideSampleRate;
|
settings.sampleRateSetting = AudioSampleRateSetting.OverrideSampleRate;
|
||||||
settings.preloadAudioData = audioObject?.Haptic != 0;
|
settings.preloadAudioData = audioObject?.Haptic != 0;
|
||||||
switch (category)
|
switch (category)
|
||||||
{
|
{
|
||||||
case AudioCategory.Music:
|
case AudioCategory.Music:
|
||||||
settings.sampleRateOverride = 44100;
|
settings.sampleRateOverride = AudioExtendSettings.Instance.musicSampleRate;
|
||||||
settings.quality = 0.13f;
|
settings.quality = AudioExtendSettings.Instance.musicQuality;
|
||||||
settings.loadType = duration switch
|
|
||||||
|
if (duration <= AudioExtendSettings.Instance.decompressThreshold)
|
||||||
{
|
{
|
||||||
<= 5 => AudioClipLoadType.DecompressOnLoad,
|
settings.loadType = AudioClipLoadType.DecompressOnLoad;
|
||||||
>= 15 => AudioClipLoadType.Streaming,
|
}else if (duration >= AudioExtendSettings.Instance.streamingThreshold)
|
||||||
_ => AudioClipLoadType.CompressedInMemory,
|
{
|
||||||
};
|
settings.loadType = AudioClipLoadType.Streaming;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
settings.loadType = AudioClipLoadType.CompressedInMemory;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case AudioCategory.Voice:
|
case AudioCategory.Voice:
|
||||||
case AudioCategory.SFX:
|
case AudioCategory.SFX:
|
||||||
default:
|
default:
|
||||||
settings.sampleRateOverride = 22050; // 音效2022.3.62f3没有32kHz这一档,要是有的话这一档其实最合适
|
settings.sampleRateOverride = AudioExtendSettings.Instance.sfxSampleRate; // 音效2022.3.62f3没有32kHz这一档,要是有的话这一档其实最合适
|
||||||
settings.quality = 0.5f;
|
settings.quality = AudioExtendSettings.Instance.sfxQuality;
|
||||||
settings.loadType = duration switch
|
|
||||||
{
|
settings.loadType = duration >= AudioExtendSettings.Instance.streamingThreshold
|
||||||
>= 15 => AudioClipLoadType.Streaming,
|
? AudioClipLoadType.Streaming
|
||||||
_ => AudioClipLoadType.DecompressOnLoad,
|
: AudioClipLoadType.DecompressOnLoad;
|
||||||
};
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ namespace OCES.Audio
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
src.volume = fromVolume;
|
src.volume = fromVolume;
|
||||||
src.DOFade(0f, duration - elapsed).SetEase(Ease.InSine); //TODO 支持读表
|
src.DOFade(0f, duration - elapsed).SetEase(AudioExtendSettings.Instance.defaultFadeOutEase); //TODO 支持读表
|
||||||
}
|
}
|
||||||
yield return null;
|
yield return null;
|
||||||
}
|
}
|
||||||
@@ -236,7 +236,7 @@ namespace OCES.Audio
|
|||||||
if (DOTween.IsTweening(src))
|
if (DOTween.IsTweening(src))
|
||||||
continue;
|
continue;
|
||||||
src.volume = 0f;
|
src.volume = 0f;
|
||||||
src.DOFade(1f, duration - elapsed).SetEase(Ease.OutSine); //TODO 支持读表
|
src.DOFade(1f, duration - elapsed).SetEase(AudioExtendSettings.Instance.defaultFadeInEase); //TODO 支持读表
|
||||||
}
|
}
|
||||||
|
|
||||||
yield return null;
|
yield return null;
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
// AudioClip clip = Resources.Load<AudioClip>($"Audios/{segment.Name}");
|
// AudioClip clip = Resources.Load<AudioClip>($"Audios/{segment.Name}");
|
||||||
AudioClip clip = null;
|
AudioClip clip = null;
|
||||||
AudioSystem.Instance.ResourceLoader.LoadAsync<AudioClip>($"Audios/{segment.Name}", loadedClip =>
|
AudioSystem.Instance.ResourceLoader.LoadAsync<AudioClip>($"{AudioExtendSettings.Instance.audioResourcePath}/{segment.Name}", loadedClip =>
|
||||||
{
|
{
|
||||||
clip = loadedClip;
|
clip = loadedClip;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ namespace OCES.Audio
|
|||||||
{
|
{
|
||||||
foreach (MusicSegment segment in this.m_musicSegmentInfos.Values)
|
foreach (MusicSegment segment in this.m_musicSegmentInfos.Values)
|
||||||
{
|
{
|
||||||
AudioClip clip = AudioSystem.Instance.ResourceLoader.LoadSync<AudioClip>($"Audios/{segment.Name}");
|
AudioClip clip =
|
||||||
|
AudioSystem.Instance.ResourceLoader.LoadSync<AudioClip>(
|
||||||
|
$"{AudioExtendSettings.Instance.audioResourcePath}/{segment.Name}");
|
||||||
if (!clip)
|
if (!clip)
|
||||||
{
|
{
|
||||||
Debug.LogError($"[MusicSegmentConfig] 音频文件未找到: {segment.Name}, SegmentId: {segment.Id}");
|
Debug.LogError($"[MusicSegmentConfig] 音频文件未找到: {segment.Name}, SegmentId: {segment.Id}");
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ namespace OCES.Audio
|
|||||||
{
|
{
|
||||||
public UnityEngine.UI.Text audioSystemTextBox;
|
public UnityEngine.UI.Text audioSystemTextBox;
|
||||||
|
|
||||||
const int k_maxGlobalConcurrent = 128;
|
|
||||||
|
|
||||||
//记录某个 AudioObject 最近一次触发播放的时刻,用于 MinInterval 节流判断,是"上次什么时候播过"。
|
//记录某个 AudioObject 最近一次触发播放的时刻,用于 MinInterval 节流判断,是"上次什么时候播过"。
|
||||||
readonly Dictionary<uint, double> m_lastPlayTime = new();
|
readonly Dictionary<uint, double> m_lastPlayTime = new();
|
||||||
readonly Dictionary<uint, int> m_clipConcurrentCount = new();
|
readonly Dictionary<uint, int> m_clipConcurrentCount = new();
|
||||||
@@ -78,11 +76,11 @@ namespace OCES.Audio
|
|||||||
this.m_pitchStepResolver = new PitchStepResolver();
|
this.m_pitchStepResolver = new PitchStepResolver();
|
||||||
this.m_volumeStepResolver = new VolumeStepResolver();
|
this.m_volumeStepResolver = new VolumeStepResolver();
|
||||||
|
|
||||||
AudioMixerGroup[] sfx = Find("Master/Regular/SFX");
|
AudioMixerGroup[] sfx = Find(AudioExtendSettings.Instance.sfxGroupPath);
|
||||||
if (sfx.Length > 0) this.m_sfxGroup = sfx[0];
|
if (sfx.Length > 0) this.m_sfxGroup = sfx[0];
|
||||||
AudioMixerGroup[] voice = Find("Master/Regular/Voice");
|
AudioMixerGroup[] voice = Find(AudioExtendSettings.Instance.voiceGroupPath);
|
||||||
if (voice.Length > 0) this.m_voiceGroup = voice[0];
|
if (voice.Length > 0) this.m_voiceGroup = voice[0];
|
||||||
AudioMixerGroup[] accentSfx = Find("Master/SFX_Accent");
|
AudioMixerGroup[] accentSfx = Find(AudioExtendSettings.Instance.accentSfxGroupPath);
|
||||||
if (accentSfx.Length > 0) this.m_accentSfxGroup = accentSfx[0];
|
if (accentSfx.Length > 0) this.m_accentSfxGroup = accentSfx[0];
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -224,7 +222,8 @@ namespace OCES.Audio
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 第四层:全局并发控制
|
// 第四层:全局并发控制
|
||||||
if (this.m_activeSounds.Count >= k_maxGlobalConcurrent)
|
//从Unity原生Audio Settings中读取最大发音数限制
|
||||||
|
if (this.m_activeSounds.Count >= AudioSettings.GetConfiguration().numVirtualVoices)
|
||||||
{
|
{
|
||||||
this.m_tempLowerPriority.Clear();
|
this.m_tempLowerPriority.Clear();
|
||||||
foreach (ActiveSound activeSound in this.m_activeSounds)
|
foreach (ActiveSound activeSound in this.m_activeSounds)
|
||||||
@@ -405,7 +404,9 @@ namespace OCES.Audio
|
|||||||
bool SetupSource(AudioSource source, ActiveSound activeSound, int clipIndex = 0)
|
bool SetupSource(AudioSource source, ActiveSound activeSound, int clipIndex = 0)
|
||||||
{
|
{
|
||||||
AudioObject audioObject = activeSound.AudioObject;
|
AudioObject audioObject = activeSound.AudioObject;
|
||||||
AudioClip clip = AudioSystem.Instance.ResourceLoader.LoadSync<AudioClip>($"Audios/{audioObject.Name[clipIndex]}");
|
AudioClip clip =
|
||||||
|
AudioSystem.Instance.ResourceLoader.LoadSync<AudioClip>(
|
||||||
|
$"{AudioExtendSettings.Instance.audioResourcePath}/{audioObject.Name[clipIndex]}");
|
||||||
if (!clip)
|
if (!clip)
|
||||||
{
|
{
|
||||||
Debug.LogError($"音频文件未找到:{audioObject.Name[clipIndex]}");
|
Debug.LogError($"音频文件未找到:{audioObject.Name[clipIndex]}");
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 0}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 79becf8778e048058fe7cc1f3a5e021b, type: 3}
|
||||||
|
m_Name: AudioExtendSettings
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
audioConfigPath: AudioData
|
||||||
|
audioResourcePath: Audios
|
||||||
|
audioMixerPath: Audios/Master
|
||||||
|
sfxGroupPath: Master/Regular/SFX
|
||||||
|
voiceGroupPath: Master/Regular/Voice
|
||||||
|
accentSfxGroupPath: Master/SFX_Accent
|
||||||
|
musicGroupPath: Master/Regular/Music
|
||||||
|
ambienceGroupPath: Master/Regular/SFX/Ambience
|
||||||
|
lowpassParamName: LowpassFreq
|
||||||
|
lowpassEnabledCutoff: 440
|
||||||
|
lowpassDisabledCutoff: 22000
|
||||||
|
lowpassTweenDuration: 0.2
|
||||||
|
compressionFormat: 1
|
||||||
|
sfxSampleRate: 22050
|
||||||
|
musicSampleRate: 44100
|
||||||
|
musicQuality: 0.13
|
||||||
|
sfxQuality: 0.5
|
||||||
|
decompressThreshold: 5
|
||||||
|
streamingThreshold: 15
|
||||||
|
defaultFadeOutEase: 2
|
||||||
|
defaultFadeInEase: 3
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: de80878c933394e2da0966a1466fd793
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Reference in New Issue
Block a user