2025-12-31 15:56:05 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections;
|
2025-03-06 17:24:31 +08:00
|
|
|
|
using System.Collections.Generic;
|
2025-12-19 11:55:13 +08:00
|
|
|
|
using System.Threading;
|
2025-12-31 15:56:05 +08:00
|
|
|
|
using Cysharp.Threading.Tasks;
|
2025-03-06 17:24:31 +08:00
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
2025-03-31 11:49:53 +08:00
|
|
|
|
namespace Stary.Evo.AudioCore
|
2025-03-06 17:24:31 +08:00
|
|
|
|
{
|
2025-03-07 17:52:50 +08:00
|
|
|
|
/// <summary>
|
2025-03-31 11:49:53 +08:00
|
|
|
|
/// Audio数据
|
2025-03-07 17:52:50 +08:00
|
|
|
|
/// </summary>
|
2025-03-26 09:34:52 +08:00
|
|
|
|
public struct AudioData
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2025-03-31 11:49:53 +08:00
|
|
|
|
/// 延迟播放时间
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public float delayTime;
|
2025-03-07 17:52:50 +08:00
|
|
|
|
|
2025-12-31 15:56:05 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 资源包名
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string packageName;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 资源名
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string assetName;
|
|
|
|
|
|
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// <summary>
|
2025-03-31 11:49:53 +08:00
|
|
|
|
/// 音频
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public AudioClip clip;
|
2025-03-07 17:52:50 +08:00
|
|
|
|
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// <summary>
|
2025-03-31 11:49:53 +08:00
|
|
|
|
/// 音量
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public float volume;
|
2025-03-06 17:24:31 +08:00
|
|
|
|
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// <summary>
|
2025-03-31 11:49:53 +08:00
|
|
|
|
/// 回调行为
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public System.Action onComplete;
|
2025-03-06 17:24:31 +08:00
|
|
|
|
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// <summary>
|
2025-03-31 11:49:53 +08:00
|
|
|
|
/// 延迟回调执行的时间
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public float delayOnCompleteTime;
|
2025-03-06 17:24:31 +08:00
|
|
|
|
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// <summary>
|
2025-03-31 11:49:53 +08:00
|
|
|
|
/// 自然过渡时间
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public float fadeDuration;
|
2025-03-06 17:24:31 +08:00
|
|
|
|
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// <summary>
|
2025-03-31 11:49:53 +08:00
|
|
|
|
/// 是否不打断上一段对话
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool isNotOverVoice;
|
2025-12-31 15:56:05 +08:00
|
|
|
|
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// <summary>
|
2025-07-16 13:54:05 +08:00
|
|
|
|
/// 是否是3D音频
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// </summary>
|
2025-07-16 13:54:05 +08:00
|
|
|
|
public bool is3DAudio;
|
2025-03-07 17:52:50 +08:00
|
|
|
|
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// <summary>
|
2025-07-16 13:54:05 +08:00
|
|
|
|
/// 3D声音位置
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public Vector3 audio3DPosition;
|
2025-12-31 15:56:05 +08:00
|
|
|
|
|
2025-07-16 13:54:05 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 3D声音最大距离
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// </summary>
|
2025-12-31 15:56:05 +08:00
|
|
|
|
public float audio3DMaxDistance;
|
2025-03-26 09:34:52 +08:00
|
|
|
|
}
|
2025-03-07 17:52:50 +08:00
|
|
|
|
|
2025-03-26 09:34:52 +08:00
|
|
|
|
public interface IAudio
|
|
|
|
|
|
{
|
2025-12-31 15:56:05 +08:00
|
|
|
|
IResources Resources { get; set; }
|
|
|
|
|
|
AudioSourcePool AudioSourcePool { get; set; }
|
|
|
|
|
|
AudioData Initialize(AudioData audioData);
|
2025-03-26 09:34:52 +08:00
|
|
|
|
void Play(AudioData audioData);
|
2025-03-06 17:24:31 +08:00
|
|
|
|
|
2025-12-31 15:56:05 +08:00
|
|
|
|
UniTask PlayAsync(AudioData audioData);
|
|
|
|
|
|
UniTask FadeInMusic(AudioSource source, float fadeDuration);
|
|
|
|
|
|
UniTask FadeOutMusic(AudioSource source, float fadeDuration);
|
2025-03-06 17:24:31 +08:00
|
|
|
|
|
2025-06-04 14:57:54 +08:00
|
|
|
|
|
2025-12-31 15:56:05 +08:00
|
|
|
|
void Stop();
|
|
|
|
|
|
void StopAll();
|
2025-03-26 09:34:52 +08:00
|
|
|
|
}
|
2025-12-31 15:56:05 +08:00
|
|
|
|
|
2025-03-26 09:34:52 +08:00
|
|
|
|
public abstract class AbstractAudio : IAudio
|
|
|
|
|
|
{
|
2025-12-31 15:56:05 +08:00
|
|
|
|
public IResources Resources { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public AudioSourcePool AudioSourcePool { get; set; }
|
2025-03-26 09:34:52 +08:00
|
|
|
|
public abstract void Play(AudioData audioData);
|
2025-03-06 17:24:31 +08:00
|
|
|
|
|
2025-12-31 15:56:05 +08:00
|
|
|
|
public abstract UniTask PlayAsync(AudioData audioData);
|
|
|
|
|
|
|
|
|
|
|
|
public abstract void StopAll();
|
2025-06-04 14:57:54 +08:00
|
|
|
|
|
2025-03-06 17:24:31 +08:00
|
|
|
|
|
2025-12-31 15:56:05 +08:00
|
|
|
|
public virtual void Stop()
|
|
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected AbstractAudio(IResources resources)
|
|
|
|
|
|
{
|
|
|
|
|
|
Resources = resources;
|
|
|
|
|
|
if (!GetType().Name.Contains("Music"))
|
|
|
|
|
|
{
|
|
|
|
|
|
AudioSourcePool = new AudioSourcePool(GetType().Name, -1);
|
|
|
|
|
|
AudioSourcePool.Creation();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// <summary>
|
2025-03-31 11:49:53 +08:00
|
|
|
|
/// 音频数据初始化
|
2025-03-26 09:34:52 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="audioData"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2025-12-31 15:56:05 +08:00
|
|
|
|
public virtual AudioData Initialize(AudioData audioData)
|
2025-03-07 17:52:50 +08:00
|
|
|
|
{
|
2025-03-26 09:34:52 +08:00
|
|
|
|
if (audioData.volume == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
audioData.volume = 1f;
|
|
|
|
|
|
}
|
2025-07-22 11:06:30 +08:00
|
|
|
|
|
|
|
|
|
|
if (audioData.fadeDuration == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
audioData.fadeDuration = 1f;
|
|
|
|
|
|
}
|
2025-12-31 15:56:05 +08:00
|
|
|
|
|
2025-03-26 09:34:52 +08:00
|
|
|
|
return audioData;
|
2025-03-07 17:52:50 +08:00
|
|
|
|
}
|
2025-12-31 15:56:05 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 音频淡入
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="source"></param>
|
|
|
|
|
|
/// <param name="fadeDuration"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public async UniTask FadeInMusic(AudioSource source, float fadeDuration)
|
|
|
|
|
|
{
|
|
|
|
|
|
float targetVolume = source.volume;
|
|
|
|
|
|
source.volume = 0;
|
|
|
|
|
|
|
|
|
|
|
|
while (source.volume < targetVolume)
|
|
|
|
|
|
{
|
|
|
|
|
|
source.volume += targetVolume * Time.deltaTime / fadeDuration;
|
|
|
|
|
|
await UniTask.Yield();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 音频淡出
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="source"></param>
|
|
|
|
|
|
/// <param name="fadeDuration"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public async UniTask FadeOutMusic(AudioSource source, float fadeDuration)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (source != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
float startVolume = source.volume;
|
|
|
|
|
|
|
|
|
|
|
|
while (source.volume > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
source.volume -= startVolume * Time.deltaTime / fadeDuration;
|
|
|
|
|
|
await UniTask.Yield();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
source.Stop();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 播放音效的协程
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="source"></param>
|
|
|
|
|
|
/// <param name="delay"></param>
|
|
|
|
|
|
/// <param name="onComplete"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public async UniTask PlayAudioAWait(AudioSourceToken audioSourceToken, float delay, System.Action onComplete)
|
|
|
|
|
|
{
|
|
|
|
|
|
await PlayAudioAWait(audioSourceToken, delay);
|
|
|
|
|
|
onComplete?.Invoke();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 播放音效的协程
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="source"></param>
|
|
|
|
|
|
/// <param name="delay"></param>
|
|
|
|
|
|
/// <param name="onComplete"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public async UniTask PlayAudioAWait(AudioSourceToken audioSourceToken, float delay)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"PlayAudioAWait:{GetType().Name}");
|
|
|
|
|
|
if (!GetType().Name.Contains("Voice"))
|
|
|
|
|
|
{
|
|
|
|
|
|
await UniTask.Delay(TimeSpan.FromSeconds(audioSourceToken.source.clip.length - 2f),
|
|
|
|
|
|
cancellationToken: audioSourceToken.cancellationToken.Token);
|
|
|
|
|
|
await FadeOutMusic(audioSourceToken.source, 2f);
|
|
|
|
|
|
await UniTask.Delay(TimeSpan.FromSeconds(delay),
|
|
|
|
|
|
cancellationToken: audioSourceToken.cancellationToken.Token);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
await UniTask.Delay(TimeSpan.FromSeconds(audioSourceToken.source.clip.length + delay),
|
|
|
|
|
|
cancellationToken: audioSourceToken.cancellationToken.Token);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
AudioSourcePool.RecycleSpawn(audioSourceToken);
|
|
|
|
|
|
}
|
2025-03-07 17:52:50 +08:00
|
|
|
|
}
|
2025-12-31 15:56:05 +08:00
|
|
|
|
}
|