Files
AudioSystem/Assets/Scripts/OCES/Audio/HandWritten/AmbienceChannelPlayer.cs
T
2026-03-20 18:48:11 +08:00

100 lines
4.1 KiB
C#

using System.Collections;
using UnityEngine;
namespace OCES.Audio
{
/// <summary>
/// 环境音通道播放器。
/// 与 MusicChannelPlayer 逻辑相同,但使用 AmbienceTransition 表,不涉及节拍对齐。
/// </summary>
public class AmbienceChannelPlayer
{
readonly AmbienceTransitionConfig m_transitionConfig;
readonly MonoBehaviour m_coroutineHost;
readonly ChannelFader m_fader;
ContainerPlayHandle m_currentHandle;
Coroutine m_transitionCoroutine;
uint m_currentContainerId;
public AmbienceChannelPlayer(
AmbienceTransitionConfig transitionConfig,
MusicContainerPlayer player,
MonoBehaviour coroutineHost)
{
this.m_transitionConfig = transitionConfig;
this.m_coroutineHost = coroutineHost;
this.m_fader = new ChannelFader(player, coroutineHost);
}
// ─────────────────────────────────────────────
// 公开接口
// ─────────────────────────────────────────────
public void SwitchTo(uint newContainerId, uint fromPathId, uint toPathId)
{
if (newContainerId == this.m_currentContainerId && this.m_currentHandle != null)
return;
AmbienceTransition transition = ResolveTransition(fromPathId, toPathId);
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)
{
ContainerPlayHandle outgoing = this.m_fader.CurrentHandle;
float outgoingVolume = this.m_fader.CurrentVolume;
this.m_coroutineHost.StartCoroutine(
this.m_fader.FadeOutBranch(outgoing, outgoingVolume, transition));
yield return this.m_coroutineHost.StartCoroutine(
this.m_fader.FadeInBranch(newContainerId, transition));
}
// ─────────────────────────────────────────────
// 工具
// ─────────────────────────────────────────────
AmbienceTransition ResolveTransition(uint fromPathId, uint toPathId)
{
// 优先精确匹配
uint exactId = fromPathId * 1000 + toPathId;
AmbienceTransition exact = this.m_transitionConfig.QueryById(exactId);
if (exact != null) return exact;
// From 为任意
uint fromWildcard = 999u * 1000 + toPathId;
AmbienceTransition fromWild = this.m_transitionConfig.QueryById(fromWildcard);
if (fromWild != null) return fromWild;
// To 为任意
uint toWildcard = fromPathId * 1000 + 999u;
AmbienceTransition toWild = this.m_transitionConfig.QueryById(toWildcard);
if (toWild != null) return toWild;
// 全通配
const uint allWild = 999u * 1000 + 999u;
return this.m_transitionConfig.QueryById(allWild);
}
}
}