Files
Cielonos/Assets/Scripts/SLSUtilities/WwiseAssistance/AudioManager.cs
SoulliesOfficial 50ee502684 完善
2026-02-13 09:22:11 -05:00

220 lines
7.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
private static Dictionary<string, uint> TrackedPlayingIDs = new Dictionary<string, uint>();
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();
TrackedPlayingIDs.Clear();
}
}
public partial class AudioManager
{
private static void RegisterTracking(string trackingKey, uint playingID)
{
if (playingID != AkUnitySoundEngine.AK_INVALID_PLAYING_ID)
{
TrackedPlayingIDs[trackingKey] = playingID;
}
}
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)
{
if (TrackedPlayingIDs.TryGetValue(trackingKey, out uint playingID))
{
AkUnitySoundEngine.ExecuteActionOnPlayingID(
AkActionOnEventType.AkActionOnEventType_Pause,
playingID, fadeOutMs,
AkCurveInterpolation.AkCurveInterpolation_Linear
);
}
}
public static void PauseAllTrackedEvents(int fadeOutMs = 0)
{
foreach (var playingID in TrackedPlayingIDs.Values)
{
AkUnitySoundEngine.ExecuteActionOnPlayingID(
AkActionOnEventType.AkActionOnEventType_Pause,
playingID, fadeOutMs,
AkCurveInterpolation.AkCurveInterpolation_Linear
);
}
}
// --- 【新增】核心控制:继续 ---
public static void Resume(string trackingKey, int fadeInMs = 0)
{
if (TrackedPlayingIDs.TryGetValue(trackingKey, out uint playingID))
{
AkUnitySoundEngine.ExecuteActionOnPlayingID(
AkActionOnEventType.AkActionOnEventType_Resume,
playingID, fadeInMs,
AkCurveInterpolation.AkCurveInterpolation_Linear
);
}
}
public static void ResumeAllTrackedEvents(int fadeInMs = 0)
{
foreach (var playingID in TrackedPlayingIDs.Values)
{
AkUnitySoundEngine.ExecuteActionOnPlayingID(
AkActionOnEventType.AkActionOnEventType_Resume,
playingID, fadeInMs,
AkCurveInterpolation.AkCurveInterpolation_Linear
);
}
}
/// <summary>
/// 【新增】通过 Key 停止特定音效
/// </summary>
public static void Stop(string trackingKey, int fadeOutMs = 0)
{
if (TrackedPlayingIDs.TryGetValue(trackingKey, out uint playingID))
{
Stop(playingID, fadeOutMs);
TrackedPlayingIDs.Remove(trackingKey);
}
}
/// <summary>
/// 【新增】停止所有被追踪的循环音效 (常用于切换场景前)
/// </summary>
public static void StopAllTrackedEvents(int fadeOutMs = 0)
{
foreach (var playingID in TrackedPlayingIDs.Values)
{
Stop(playingID, fadeOutMs);
}
TrackedPlayingIDs.Clear();
}
}
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);
}
}
}