Files
ichni_Official/Assets/Scripts/SLSUtilities/WwiseAssistance/AudioManager.cs
SoulliesOfficial 7580c4d87c 大更
2026-03-14 03:13:10 -04:00

243 lines
8.2 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 Ichni;
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 SongPlayer backgroundMusicManager;
private static Dictionary<string, uint> TrackedPlayingIDs = new Dictionary<string, uint>();
protected override void Awake()
{
Initialize(true);
soundBanks.ForEach(bank => bank.Load());
}
}
public partial class AudioManager
{
/// <summary>
/// 【核心方法】播放音效
/// 使用方法: AudioManager.Instance.PlayEvent(AK.EVENTS.EXPLOSION, position);
/// </summary>
/// <param name="eventID">AK.EVENTS 中的静态 ID</param>
public static uint Post(uint eventID)
{
if (eventID == 0) return AkUnitySoundEngine.AK_INVALID_PLAYING_ID;
uint playingID = AkUnitySoundEngine.PostEvent(eventID, Instance.gameObject);
if (playingID == AkUnitySoundEngine.AK_INVALID_PLAYING_ID)
{
Debug.LogWarning($"Wwise Event ID [{eventID}] 播放失败");
}
return playingID;
}
public static AudioPoint Post(uint eventID, Vector3 position)
{
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 static void SetRTPC(string rtpcName, float value)
{
AkUnitySoundEngine.SetRTPCValue(rtpcName, value);
}
/// <summary>
/// 设置状态 (State)
/// 例如: Group="MusicState", State="Combat" / "Explore"
/// </summary>
public static void SetState(string stateGroup, string stateName)
{
AkUnitySoundEngine.SetState(stateGroup, stateName);
}
public static void SetState(State targetState)
{
targetState?.SetValue();
}
/// <summary>
/// 设置全局开关 (Switch) - 通常用于特定的全局对象
/// </summary>
public static void SetSwitch(string switchGroup, string switchName)
{
// 对于全局Switch通常传一个全局GameObject或者使用 Wwise 的 Global Scope
AkUnitySoundEngine.SetSwitch(switchGroup, switchName, Instance.gameObject);
}
public static void SetSwitch(Switch targetSwitch)
{
targetSwitch?.SetValue(Instance.gameObject);
}
}
}