整合SLSUtilities
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Lean.Pool;
|
||||
using Sirenix.OdinInspector;
|
||||
using UniRx;
|
||||
using UnityEngine;
|
||||
using Event = AK.Wwise.Event;
|
||||
|
||||
namespace SLSFramework.WwiseAssistance
|
||||
{
|
||||
public class AudioContainer : SerializedMonoBehaviour
|
||||
{
|
||||
public Dictionary<string, Event> soundEventDictionary = new Dictionary<string, Event>();
|
||||
|
||||
private HashSet<uint> normalAudioPlayingIDs;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
soundEventDictionary ??= new Dictionary<string, Event>();
|
||||
normalAudioPlayingIDs = new HashSet<uint>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发自定义的Wwise事件
|
||||
/// </summary>
|
||||
public void PostEvent(string eventName, GameObject attachedObject = null)
|
||||
{
|
||||
Event evt = soundEventDictionary[eventName];
|
||||
|
||||
if (evt == null) return;
|
||||
|
||||
attachedObject = attachedObject == null ? gameObject : attachedObject;
|
||||
evt.Post(attachedObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 依附于GameObject播放3D音频,attachedObject为null时默认为当前GameObject
|
||||
/// </summary>
|
||||
public uint PlaySoundFX(string soundName, GameObject attachedObject = null, bool spawnTempObject = false)
|
||||
{
|
||||
if (!soundEventDictionary.TryGetValue(soundName, out Event sound))
|
||||
{
|
||||
Debug.LogWarning($"Sound event '{soundName}' not found in dictionary.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
attachedObject = attachedObject == null ? gameObject : attachedObject;
|
||||
|
||||
uint playingID; // *** 修正 ***: 在这里声明 playingID
|
||||
|
||||
if (spawnTempObject)
|
||||
{
|
||||
GameObject soundObj = LeanPool.Spawn(AudioManager.Instance.audioPoint, attachedObject.transform);
|
||||
|
||||
// *** 修正 ***:
|
||||
// 1. 将 soundObj 本身作为 cookie 传递。
|
||||
// 2. 捕获 Post() 返回的
|
||||
playingID = sound.Post(soundObj, (uint)AkCallbackType.AK_EndOfEvent, AutoDespawnCallback, soundObj);
|
||||
soundObj.name = $"{soundName}-WwiseEvent{playingID}"; // 使用正确的 playingID
|
||||
}
|
||||
else
|
||||
{
|
||||
// *** 修正 ***:
|
||||
// 1. cookie 传递 null,因为我们不需要它。
|
||||
// 2. 捕获 Post() 返回的 playingID。
|
||||
playingID = sound.Post(attachedObject,(uint)AkCallbackType.AK_EndOfEvent, OnEventCallback, null);
|
||||
}
|
||||
|
||||
// *** 修正 ***:
|
||||
// 将捕获到的、正确的 playingID 添加到集合中
|
||||
// (还应检查 Post 是否成功,不为0)
|
||||
if (playingID != 0)
|
||||
{
|
||||
normalAudioPlayingIDs.Add(playingID);
|
||||
}
|
||||
|
||||
return playingID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在指定位置播放3D音频
|
||||
/// </summary>
|
||||
public uint PlaySoundFX(string soundName, Vector3 position, bool isLoop = false)
|
||||
{
|
||||
Event sound = soundEventDictionary[soundName];
|
||||
if (sound == null) return 0;
|
||||
|
||||
GameObject soundObj = LeanPool.Spawn(AudioManager.Instance.audioPoint, position, Quaternion.identity);
|
||||
|
||||
// *** 修正 ***:
|
||||
// 1. 将 soundObj 作为 cookie 传递。
|
||||
// 2. 捕获 Post() 返回的 playingID。
|
||||
uint playingID = sound.Post(soundObj, (uint)AkCallbackType.AK_EndOfEvent, AutoDespawnCallback, soundObj);
|
||||
soundObj.name = $"{soundName}-WwiseEvent{playingID}"; // 使用正确的 playingID
|
||||
|
||||
if (playingID != 0)
|
||||
{
|
||||
normalAudioPlayingIDs.Add(playingID);
|
||||
}
|
||||
|
||||
return playingID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止播放音效
|
||||
/// </summary>
|
||||
public void StopSoundFX(uint playingID)
|
||||
{
|
||||
if (normalAudioPlayingIDs.Contains(playingID))
|
||||
{
|
||||
AkUnitySoundEngine.StopPlayingID(playingID);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"No sound is playing with PlayingID: {playingID}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 以淡出效果停止播放音效
|
||||
/// </summary>
|
||||
public void StopSoundWithFadeOut(uint playingID, float fadeOutDuration)
|
||||
{
|
||||
if (normalAudioPlayingIDs.Contains(playingID))
|
||||
{
|
||||
AkUnitySoundEngine.ExecuteActionOnPlayingID(
|
||||
AkActionOnEventType.AkActionOnEventType_Stop,
|
||||
playingID,
|
||||
(int)(fadeOutDuration * 1000), // 将秒数转为毫秒
|
||||
AkCurveInterpolation.AkCurveInterpolation_Sine // 选择淡出曲线
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"No sound is playing with PlayingID: {playingID}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动回收临时音频对象
|
||||
/// </summary>
|
||||
private void AutoDespawnCallback(object in_cookie, AkCallbackType in_type, AkCallbackInfo in_info)
|
||||
{
|
||||
if (in_type == AkCallbackType.AK_EndOfEvent)
|
||||
{
|
||||
// *** 修正 ***: cookie 现在是 GameObject
|
||||
GameObject soundObj = (GameObject)in_cookie;
|
||||
|
||||
// *** 修正 ***: 从 AkCallbackInfo (in_info) 中获取 playingID
|
||||
uint playingID = 0;
|
||||
if (in_info is AkEventCallbackInfo eventInfo)
|
||||
{
|
||||
playingID = eventInfo.playingID;
|
||||
}
|
||||
|
||||
if (playingID != 0 && normalAudioPlayingIDs.Contains(playingID))
|
||||
{
|
||||
normalAudioPlayingIDs.Remove(playingID);
|
||||
if (soundObj != null) // 最好检查一下对象是否仍然存在
|
||||
{
|
||||
LeanPool.Despawn(soundObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEventCallback(object in_cookie, AkCallbackType in_type, AkCallbackInfo in_info)
|
||||
{
|
||||
if (in_type == AkCallbackType.AK_EndOfEvent)
|
||||
{
|
||||
// *** 修正 ***: 从 AkCallbackInfo (in_info) 中获取 playingID
|
||||
uint playingID = 0;
|
||||
if (in_info is AkEventCallbackInfo eventInfo)
|
||||
{
|
||||
playingID = eventInfo.playingID;
|
||||
}
|
||||
|
||||
if (playingID != 0 && normalAudioPlayingIDs.Contains(playingID))
|
||||
{
|
||||
normalAudioPlayingIDs.Remove(playingID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02ab9c91fe7438e47b00faa9866da79e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using AK.Wwise;
|
||||
using SLSFramework.General;
|
||||
|
||||
namespace SLSFramework.WwiseAssistance
|
||||
{
|
||||
public class AudioManager : Singleton<AudioManager>
|
||||
{
|
||||
public GameObject audioPoint;
|
||||
public List<Bank> soundBanks;
|
||||
|
||||
public BackgroundMusicManager backgroundMusicManager;
|
||||
public AudioContainer generalSoundEffects;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
soundBanks.ForEach(bank => bank.Load());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86e86add9ce9c434e8022154ae0c00e7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using AK.Wwise;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace SLSFramework.WwiseAssistance
|
||||
{
|
||||
public class BackgroundMusicManager : SerializedMonoBehaviour
|
||||
{
|
||||
public Dictionary<string, State> baseMusicDictionary; // 背景音乐事件字典
|
||||
public Event playMusicEvent; // 播放背景音乐的事件
|
||||
public Event stopMusicEvent; // 停止播放背景音乐的事件
|
||||
|
||||
private void Start()
|
||||
{
|
||||
PlayMusic("NormalMusic");
|
||||
}
|
||||
|
||||
public void PlayMusic(string musicStateName)
|
||||
{
|
||||
//if (baseMusicDictionary.ContainsKey(musicStateName))
|
||||
{
|
||||
stopMusicEvent.Post(gameObject);
|
||||
//baseMusicDictionary[musicStateName].SetValue();
|
||||
playMusicEvent.Post(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
public void StopMusic()
|
||||
{
|
||||
stopMusicEvent.Post(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9eaf3d8d8a9f40a4ab52ce261804f4f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user