修复bug+清理

This commit is contained in:
SoulliesOfficial
2026-05-23 09:43:16 -04:00
parent 51878f15ae
commit 3995beeb29
417 changed files with 11682 additions and 10915791 deletions

View File

@@ -128,37 +128,75 @@ namespace Ichni.RhythmGame
ApplyTimeShiftToElement(this, affectNotes, offset);
}
/// <summary>
/// 递归偏移元素及其所有子元素的时间参数。
/// 处理顺序:先偏移当前元素,再递归处理子元素。
/// </summary>
private void ApplyTimeShiftToElement(GameElement element, bool affectNotes, float offset)
{
if (element is AnimationBase anim)
try
{
anim.ApplyTimeOffset(offset);
anim.Refresh();
}
else if (element is NoteBase note && affectNotes)
{
note.exactJudgeTime += offset;
if (note is Hold hold)
if (element == null) return;
switch (element)
{
hold.holdEndTime += offset;
case AnimationBase anim:
anim.ApplyTimeOffset(offset);
anim.Refresh();
break;
case NoteBase note when affectNotes:
note.exactJudgeTime += offset;
if (note is Hold hold)
{
hold.holdEndTime += offset;
}
note.UpdateNoteInTrack(EditorManager.instance.songInformation.songTime);
note.AddinNoteManager(false);
note.Refresh();
break;
case Track track:
// 偏移 Track 自身的 timeDurationSubmodule
if (track.timeDurationSubmodule != null && track.timeDurationSubmodule.isOverridingDuration)
{
track.timeDurationSubmodule.startTime += offset;
track.timeDurationSubmodule.endTime += offset;
}
// 偏移 TrackTimeSubmodule 中的轨道起止时间
if (track.trackTimeSubmodule is TrackTimeSubmoduleMovable movable)
{
movable.trackStartTime += offset;
movable.trackEndTime += offset;
movable.Refresh();
}
track.Refresh();
break;
case DTMTrail dtmTrail:
dtmTrail.ApplyTimeOffset(offset);
dtmTrail.Refresh();
break;
// 泛型兜底:处理 TemporaryObject、ParticleEmitter、GameCamera、TimeEffectsCollection 等
// 所有实现了 IHaveTimeDurationSubmodule 但不属于上述类型的元素
case IHaveTimeDurationSubmodule hasDuration:
hasDuration.ApplyTimeOffset(offset);
break;
}
note.UpdateNoteInTrack(EditorManager.instance.songInformation.songTime);
note.AddinNoteManager(false);
note.Refresh();
}
else if (element is DTMTrail dtmTrail)
catch (System.Exception ex)
{
dtmTrail.ApplyTimeOffset(offset);
dtmTrail.Refresh();
Debug.LogError($"[TimeShift] 处理元素 '{element?.elementName}' ({element?.GetType().Name}) 时出错: {ex.Message}\n{ex.StackTrace}");
}
// GameElement 本身具有层级结构,所有的 GameElement 都可能会携带子物体(如 EnvironmentObjectTrack 等等)
// 使用快照副本进行安全迭代,防止子操作意外修改集合
if (element.childElementList != null && element.childElementList.Count > 0)
{
foreach (var child in element.childElementList)
List<GameElement> snapshot = new List<GameElement>(element.childElementList);
for (int i = 0; i < snapshot.Count; i++)
{
ApplyTimeShiftToElement(child, affectNotes, offset);
ApplyTimeShiftToElement(snapshot[i], affectNotes, offset);
}
}
}

View File

@@ -52,9 +52,17 @@ namespace Ichni.RhythmGame
colorSubmodule = new ColorSubmodule(this);
}
/// <summary>
/// 施加时间偏移。直接操作 timeDurationSubmodule
/// 不通过 interface cast 委托,避免 C# default interface method 虚分派导致无限递归。
/// </summary>
public virtual void ApplyTimeOffset(float offset)
{
(this as IHaveTimeDurationSubmodule).ApplyTimeOffset(offset);
if (timeDurationSubmodule != null)
{
timeDurationSubmodule.startTime += offset;
timeDurationSubmodule.endTime += offset;
}
}
#endregion