using UnityEngine;
using Lean.Pool;
using AK.Wwise;
using SLSUtilities.LeanPoolAssistance; // 引用 Wwise
namespace SLSUtilities.WwiseAssistance
{
///
/// 挂载在 AudioPoint 预制体上,负责管理单个音频实例的生命周期
///
public partial class AudioPoint : PooledObject
{
public uint playingID = AkUnitySoundEngine.AK_INVALID_PLAYING_ID;
public uint eventID = uint.MaxValue;
///
/// 播放指定 ID 的事件
///
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;
}
///
/// 手动停止播放(支持淡出),用于 Loop 音效
///
/// 淡出时间(毫秒)
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
{
///
/// Wwise 内部回调
///
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();
}
}
}