Files
ichni_Official/Assets/Scripts/SLSUtilities/WwiseAssistance/AudioPoint.cs

107 lines
3.7 KiB
C#
Raw Normal View History

2026-03-14 03:13:10 -04:00
using UnityEngine;
using Lean.Pool;
using AK.Wwise;
using SLSUtilities.LeanPoolAssistance; // 引用 Wwise
namespace SLSUtilities.WwiseAssistance
{
/// <summary>
/// 挂载在 AudioPoint 预制体上,负责管理单个音频实例的生命周期
/// </summary>
public partial class AudioPoint : PooledObject
{
public uint playingID = AkUnitySoundEngine.AK_INVALID_PLAYING_ID;
public uint eventID = uint.MaxValue;
/// <summary>
/// 播放指定 ID 的事件
/// </summary>
public uint Play(uint eventID)
{
this.eventID = eventID;
// PostEvent 并注册 EndOfEvent 回调
playingID = AkUnitySoundEngine.PostEvent(eventID, gameObject, (uint)AkCallbackType.AK_EndOfEvent, OnEventFinished, null);
// 安全检查:如果 ID 无效比如Bank没加载立即回收防止对象泄漏
if (playingID == AkUnitySoundEngine.AK_INVALID_PLAYING_ID)
{
Debug.LogWarning($"Wwise Event ID [{eventID}] 播放失败,正在回收对象。");
LeanPool.Despawn(gameObject);
}
return playingID;
}
/// <summary>
/// 手动停止播放(支持淡出),用于 Loop 音效
/// </summary>
/// <param name="fadeOutMs">淡出时间(毫秒)</param>
public void Stop(int fadeOutMs = 0)
{
if (playingID != AkUnitySoundEngine.AK_INVALID_PLAYING_ID)
{
// 执行 Stop Action
AkUnitySoundEngine.ExecuteActionOnPlayingID(AkActionOnEventType.AkActionOnEventType_Stop, playingID, fadeOutMs, AkCurveInterpolation.AkCurveInterpolation_Sine);
// 注意:这里不调用 DespawnSelf。
// Wwise 停止并淡出后,会触发 AK_EndOfEvent由 OnEventFinished 负责回收。
}
else
{
// 如果没有在播放,直接回收
LeanPool.Despawn(gameObject);
}
}
public void Pause(int fadeOutMs = 0)
{
if (playingID != AkUnitySoundEngine.AK_INVALID_PLAYING_ID)
{
AkUnitySoundEngine.ExecuteActionOnPlayingID(
AkActionOnEventType.AkActionOnEventType_Pause,
playingID, fadeOutMs,
AkCurveInterpolation.AkCurveInterpolation_Linear
);
}
}
// 【新增】继续
public void Resume(int fadeInMs = 0)
{
if (playingID != AkUnitySoundEngine.AK_INVALID_PLAYING_ID)
{
AkUnitySoundEngine.ExecuteActionOnPlayingID(
AkActionOnEventType.AkActionOnEventType_Resume,
playingID, fadeInMs,
AkCurveInterpolation.AkCurveInterpolation_Linear
);
}
}
}
public partial class AudioPoint
{
/// <summary>
/// Wwise 内部回调
/// </summary>
private void OnEventFinished(object in_cookie, AkCallbackType in_type, object in_info)
{
if (in_type == AkCallbackType.AK_EndOfEvent)
{
// 确保在 Unity 主线程且对象有效时回收
// (Wwise 回调通常在主线程,但为了防止 Destroy 竞争条件,加个检查)
if (this != null && gameObject.activeInHierarchy)
{
LeanPool.Despawn(gameObject);
}
}
}
public override void OnDespawn()
{
playingID = AkUnitySoundEngine.AK_INVALID_PLAYING_ID;
eventID = 0;
base.OnDespawn();
}
}
}