@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user