Files
Cielonos/Assets/Scripts/SLSUtilities/WwiseAssistance/AudioManager.cs

220 lines
7.6 KiB
C#
Raw Normal View History

2026-02-13 09:22:11 -05:00
using System.Collections.Generic;
using UnityEngine;
using AK.Wwise;
using Lean.Pool;
using Sirenix.OdinInspector;
using SLSUtilities.General;
namespace SLSUtilities.WwiseAssistance
{
public partial class AudioManager : Singleton<AudioManager>
{
[Title("Settings")]
[Required]
public GameObject audioPoint;
public List<Bank> soundBanks;
[Title("Subsystems")]
public BackgroundMusicManager backgroundMusicManager;
2026-05-26 10:48:49 -04:00
private static Dictionary<string, uint> _trackedPlayingIDs = new Dictionary<string, uint>();
2026-02-13 09:22:11 -05:00
protected override void Awake()
{
base.Awake();
soundBanks.ForEach(bank => bank.Load());
}
}
public partial class AudioManager
{
/// <summary>
/// 【核心方法】在指定位置播放 3D 音效
/// 使用方法: AudioManager.Instance.PlayEvent(AK.EVENTS.EXPLOSION, position);
/// </summary>
/// <param name="eventID">AK.EVENTS 中的静态 ID</param>
/// <param name="position">世界坐标</param>
/// <returns>返回 WwiseEmitter以便需要时手动 Stop</returns>
public static AudioPoint Post(uint eventID, Vector3 position = default)
{
if (eventID == 0) return null;
AudioPoint point = LeanPool.Spawn(instance.audioPoint, position, Quaternion.identity).GetComponent<AudioPoint>();
point.Play(eventID);
return point;
}
public static uint Post(uint eventID, GameObject attachedObject)
{
if (eventID == 0 || attachedObject == null) return AkUnitySoundEngine.AK_INVALID_PLAYING_ID;
return AkUnitySoundEngine.PostEvent(eventID, attachedObject);
}
public static AudioPoint Post(string eventName, Vector3 position)
{
return Post(AkUnitySoundEngine.GetIDFromString(eventName), position);
}
public static void Post(string eventName, GameObject attachedObject)
{
Post(AkUnitySoundEngine.GetIDFromString(eventName), attachedObject);
}
public static void Stop(uint playingID, int fadeOutMs = 0)
{
if (playingID == AkUnitySoundEngine.AK_INVALID_PLAYING_ID) return;
AkUnitySoundEngine.ExecuteActionOnPlayingID(
AkActionOnEventType.AkActionOnEventType_Stop,
playingID, fadeOutMs,
AkCurveInterpolation.AkCurveInterpolation_Linear
);
}
public void StopAll()
{
AkUnitySoundEngine.StopAll();
2026-05-26 10:48:49 -04:00
_trackedPlayingIDs.Clear();
2026-02-13 09:22:11 -05:00
}
}
public partial class AudioManager
{
private static void RegisterTracking(string trackingKey, uint playingID)
{
if (playingID != AkUnitySoundEngine.AK_INVALID_PLAYING_ID)
{
2026-05-26 10:48:49 -04:00
_trackedPlayingIDs[trackingKey] = playingID;
2026-02-13 09:22:11 -05:00
}
}
public static void Post(string trackingKey, uint eventID, Vector3 position = default)
{
Stop(trackingKey);
AudioPoint point = Post(eventID, position);
uint playingID = point.eventID;
RegisterTracking(trackingKey, playingID);
}
public static void Post(string trackingKey, string eventName, Vector3 position = default)
{
Post(trackingKey, AkUnitySoundEngine.GetIDFromString(eventName), position);
}
public static void Post(string trackingKey, uint eventID, GameObject attachedObject)
{
Stop(trackingKey);
uint playingID = Post(eventID, attachedObject);
RegisterTracking(trackingKey, playingID);
}
public static void Post(string trackingKey, string eventName, GameObject attachedObject)
{
Post(trackingKey, AkUnitySoundEngine.GetIDFromString(eventName), attachedObject);
}
public static void Pause(string trackingKey, int fadeOutMs = 0)
{
2026-05-26 10:48:49 -04:00
if (_trackedPlayingIDs.TryGetValue(trackingKey, out uint playingID))
2026-02-13 09:22:11 -05:00
{
AkUnitySoundEngine.ExecuteActionOnPlayingID(
AkActionOnEventType.AkActionOnEventType_Pause,
playingID, fadeOutMs,
AkCurveInterpolation.AkCurveInterpolation_Linear
);
}
}
public static void PauseAllTrackedEvents(int fadeOutMs = 0)
{
2026-05-26 10:48:49 -04:00
foreach (var playingID in _trackedPlayingIDs.Values)
2026-02-13 09:22:11 -05:00
{
AkUnitySoundEngine.ExecuteActionOnPlayingID(
AkActionOnEventType.AkActionOnEventType_Pause,
playingID, fadeOutMs,
AkCurveInterpolation.AkCurveInterpolation_Linear
);
}
}
// --- 【新增】核心控制:继续 ---
public static void Resume(string trackingKey, int fadeInMs = 0)
{
2026-05-26 10:48:49 -04:00
if (_trackedPlayingIDs.TryGetValue(trackingKey, out uint playingID))
2026-02-13 09:22:11 -05:00
{
AkUnitySoundEngine.ExecuteActionOnPlayingID(
AkActionOnEventType.AkActionOnEventType_Resume,
playingID, fadeInMs,
AkCurveInterpolation.AkCurveInterpolation_Linear
);
}
}
public static void ResumeAllTrackedEvents(int fadeInMs = 0)
{
2026-05-26 10:48:49 -04:00
foreach (var playingID in _trackedPlayingIDs.Values)
2026-02-13 09:22:11 -05:00
{
AkUnitySoundEngine.ExecuteActionOnPlayingID(
AkActionOnEventType.AkActionOnEventType_Resume,
playingID, fadeInMs,
AkCurveInterpolation.AkCurveInterpolation_Linear
);
}
}
/// <summary>
/// 【新增】通过 Key 停止特定音效
/// </summary>
public static void Stop(string trackingKey, int fadeOutMs = 0)
{
2026-05-26 10:48:49 -04:00
if (_trackedPlayingIDs.TryGetValue(trackingKey, out uint playingID))
2026-02-13 09:22:11 -05:00
{
Stop(playingID, fadeOutMs);
2026-05-26 10:48:49 -04:00
_trackedPlayingIDs.Remove(trackingKey);
2026-02-13 09:22:11 -05:00
}
}
/// <summary>
/// 【新增】停止所有被追踪的循环音效 (常用于切换场景前)
/// </summary>
public static void StopAllTrackedEvents(int fadeOutMs = 0)
{
2026-05-26 10:48:49 -04:00
foreach (var playingID in _trackedPlayingIDs.Values)
2026-02-13 09:22:11 -05:00
{
Stop(playingID, fadeOutMs);
}
2026-05-26 10:48:49 -04:00
_trackedPlayingIDs.Clear();
2026-02-13 09:22:11 -05:00
}
}
public partial class AudioManager
{
/// <summary>
/// 设置全局参数 (RTPC)
/// 例如: "MasterVolume", "MusicVolume", "PlayerHealth"
/// </summary>
public void SetRTPC(string rtpcName, float value)
{
AkUnitySoundEngine.SetRTPCValue(rtpcName, value);
}
/// <summary>
/// 设置状态 (State)
/// 例如: Group="MusicState", State="Combat" / "Explore"
/// </summary>
public void SetState(string stateGroup, string stateName)
{
AkUnitySoundEngine.SetState(stateGroup, stateName);
}
/// <summary>
/// 设置全局开关 (Switch) - 通常用于特定的全局对象
/// </summary>
public void SetGlobalSwitch(string switchGroup, string switchName)
{
// 对于全局Switch通常传一个全局GameObject或者使用 Wwise 的 Global Scope
AkUnitySoundEngine.SetSwitch(switchGroup, switchName, gameObject);
}
}
}