feat: SyncPoint.SameAsCurrentSegment music transition
- Add SameAsCurrentSegment mode to align new container's timeSamples with the old container's playback position, accounting for FadeInOffset - Fix BeatClock callback burst when Restart is called with a past dspTime - Add GetFirstLeafSource() for resolving playback position across nested containers - Manual BeatClock.Restart replaces OnContainerEntered subscription for accurate timing with SyncPoint
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -2579,6 +2579,7 @@ GameObject:
|
|||||||
m_Component:
|
m_Component:
|
||||||
- component: {fileID: 2093584671}
|
- component: {fileID: 2093584671}
|
||||||
- component: {fileID: 2093584670}
|
- component: {fileID: 2093584670}
|
||||||
|
- component: {fileID: 2093584672}
|
||||||
m_Layer: 0
|
m_Layer: 0
|
||||||
m_Name: AudioSystem
|
m_Name: AudioSystem
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
@@ -2613,6 +2614,18 @@ Transform:
|
|||||||
m_Children: []
|
m_Children: []
|
||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &2093584672
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 2093584669}
|
||||||
|
m_Enabled: 0
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: a3d8ad76f12545caa287f26889c674e3, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
--- !u!1660057539 &9223372036854775807
|
--- !u!1660057539 &9223372036854775807
|
||||||
SceneRoots:
|
SceneRoots:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ namespace OCES.Audio
|
|||||||
{
|
{
|
||||||
// ── 启动默认音乐与环境音 ──
|
// ── 启动默认音乐与环境音 ──
|
||||||
// 触发一次初始状态,让音乐系统从默认状态开始匹配
|
// 触发一次初始状态,让音乐系统从默认状态开始匹配
|
||||||
//SetState(GameState.Home);
|
SetState(GameState.Home);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioObject ResolveSwitchContainer(AudioObject switchContainer)
|
AudioObject ResolveSwitchContainer(AudioObject switchContainer)
|
||||||
|
|||||||
@@ -65,15 +65,16 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
IEnumerator BeatCoroutine()
|
IEnumerator BeatCoroutine()
|
||||||
{
|
{
|
||||||
long index = 0; // 从第 1 拍开始,第 0 拍是起始点本身
|
double elapsed = AudioSettings.dspTime - this.m_startDspTime;
|
||||||
|
long index = elapsed > 0.05 ? (long)(elapsed / this.m_secondsPerBeat) : 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
double nextTime = this.m_startDspTime + index * this.m_secondsPerBeat;
|
double nextTime = this.m_startDspTime + index * this.m_secondsPerBeat;
|
||||||
yield return new WaitUntil(() => AudioSettings.dspTime >= nextTime - 0.02);
|
yield return new WaitUntil(() => AudioSettings.dspTime >= nextTime - 0.02);
|
||||||
|
|
||||||
while (AudioSettings.dspTime < nextTime)
|
while (AudioSettings.dspTime < nextTime)
|
||||||
yield return null;
|
yield return null;
|
||||||
|
|
||||||
if (this.m_blendError || this.m_stopped){
|
if (this.m_blendError || this.m_stopped){
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
@@ -84,12 +85,14 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
IEnumerator BarCoroutine()
|
IEnumerator BarCoroutine()
|
||||||
{
|
{
|
||||||
long index = 0;
|
double elapsed = AudioSettings.dspTime - this.m_startDspTime;
|
||||||
|
double secondsPerBar = this.m_secondsPerBeat * this.m_beatsPerBar;
|
||||||
|
long index = elapsed > 0.05 ? (long)(elapsed / secondsPerBar) : 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
double nextTime = this.m_startDspTime + index * this.m_secondsPerBeat * this.m_beatsPerBar;
|
double nextTime = this.m_startDspTime + index * secondsPerBar;
|
||||||
yield return new WaitUntil(() => AudioSettings.dspTime >= nextTime - 0.02);
|
yield return new WaitUntil(() => AudioSettings.dspTime >= nextTime - 0.02);
|
||||||
|
|
||||||
while (AudioSettings.dspTime < nextTime)
|
while (AudioSettings.dspTime < nextTime)
|
||||||
yield return null;
|
yield return null;
|
||||||
if (this.m_blendError || this.m_stopped){
|
if (this.m_blendError || this.m_stopped){
|
||||||
@@ -102,12 +105,14 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
IEnumerator GridCoroutine()
|
IEnumerator GridCoroutine()
|
||||||
{
|
{
|
||||||
long index = 0;
|
double elapsed = AudioSettings.dspTime - this.m_startDspTime;
|
||||||
|
double secondsPerGrid = this.m_secondsPerBeat * this.m_beatsPerBar * this.m_barsPerGrid;
|
||||||
|
long index = elapsed > 0.05 ? (long)(elapsed / secondsPerGrid) : 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
double nextTime = this.m_startDspTime + index * this.m_secondsPerBeat * this.m_beatsPerBar * this.m_barsPerGrid;
|
double nextTime = this.m_startDspTime + index * secondsPerGrid;
|
||||||
yield return new WaitUntil(() => AudioSettings.dspTime >= nextTime - 0.02);
|
yield return new WaitUntil(() => AudioSettings.dspTime >= nextTime - 0.02);
|
||||||
|
|
||||||
while (AudioSettings.dspTime < nextTime)
|
while (AudioSettings.dspTime < nextTime)
|
||||||
yield return null;
|
yield return null;
|
||||||
if (this.m_blendError || this.m_stopped){
|
if (this.m_blendError || this.m_stopped){
|
||||||
|
|||||||
@@ -6,6 +6,18 @@ using DG.Tweening;
|
|||||||
|
|
||||||
namespace OCES.Audio
|
namespace OCES.Audio
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// SyncPoint 协调状态,在 FadeOutBranch 和 FadeInBranch 之间共享。
|
||||||
|
/// </summary>
|
||||||
|
internal class SyncPointState
|
||||||
|
{
|
||||||
|
public SyncPoint Mode;
|
||||||
|
public int BaseTimeSamples; // 读取旧 Source 时的 timeSamples
|
||||||
|
public double BaseDspTime; // 读取旧 Source 时的 dspTime
|
||||||
|
public int SampleRate; // 旧 Source 的采样率
|
||||||
|
public bool Ready;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 与Transition无关的音量/生命周期管理逻辑
|
/// 与Transition无关的音量/生命周期管理逻辑
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -47,16 +59,20 @@ namespace OCES.Audio
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 淡出分支:fire-and-forget,由调用方 StartCoroutine
|
/// 淡出分支:fire-and-forget,由调用方 StartCoroutine
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal IEnumerator FadeOutBranch(ContainerPlayHandle outgoingHandle, float outgoingVolume, ITransitionConfig transition)
|
internal IEnumerator FadeOutBranch(
|
||||||
|
ContainerPlayHandle outgoingHandle,
|
||||||
|
float outgoingVolume,
|
||||||
|
ITransitionConfig transition,
|
||||||
|
SyncPointState syncState = null)
|
||||||
{
|
{
|
||||||
if (outgoingHandle == null) yield break;
|
if (outgoingHandle == null) yield break;
|
||||||
|
|
||||||
if (transition?.FadeOutOffset > 0f)
|
if (transition?.FadeOutOffset > 0f)
|
||||||
{
|
{
|
||||||
//Debug.Log($"Waiting for {transition.FadeOutOffset} to fade out.");
|
//Debug.Log($"Waiting for {transition.FadeOutOffset} to fade out.");
|
||||||
yield return new WaitForSeconds(transition.FadeOutOffset);
|
yield return new WaitForSeconds(transition.FadeOutOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transition?.FadeOutTime > 0f )
|
if (transition?.FadeOutTime > 0f )
|
||||||
yield return this.m_coroutineHost.StartCoroutine(
|
yield return this.m_coroutineHost.StartCoroutine(
|
||||||
FadeOut(outgoingHandle, outgoingVolume, transition.FadeOutTime));
|
FadeOut(outgoingHandle, outgoingVolume, transition.FadeOutTime));
|
||||||
@@ -68,23 +84,52 @@ namespace OCES.Audio
|
|||||||
/// 淡入分支:等待 FadeInOffset 后启动新音乐并淡入。
|
/// 淡入分支:等待 FadeInOffset 后启动新音乐并淡入。
|
||||||
/// 主协程 yield return 此分支,以便 DoTransition 在新音乐就绪后才结束。
|
/// 主协程 yield return 此分支,以便 DoTransition 在新音乐就绪后才结束。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal IEnumerator FadeInBranch(uint newContainerId, ITransitionConfig transition, Action onContainerStarted = null)
|
internal IEnumerator FadeInBranch(uint newContainerId, ITransitionConfig transition, SyncPointState syncState = null, Action onContainerStarted = null)
|
||||||
{
|
{
|
||||||
if (transition?.FadeInOffset > 0f)
|
if (transition?.FadeInOffset > 0f)
|
||||||
{
|
{
|
||||||
//Debug.Log($"Waiting {transition.FadeInOffset} to fade in.");
|
//Debug.Log($"Waiting {transition.FadeInOffset} to fade in.");
|
||||||
yield return new WaitForSeconds(transition.FadeInOffset);
|
yield return new WaitForSeconds(transition.FadeInOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newContainerId == 0)
|
if (newContainerId == 0)
|
||||||
{
|
{
|
||||||
CurrentHandle = null;
|
CurrentHandle = null;
|
||||||
CurrentContainerId = 0;
|
CurrentContainerId = 0;
|
||||||
|
if (syncState != null) syncState.Ready = true;
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float startVolume = transition?.FadeInTime > 0f ? 0f : 1f;
|
float startVolume = transition?.FadeInTime > 0f ? 0f : 1f;
|
||||||
StartNew(newContainerId, startVolume);
|
StartNew(newContainerId, startVolume);
|
||||||
|
|
||||||
|
// SyncPoint: 获取新 Segment 的 AudioSource 并设置 timeSamples
|
||||||
|
if (syncState is { Mode: SyncPoint.SameAsCurrentSegment })
|
||||||
|
{
|
||||||
|
AudioSource newSource = CurrentHandle?.GetFirstLeafSource();
|
||||||
|
if (newSource != null && newSource.clip != null)
|
||||||
|
{
|
||||||
|
// 计算从读取旧 Source 到现在经过的 samples
|
||||||
|
double elapsedSeconds = AudioSettings.dspTime - syncState.BaseDspTime;
|
||||||
|
int elapsedSamples = (int)(elapsedSeconds * syncState.SampleRate);
|
||||||
|
int targetTimeSamples = syncState.BaseTimeSamples + elapsedSamples;
|
||||||
|
|
||||||
|
if (targetTimeSamples < newSource.clip.samples)
|
||||||
|
{
|
||||||
|
newSource.timeSamples = targetTimeSamples;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError($"[ChannelFader] SyncPoint.SameAsCurrentSegment: 新音频 samples({newSource.clip.samples}) <= 目标 samples({targetTimeSamples}),降级为 Start");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError($"[ChannelFader] SyncPoint.SameAsCurrentSegment: 未能获取新 Segment 的 AudioSource,降级为 Start");
|
||||||
|
}
|
||||||
|
syncState.Ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
onContainerStarted?.Invoke();
|
onContainerStarted?.Invoke();
|
||||||
|
|
||||||
if (transition?.FadeInTime > 0f)
|
if (transition?.FadeInTime > 0f)
|
||||||
|
|||||||
@@ -47,8 +47,7 @@ namespace OCES.Audio
|
|||||||
this.m_fader = new ChannelFader(player, coroutineHost);
|
this.m_fader = new ChannelFader(player, coroutineHost);
|
||||||
this.m_beatClock = new BeatClock(coroutineHost, onBeat, onBar, onGrid);
|
this.m_beatClock = new BeatClock(coroutineHost, onBeat, onBar, onGrid);
|
||||||
|
|
||||||
player.OnContainerEntered += this.m_beatClock.Restart;
|
player.OnBlendError += this.m_beatClock.OnBlendError;
|
||||||
player.OnBlendError += this.m_beatClock.OnBlendError;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─────────────────────────────────────────────
|
// ─────────────────────────────────────────────
|
||||||
@@ -103,7 +102,46 @@ namespace OCES.Audio
|
|||||||
this.m_coroutineHost.StopCoroutine(this.m_currentFadeOutCoroutine);
|
this.m_coroutineHost.StopCoroutine(this.m_currentFadeOutCoroutine);
|
||||||
this.m_currentFadeOutCoroutine = null;
|
this.m_currentFadeOutCoroutine = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── 构建 SyncPoint 状态 ──
|
||||||
|
SyncPointState syncState = new()
|
||||||
|
{
|
||||||
|
Mode = transition?.SyncPoint ?? SyncPoint.Start,
|
||||||
|
Ready = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
//Debug.Log($"[MusicChannelPlayer] DoTransition: transition?.SyncPoint={transition?.SyncPoint}, Mode={syncState.Mode}");
|
||||||
|
|
||||||
|
if (syncState.Mode == SyncPoint.SameAsCurrentSegment)
|
||||||
|
{
|
||||||
|
// 旧 Container 不存在(如游戏首次启动),静默降级为 Start
|
||||||
|
if (this.m_fader.CurrentHandle == null)
|
||||||
|
{
|
||||||
|
syncState.Mode = SyncPoint.Start;
|
||||||
|
}
|
||||||
|
// Blend 类型不支持 SameAsCurrentSegment,降级为 Start
|
||||||
|
else if (this.m_currentContainer is { ContainerType: ContainerType.Blend })
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"[MusicChannelPlayer] SyncPoint.SameAsCurrentSegment 不支持 Blend 类型 Container({this.m_currentContainer.Id}),降级为 Start");
|
||||||
|
syncState.Mode = SyncPoint.Start;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AudioSource oldSource = this.m_fader.CurrentHandle.GetFirstLeafSource();
|
||||||
|
if (oldSource && oldSource.clip)
|
||||||
|
{
|
||||||
|
syncState.BaseTimeSamples = oldSource.timeSamples;
|
||||||
|
syncState.BaseDspTime = AudioSettings.dspTime;
|
||||||
|
syncState.SampleRate = oldSource.clip.frequency;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning("[MusicChannelPlayer] SameAsCurrentSegment: 旧 Source 不存在,降级为 Start");
|
||||||
|
syncState.Mode = SyncPoint.Start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── 1. 等待节拍对齐(由 Transition 的 AlignMode 决定)──
|
// ── 1. 等待节拍对齐(由 Transition 的 AlignMode 决定)──
|
||||||
if (transition != null && this.m_currentContainer != null)
|
if (transition != null && this.m_currentContainer != null)
|
||||||
{
|
{
|
||||||
@@ -112,22 +150,39 @@ namespace OCES.Audio
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ── 2 & 3. 淡出与淡入并行:两条分支从同一时刻起算各自的 Offset,互不等待 ──
|
// ── 2 & 3. 淡出与淡入并行:两条分支从同一时刻起算各自的 Offset,互不等待 ──
|
||||||
if (newContainerId == this.m_fader.CurrentContainerId && this.m_fader.CurrentHandle != null) yield break;
|
if (newContainerId == this.m_fader.CurrentContainerId && this.m_fader.CurrentHandle != null) yield break;
|
||||||
// 如果等待期间被切回来了,就不淡变了
|
// 如果等待期间被切回来了,就不淡变了
|
||||||
|
|
||||||
ContainerPlayHandle outgoing = this.m_fader.CurrentHandle;
|
ContainerPlayHandle outgoing = this.m_fader.CurrentHandle;
|
||||||
float outVol = this.m_fader.CurrentVolume;
|
float outVol = this.m_fader.CurrentVolume;
|
||||||
|
|
||||||
this.m_currentFadeOutCoroutine = this.m_coroutineHost.StartCoroutine(
|
this.m_currentFadeOutCoroutine = this.m_coroutineHost.StartCoroutine(
|
||||||
this.m_fader.FadeOutBranch(outgoing, outVol, transition));
|
this.m_fader.FadeOutBranch(outgoing, outVol, transition, syncState));
|
||||||
|
|
||||||
this.m_currentFadeInCoroutine = this.m_coroutineHost.StartCoroutine(
|
this.m_currentFadeInCoroutine = this.m_coroutineHost.StartCoroutine(
|
||||||
this.m_fader.FadeInBranch(newContainerId, transition,
|
this.m_fader.FadeInBranch(newContainerId, transition, syncState,
|
||||||
onContainerStarted: () =>
|
onContainerStarted: () =>
|
||||||
{
|
{
|
||||||
// Music 独有:记录新 container 和播放起始时间
|
MusicContainer container = this.m_containerConfig.QueryById(newContainerId);
|
||||||
this.m_currentContainer = this.m_containerConfig.QueryById(newContainerId);
|
float bpm = container.Bpm > 0f ? container.Bpm : 120f;
|
||||||
this.m_playStartTime = AudioSettings.dspTime;
|
|
||||||
|
// SyncPoint: BeatClock 用调整后的 dspTime,对齐到音频实际播放位置
|
||||||
|
double dspTime;
|
||||||
|
if (syncState is { Mode: SyncPoint.SameAsCurrentSegment })
|
||||||
|
{
|
||||||
|
double elapsedSeconds = AudioSettings.dspTime - syncState.BaseDspTime;
|
||||||
|
int elapsedSamples = (int)(elapsedSeconds * syncState.SampleRate);
|
||||||
|
double audioTime = (double)(syncState.BaseTimeSamples + elapsedSamples) / syncState.SampleRate;
|
||||||
|
dspTime = AudioSettings.dspTime - audioTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dspTime = AudioSettings.dspTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.m_currentContainer = container;
|
||||||
|
this.m_playStartTime = dspTime;
|
||||||
|
this.m_beatClock.Restart(container, bpm, dspTime);
|
||||||
}));
|
}));
|
||||||
yield return this.m_currentFadeInCoroutine;
|
yield return this.m_currentFadeInCoroutine;
|
||||||
this.m_currentFadeInCoroutine = null;
|
this.m_currentFadeInCoroutine = null;
|
||||||
@@ -147,23 +202,28 @@ namespace OCES.Audio
|
|||||||
|
|
||||||
double secondsPerBeat = 60.0 / container.Bpm;
|
double secondsPerBeat = 60.0 / container.Bpm;
|
||||||
|
|
||||||
if (mode == AlignMode.Beat)
|
switch (mode)
|
||||||
{
|
{
|
||||||
double beatsElapsed = elapsed / secondsPerBeat;
|
case AlignMode.Beat:
|
||||||
double nextBeat = System.Math.Ceiling(beatsElapsed);
|
{
|
||||||
double waitSeconds = (nextBeat - beatsElapsed) * secondsPerBeat;
|
double beatsElapsed = elapsed / secondsPerBeat;
|
||||||
if (waitSeconds > 0.001)
|
double nextBeat = Math.Ceiling(beatsElapsed);
|
||||||
yield return new WaitForSeconds((float)waitSeconds);
|
double waitSeconds = (nextBeat - beatsElapsed) * secondsPerBeat;
|
||||||
}
|
if (waitSeconds > 0.001)
|
||||||
else if (mode == AlignMode.Bar)
|
yield return new WaitForSeconds((float)waitSeconds);
|
||||||
{
|
break;
|
||||||
int beatsPerBar = MusicContainerConfig.GetBeatsPerBar(container.TimeSig);
|
}
|
||||||
double secondsPerBar = secondsPerBeat * beatsPerBar;
|
case AlignMode.Bar:
|
||||||
double barsElapsed = elapsed / secondsPerBar;
|
{
|
||||||
double nextBar = System.Math.Ceiling(barsElapsed);
|
int beatsPerBar = MusicContainerConfig.GetBeatsPerBar(container.TimeSig);
|
||||||
double waitSeconds = (nextBar - barsElapsed) * secondsPerBar;
|
double secondsPerBar = secondsPerBeat * beatsPerBar;
|
||||||
if (waitSeconds > 0.001)
|
double barsElapsed = elapsed / secondsPerBar;
|
||||||
yield return new WaitForSeconds((float)waitSeconds);
|
double nextBar = Math.Ceiling(barsElapsed);
|
||||||
|
double waitSeconds = (nextBar - barsElapsed) * secondsPerBar;
|
||||||
|
if (waitSeconds > 0.001)
|
||||||
|
yield return new WaitForSeconds((float)waitSeconds);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -411,5 +411,20 @@ namespace OCES.Audio
|
|||||||
foreach (ContainerPlayHandle child in this.ChildHandles)
|
foreach (ContainerPlayHandle child in this.ChildHandles)
|
||||||
child.CollectActiveSources(result);
|
child.CollectActiveSources(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取第一个正在播放的 Leaf Segment 的 AudioSource。
|
||||||
|
/// 递归遍历子句柄,优先取当前层级的 ActiveSources,找不到再深入子层级。
|
||||||
|
/// </summary>
|
||||||
|
internal AudioSource GetFirstLeafSource()
|
||||||
|
{
|
||||||
|
if (this.ActiveSources.Count > 0) return this.ActiveSources[0];
|
||||||
|
foreach (ContainerPlayHandle child in this.ChildHandles)
|
||||||
|
{
|
||||||
|
AudioSource src = child.GetFirstLeafSource();
|
||||||
|
if (src) return src;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace OCES.Audio
|
|||||||
{
|
{
|
||||||
this.m_clipConcurrentCount[id] = GetClipCount(id) + 1;
|
this.m_clipConcurrentCount[id] = GetClipCount(id) + 1;
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
Debug.Log($"{id} count added to {GetClipCount(id)}");
|
//Debug.Log($"{id} count added to {GetClipCount(id)}");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace OCES
|
|||||||
{
|
{
|
||||||
public class SetStateBind : MonoBehaviour
|
public class SetStateBind : MonoBehaviour
|
||||||
{
|
{
|
||||||
public TileMaterial targetGameState;
|
public GameState targetGameState;
|
||||||
public bool enableLowpass;
|
public bool enableLowpass;
|
||||||
public Text buttonText;
|
public Text buttonText;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user