添加PositionSync正在考虑本体对策

Signed-off-by: TRADER_FOER <lhf190@outlook.com>
This commit is contained in:
2026-07-16 10:55:30 +08:00
parent c16c2480ff
commit be0290372f
142 changed files with 6157247 additions and 123045 deletions

View File

@@ -40,7 +40,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
float e = AnimationCurveEvaluator.Evaluate(AnimationCurveType.OutQuad, effectProgressPercent);
if (noteVisual is DTMNoteVisualHold noteVisualHold)
{
noteVisualHold.meshGenerator.size = e;
noteVisualHold.meshGenerator.size = e * noteVisualHold.holdThickness;
}
else
{
@@ -52,7 +52,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
{
if (noteVisual is DTMNoteVisualHold noteVisualHold)
{
noteVisualHold.meshGenerator.size = 1;
noteVisualHold.ApplyHoldThicknessFromScale();
}
else
{

View File

@@ -32,15 +32,19 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
#region [] Effect Logic
private void UpdateHold()
{
hold.trackPositioner.SetPercent(startPercent);
noteVisualHold.meshGenerator.SetClipRange(startPercent, endPercent);
noteVisualHold.headPoint.SetPercent(startPercent);
noteVisualHold.tailPoint.SetPercent(endPercent);
noteVisualHold.SetHoldPercentRange(startPercent, endPercent, false);
}
private void UpdateTargetPercents(float songTime)
{
targetStartPercent = noteVisualHold.GetTrackPercent(hold.exactJudgeTime, songTime);
targetEndPercent = noteVisualHold.GetTrackPercent(hold.holdEndTime, songTime);
}
public override void UpdateEffect(float triggerTime)
{
EffectState state = CheckEffectState(triggerTime);
float songTime = EditorManager.instance.songInformation.songTime;
float songTime = CoreServices.TimeProvider?.SongTime ?? 0f;
triggerTime -= generateTime;
if (state == EffectState.Before)
@@ -88,9 +92,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public override void PreExecute()
{
TrackTimeSubmoduleMovable trackTimeSubmoduleMovable = hold.track.trackTimeSubmodule as TrackTimeSubmoduleMovable;
targetStartPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.exactJudgeTime);
targetEndPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.holdEndTime);
UpdateTargetPercents(CoreServices.TimeProvider?.SongTime ?? 0f);
startPercent = targetStartPercent;
endPercent = targetStartPercent;
noteVisual.noteMain.SetActive(true);
@@ -99,6 +101,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public override void Execute()
{
UpdateTargetPercents(CoreServices.TimeProvider?.SongTime ?? 0f);
float e = AnimationCurveEvaluator.Evaluate(AnimationCurveType.OutQuad, effectProgressPercent);
startPercent = targetStartPercent;
endPercent = Mathf.Lerp(targetStartPercent, targetEndPercent, e);
@@ -107,6 +110,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public override void Adjust()
{
UpdateTargetPercents(CoreServices.TimeProvider?.SongTime ?? 0f);
startPercent = targetStartPercent;
endPercent = targetEndPercent;
UpdateHold();
@@ -114,4 +118,4 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
#endregion
}
}
}

View File

@@ -60,12 +60,12 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
tailPoint.spline = hold.track.trackPathSubmodule.path;
tailPoint.autoUpdate = false; // 由调度器 Phase 6 通过 RebuildImmediate 手动刷新
TrackTimeSubmoduleMovable trackTimeSubmoduleMovable = hold.track.trackTimeSubmodule as TrackTimeSubmoduleMovable;
float startPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.exactJudgeTime);
float endPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.holdEndTime);
float startPercent = GetTrackPercent(hold.exactJudgeTime);
float endPercent = GetTrackPercent(hold.holdEndTime);
hold.trackPositioner.SetPercent(startPercent);
meshGenerator.SetClipRange(startPercent, endPercent);
ApplyHoldThicknessFromScale();
headPoint.SetPercent(startPercent);
tailPoint.SetPercent(endPercent);
@@ -123,6 +123,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
meshGenerator.offset = posOffset;
headPoint.motion.offset = posOffset;
tailPoint.motion.offset = posOffset;
ApplyHoldThicknessFromScale();
}
#endregion
}
@@ -140,6 +141,77 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
#region [] Positional Updates
private float startPercent, endPercent;
public float holdThickness => Mathf.Max(0f, transformSubmodule?.currentScale.x ?? 1f);
public void ApplyHoldThicknessFromScale()
{
meshGenerator.size = holdThickness;
}
public void UpdateTransform(bool refreshAll = true)
{
if (transformSubmodule == null) return;
bool willRefresh = false;
if (transformSubmodule.scaleDirtyMark)
{
transformSubmodule.currentScale = transformSubmodule.originalScale + transformSubmodule.scaleOffset;
transform.localScale = Vector3.one;
ApplyHoldThicknessFromScale();
transformSubmodule.scaleDirtyMark = false;
willRefresh = true;
transformSubmodule.scaleOffset = Vector3.zero;
}
if (!transformSubmodule.eulerAnglesOffsetLock && transformSubmodule.eulerAnglesDirtyMark)
{
transformSubmodule.currentEulerAngles = transformSubmodule.originalEulerAngles + transformSubmodule.eulerAnglesOffset;
transform.localEulerAngles = transformSubmodule.currentEulerAngles;
transformSubmodule.eulerAnglesDirtyMark = false;
willRefresh = true;
transformSubmodule.eulerAnglesOffset = Vector3.zero;
}
if (transformSubmodule.positionDirtyMark)
{
transformSubmodule.currentPosition = transformSubmodule.originalPosition + transformSubmodule.positionOffset;
transform.localPosition = transformSubmodule.currentPosition;
transformSubmodule.positionDirtyMark = false;
willRefresh = true;
transformSubmodule.positionOffset = Vector3.zero;
}
if (willRefresh && refreshAll)
{
Refresh();
}
}
public float GetTrackPercent(float targetTime)
{
return GetTrackPercent(targetTime, CoreServices.TimeProvider?.SongTime ?? 0f);
}
public float GetTrackPercent(float targetTime, float songTime)
{
if (hold.track.trackTimeSubmodule is TrackTimeSubmoduleMovable trackTimeSubmoduleMovable)
{
return trackTimeSubmoduleMovable.GetTrackPercent(targetTime);
}
if (hold.track.trackTimeSubmodule is TrackTimeSubmoduleStatic trackTimeSubmoduleStatic)
{
float startMove = targetTime - trackTimeSubmoduleStatic.trackTotalTime;
float percent = AnimationCurveEvaluator.Evaluate(trackTimeSubmoduleStatic.animationCurveType,
(songTime - startMove) / trackTimeSubmoduleStatic.trackTotalTime);
return 1 - Mathf.Clamp01(percent);
}
throw new InvalidOperationException("Hold NoteVisual needs a TrackTimeSubmodule.");
}
public void UpdateHoldInMovableTrack()
{
if (effectSubmodule.effectCollection["Generate"].Any(e => e.nowEffectState == EffectBase.EffectState.Middle))
@@ -147,41 +219,74 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
return;
}
TrackTimeSubmoduleMovable trackTimeSubmoduleMovable = hold.track.trackTimeSubmodule as TrackTimeSubmoduleMovable;
startPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.exactJudgeTime);
endPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.holdEndTime);
startPercent = GetTrackPercent(hold.exactJudgeTime);
endPercent = GetTrackPercent(hold.holdEndTime);
if (hold.isHolding)
{
startPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.exactJudgeTime + hold.holdingTime);
endPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.holdEndTime);
startPercent = GetTrackPercent(hold.exactJudgeTime + hold.holdingTime);
endPercent = GetTrackPercent(hold.holdEndTime);
}
else if (hold.isFinalJudged)
{
startPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.holdEndTime);
endPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.holdEndTime);
startPercent = GetTrackPercent(hold.holdEndTime);
endPercent = GetTrackPercent(hold.holdEndTime);
}
// 确保所有 SplineUser 使用当前帧的最新 Spline 采样数据。
// Phase 6 在 LateUpdate 中执行SplineComputer 已在 Update 中重采样完毕。
// autoUpdate=false 的 SplinePositioner 不会自行刷新,必须手动 RebuildImmediate。
hold.trackPositioner.RebuildImmediate();
hold.trackPositioner.SetPercent(startPercent);
meshGenerator.SetClipRange(startPercent, endPercent);
meshGenerator.RebuildImmediate(); // 立即重建网格,避免与 head/tail 位置错位一帧
headPoint.RebuildImmediate();
headPoint.SetPercent(startPercent);
tailPoint.RebuildImmediate();
tailPoint.SetPercent(endPercent);
SetHoldPercentRange(startPercent, endPercent, true);
}
public void UpdateHoldInStaticTrack()
public void UpdateHoldInStaticTrack(float songTime)
{
//throw new NotImplementedException();
if (effectSubmodule.effectCollection["Generate"].Any(e => e.nowEffectState == EffectBase.EffectState.Middle))
{
return;
}
startPercent = GetTrackPercent(hold.exactJudgeTime, songTime);
endPercent = GetTrackPercent(hold.holdEndTime, songTime);
if (hold.isHolding)
{
startPercent = GetTrackPercent(hold.exactJudgeTime + hold.holdingTime, songTime);
endPercent = GetTrackPercent(hold.holdEndTime, songTime);
}
else if (hold.isFinalJudged)
{
startPercent = GetTrackPercent(hold.holdEndTime, songTime);
endPercent = GetTrackPercent(hold.holdEndTime, songTime);
}
SetHoldPercentRange(startPercent, endPercent, true);
}
public void SetHoldPercentRange(float startPercent, float endPercent, bool rebuildImmediately)
{
if (rebuildImmediately)
{
// autoUpdate=false 的 SplineUser 不会自行刷新,必须手动 RebuildImmediate。
hold.trackPositioner.RebuildImmediate();
}
hold.trackPositioner.SetPercent(startPercent);
meshGenerator.SetClipRange(startPercent, endPercent);
ApplyHoldThicknessFromScale();
if (rebuildImmediately)
{
meshGenerator.RebuildImmediate();
headPoint.RebuildImmediate();
}
headPoint.SetPercent(startPercent);
if (rebuildImmediately)
{
tailPoint.RebuildImmediate();
}
tailPoint.SetPercent(endPercent);
}
public void SetTransformObserver()
@@ -217,4 +322,4 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
}
#endregion
}
}
}