124 lines
5.3 KiB
C#
124 lines
5.3 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace OCES.Audio
|
|
{
|
|
/// <summary>
|
|
/// 环境音通道播放器。
|
|
/// 与 MusicChannelPlayer 逻辑相同,但使用 AmbienceTransition 表,不涉及节拍对齐。
|
|
/// </summary>
|
|
class AmbienceChannelPlayer
|
|
{
|
|
readonly AmbienceTransitionConfig m_transitionConfig;
|
|
readonly MonoBehaviour m_coroutineHost;
|
|
readonly ChannelFader m_fader;
|
|
readonly List<AmbienceTransition> m_transitionCandidates = new();
|
|
|
|
ContainerPlayHandle m_currentHandle;
|
|
Coroutine m_transitionCoroutine;
|
|
Coroutine m_currentFadeOutCoroutine;
|
|
Coroutine m_currentFadeInCoroutine;
|
|
|
|
uint m_currentContainerId;
|
|
|
|
internal AmbienceChannelPlayer(
|
|
AmbienceTransitionConfig transitionConfig,
|
|
LongAudioContainerPlayer player,
|
|
MonoBehaviour coroutineHost)
|
|
{
|
|
this.m_transitionConfig = transitionConfig;
|
|
this.m_coroutineHost = coroutineHost;
|
|
this.m_fader = new ChannelFader(player, coroutineHost);
|
|
}
|
|
|
|
// ─────────────────────────────────────────────
|
|
// 公开接口
|
|
// ─────────────────────────────────────────────
|
|
|
|
internal void SwitchTo(uint newContainerId)
|
|
{
|
|
if (newContainerId == this.m_currentContainerId && this.m_currentHandle != null)
|
|
return;
|
|
|
|
AmbienceTransition transition = ResolveTransition((int)this.m_currentContainerId, (int)newContainerId);
|
|
|
|
if (this.m_transitionCoroutine != null)
|
|
this.m_coroutineHost.StopCoroutine(this.m_transitionCoroutine);
|
|
|
|
this.m_transitionCoroutine = this.m_coroutineHost.StartCoroutine(
|
|
DoTransition(newContainerId, transition));
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
if (this.m_transitionCoroutine != null)
|
|
this.m_coroutineHost.StopCoroutine(this.m_transitionCoroutine);
|
|
|
|
this.m_fader.StopCurrent();
|
|
}
|
|
|
|
// ─────────────────────────────────────────────
|
|
// Transition 流程(无节拍对齐)
|
|
// ─────────────────────────────────────────────
|
|
|
|
IEnumerator DoTransition(uint newContainerId, AmbienceTransition transition)
|
|
{
|
|
if (newContainerId == this.m_fader.CurrentContainerId && this.m_fader.CurrentHandle != null) yield break;
|
|
// 如果等待期间被切回来了,就不淡变了
|
|
|
|
if (this.m_currentFadeInCoroutine != null)
|
|
{
|
|
this.m_coroutineHost.StopCoroutine(this.m_currentFadeInCoroutine);
|
|
this.m_currentFadeInCoroutine = null;
|
|
}
|
|
|
|
if (this.m_currentFadeOutCoroutine != null)
|
|
{
|
|
this.m_coroutineHost.StopCoroutine(this.m_currentFadeOutCoroutine);
|
|
this.m_currentFadeOutCoroutine = null;
|
|
}
|
|
|
|
ContainerPlayHandle outgoing = this.m_fader.CurrentHandle;
|
|
float outgoingVolume = this.m_fader.CurrentVolume;
|
|
|
|
this.m_currentFadeOutCoroutine = this.m_coroutineHost.StartCoroutine(
|
|
this.m_fader.FadeOutBranch(outgoing, outgoingVolume, transition));
|
|
|
|
this.m_currentFadeInCoroutine = this.m_coroutineHost.StartCoroutine(
|
|
this.m_fader.FadeInBranch(newContainerId, transition));
|
|
yield return this.m_currentFadeInCoroutine;
|
|
this.m_currentFadeInCoroutine = null;
|
|
}
|
|
|
|
// ─────────────────────────────────────────────
|
|
// 工具
|
|
// ─────────────────────────────────────────────
|
|
|
|
AmbienceTransition ResolveTransition(int sourceContainerId, int destinationContainerId)
|
|
{
|
|
this.m_transitionCandidates.Clear();
|
|
foreach (AmbienceTransition transition in this.m_transitionConfig.AmbienceTransitionList())
|
|
{
|
|
bool sourceMatch = transition.SourceContainerID == sourceContainerId || transition.SourceContainerID < 0;
|
|
bool destMatch = transition.DestinationContainerID == destinationContainerId || transition.DestinationContainerID < 0;
|
|
if (sourceMatch && destMatch)
|
|
{
|
|
this.m_transitionCandidates.Add(transition);
|
|
}
|
|
}
|
|
|
|
if (this.m_transitionCandidates.Count == 0)
|
|
return this.m_transitionConfig.QueryById(1);
|
|
|
|
AmbienceTransition best = this.m_transitionCandidates[0];
|
|
for (int i = 1; i < this.m_transitionCandidates.Count; i++)
|
|
{
|
|
if (this.m_transitionCandidates[i].Id > best.Id)
|
|
best = this.m_transitionCandidates[i];
|
|
}
|
|
return best;
|
|
}
|
|
}
|
|
}
|