refactor: 重构 Transition 查询逻辑,移除 PathId 改用 ContainerId 匹配

This commit is contained in:
2026-04-28 15:30:01 +08:00
parent 2fa3fa49d7
commit 8ea862b546
13 changed files with 204 additions and 78 deletions
@@ -1,5 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace OCES.Audio
@@ -15,27 +17,21 @@ namespace OCES.Audio
readonly MonoBehaviour m_coroutineHost;
readonly ChannelFader m_fader;
readonly BeatClock m_beatClock;
readonly List<MusicTransition> m_transitionCandidates = new();
Coroutine m_currentFadeInCoroutine;
Coroutine m_currentFadeOutCoroutine;
// 当前正在播放的句柄
ContainerPlayHandle m_currentHandle;
uint m_currentContainerId;
// 当前播放的 Container(用于读取 bpm/timeSig 做节拍对齐)
MusicContainer m_currentContainer;
// 当前播放开始的时间(用于计算当前播到哪个拍子)
double m_playStartTime;
// 正在进行的 transition 协程(防止重叠)
Coroutine m_transitionCoroutine;
internal MusicChannelPlayer(
MusicContainerConfig containerConfig,
MusicTransitionConfig transitionConfig,
MusicContainerPlayer player,
LongAudioContainerPlayer player,
MonoBehaviour coroutineHost,
Action<uint> onBeat,
Action<uint> onBar,
@@ -56,14 +52,14 @@ namespace OCES.Audio
/// <summary>
/// 切换到新的 Container。
/// fromPathId / toPathId 用于查询 Transition 配置。
/// </summary>
internal void SwitchTo(uint newContainerId, uint fromPathId, uint toPathId)
internal void SwitchTo(uint newContainerId)
{
if (newContainerId == this.m_currentContainerId && this.m_currentHandle != null)
if (newContainerId == this.m_fader.CurrentContainerId && this.m_fader.CurrentHandle != null)
return; // 已经在播目标,无需切换
MusicTransition transition = ResolveTransition(fromPathId, toPathId);
MusicTransition transition = ResolveTransition((int)this.m_fader.CurrentContainerId, (int)newContainerId);
//Debug.Log($"[MusicChannelPlayer] Switch from {this.m_fader.CurrentContainerId} to {newContainerId} with transition {transition.Id}");
if (this.m_transitionCoroutine != null)
this.m_coroutineHost.StopCoroutine(this.m_transitionCoroutine);
@@ -181,7 +177,6 @@ namespace OCES.Audio
}
this.m_currentContainer = container;
this.m_playStartTime = dspTime;
this.m_beatClock.Restart(container, bpm, dspTime);
}));
yield return this.m_currentFadeInCoroutine;
@@ -206,29 +201,31 @@ namespace OCES.Audio
// ─────────────────────────────────────────────
/// <summary>
/// 查询 Transition 配置,支持精确匹配和 999 通配符。
/// ID 规则:FromPathId × 1000 + ToPathId999 表示任意。
/// 查询 Transition 配置,支持精确匹配和 -1 通配符。
/// </summary>
MusicTransition ResolveTransition(uint fromPathId, uint toPathId)
MusicTransition ResolveTransition(int sourceContainerId, int destinationContainerId)
{
// 优先精确匹配
uint exactId = fromPathId * 1000 + toPathId;
MusicTransition exact = this.m_transitionConfig.QueryById(exactId);
if (exact != null) return exact;
this.m_transitionCandidates.Clear();
foreach (MusicTransition transition in this.m_transitionConfig.MusicTransitionList())
{
bool sourceMatch = transition.SourceContainerID == sourceContainerId || transition.SourceContainerID < 0;
bool destMatch = transition.DestinationContainerID == destinationContainerId || transition.DestinationContainerID < 0;
if (sourceMatch && destMatch)
{
this.m_transitionCandidates.Add(transition);
}
}
// From 为任意
uint fromWildcard = 999u * 1000 + toPathId;
MusicTransition fromWild = this.m_transitionConfig.QueryById(fromWildcard);
if (fromWild != null) return fromWild;
if (this.m_transitionCandidates.Count == 0)
return this.m_transitionConfig.QueryById(1);
// To 为任意
uint toWildcard = fromPathId * 1000 + 999u;
MusicTransition toWild = this.m_transitionConfig.QueryById(toWildcard);
if (toWild != null) return toWild;
// 全通配
const uint allWild = 999u * 1000 + 999u;
return this.m_transitionConfig.QueryById(allWild);
MusicTransition 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;
}
}
}