107 lines
3.7 KiB
C#
107 lines
3.7 KiB
C#
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();
|
||
}
|
||
}
|
||
} |