修复bug+清理
This commit is contained in:
@@ -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 都可能会携带子物体(如 EnvironmentObject,Track 等等)
|
||||
// 使用快照副本进行安全迭代,防止子操作意外修改集合
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user