修改本体,添加CrossTrackPoint兼容层,兼容StaticTrack Hold,为难度选项扩增全屏可选,添加和调整某些谱面
Signed-off-by: TRADER_FOER <lhf190@outlook.com>
This commit is contained in:
@@ -18,13 +18,13 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
#region [效果核心实现] Core Effect Implementation
|
||||
public sealed override void Recover()
|
||||
{
|
||||
noteVisual.noteMain.SetActive(false);
|
||||
SetVisualShown(false);
|
||||
noteVisual.noteMain.transform.localScale = Vector3.zero;
|
||||
}
|
||||
|
||||
public override void PreExecute()
|
||||
{
|
||||
noteVisual.noteMain.SetActive(true);
|
||||
SetVisualShown(true);
|
||||
}
|
||||
|
||||
public override void Execute()
|
||||
@@ -35,9 +35,20 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
|
||||
public override void Adjust()
|
||||
{
|
||||
SetVisualShown(true);
|
||||
noteVisual.noteMain.transform.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
private void SetVisualShown(bool isShown)
|
||||
{
|
||||
if (noteVisual is DTMNoteVisualHold holdVisual)
|
||||
{
|
||||
holdVisual.SetHoldVisualShown(isShown);
|
||||
return;
|
||||
}
|
||||
|
||||
noteVisual.noteMain.SetActive(isShown);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -26,30 +26,32 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
#region [效果核心逻辑] Core Effect Logic
|
||||
private void UpdateHold()
|
||||
{
|
||||
hold.trackPositioner.SetPercent(startPercent);
|
||||
noteVisualHold.meshGenerator.SetClipRange(startPercent, endPercent);
|
||||
//noteVisualHold.extrude.Range = new Vector2(startPercent, endPercent);
|
||||
noteVisualHold.headPoint.SetPercent(startPercent);
|
||||
noteVisualHold.tailPoint.SetPercent(endPercent);
|
||||
noteVisualHold.SetHoldPercentRange(startPercent, endPercent, true);
|
||||
}
|
||||
|
||||
private void UpdateTargetPercents(float songTime)
|
||||
{
|
||||
targetStartPercent = noteVisualHold.GetTrackPercent(hold.exactJudgeTime, songTime);
|
||||
targetEndPercent = noteVisualHold.GetTrackPercent(hold.holdEndTime, songTime);
|
||||
}
|
||||
|
||||
public override void Recover()
|
||||
{
|
||||
noteVisualHold.noteMain.SetActive(false);
|
||||
noteVisualHold.SetHoldVisualShown(false);
|
||||
}
|
||||
|
||||
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);
|
||||
noteVisualHold.SetHoldVisualShown(true);
|
||||
UpdateHold();
|
||||
}
|
||||
|
||||
public override void Execute()
|
||||
{
|
||||
UpdateTargetPercents(CoreServices.TimeProvider?.SongTime ?? 0f);
|
||||
float e = AnimationCurveEvaluator.Evaluate(AnimationCurveType.OutQuad, effectProgressPercent);
|
||||
startPercent = targetStartPercent;
|
||||
endPercent = Mathf.Lerp(targetStartPercent, targetEndPercent, e);
|
||||
@@ -58,11 +60,12 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
|
||||
public override void Adjust()
|
||||
{
|
||||
UpdateTargetPercents(CoreServices.TimeProvider?.SongTime ?? 0f);
|
||||
startPercent = targetStartPercent;
|
||||
endPercent = targetEndPercent;
|
||||
noteVisualHold.SetHoldVisualShown(true);
|
||||
UpdateHold();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -45,8 +45,16 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
this.hold.trackPositioner.autoUpdate = false;
|
||||
|
||||
headPoint.spline = hold.track.trackPathSubmodule.path;
|
||||
headPoint.autoUpdate = false;
|
||||
meshGenerator.spline = hold.track.trackPathSubmodule.path;
|
||||
tailPoint.spline = hold.track.trackPathSubmodule.path;
|
||||
tailPoint.autoUpdate = false;
|
||||
ConfigurePathNodeScaleIsolation();
|
||||
|
||||
startPercent = GetTrackPercent(hold.exactJudgeTime);
|
||||
endPercent = GetTrackPercent(hold.holdEndTime);
|
||||
ApplyHoldPositionOffset(GetCurrentPositionOffset());
|
||||
SetHoldPercentRange(startPercent, endPercent, true);
|
||||
|
||||
//meshGenerator.enabled = false;
|
||||
//extrude.Container = hold.track.trackPathSubmodule.container;
|
||||
@@ -69,11 +77,11 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
{
|
||||
rend.materials[0].SetFloat("_MainAlpha", 1f);
|
||||
rend.materials[1].SetFloat("_MainAlpha", 1f);
|
||||
note.track.trackPathSubmodule.path.RebuildImmediate();
|
||||
note?.track?.trackPathSubmodule?.path?.RebuildImmediate();
|
||||
}
|
||||
}
|
||||
|
||||
foreach (EffectBase effect in effectSubmodule.effectCollection["Generate"])
|
||||
foreach (EffectBase effect in GetEffects("Generate"))
|
||||
{
|
||||
effect.Recover();
|
||||
}
|
||||
@@ -85,41 +93,279 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
{
|
||||
#region [长条动态更新] Hold Updates
|
||||
private float startPercent, endPercent;
|
||||
private Vector2 positionOffset;
|
||||
private SplineSample offsetSample = new();
|
||||
private Transform hitPointTransform;
|
||||
private Vector3 hitPointBaseLocalScale = Vector3.one;
|
||||
private bool isHoldVisualShown = true;
|
||||
|
||||
public float holdThickness => Mathf.Max(0f, transformSubmodule?.currentScale.x ?? 1f);
|
||||
|
||||
public void ApplyHoldThicknessFromScale()
|
||||
{
|
||||
if (meshGenerator == null) return;
|
||||
meshGenerator.size = holdThickness;
|
||||
}
|
||||
|
||||
private void ConfigurePathNodeScaleIsolation()
|
||||
{
|
||||
if (meshGenerator != null) meshGenerator.useSplineSize = false;
|
||||
DisableSplineSizeScale(hold?.trackPositioner);
|
||||
DisableSplineSizeScale(headPoint);
|
||||
DisableSplineSizeScale(tailPoint);
|
||||
ApplyHitPointScaleIsolation();
|
||||
}
|
||||
|
||||
private void DisableSplineSizeScale(SplinePositioner positioner)
|
||||
{
|
||||
if (positioner == null) return;
|
||||
positioner.motion.applyScaleX = false;
|
||||
positioner.motion.applyScaleY = false;
|
||||
positioner.motion.applyScaleZ = false;
|
||||
}
|
||||
|
||||
private Vector2 GetCurrentPositionOffset()
|
||||
{
|
||||
if (transformSubmodule == null) return Vector2.zero;
|
||||
return new Vector2(transformSubmodule.currentPosition.x, transformSubmodule.currentPosition.y);
|
||||
}
|
||||
|
||||
private List<EffectBase> GetEffects(string key)
|
||||
{
|
||||
if (effectSubmodule?.effectCollection != null &&
|
||||
effectSubmodule.effectCollection.TryGetValue(key, out List<EffectBase> effects))
|
||||
{
|
||||
return effects;
|
||||
}
|
||||
|
||||
return new List<EffectBase>();
|
||||
}
|
||||
|
||||
private bool IsGenerateEffectMiddle()
|
||||
{
|
||||
return GetEffects("Generate").Any(e => e.nowEffectState == EffectBase.EffectState.Middle);
|
||||
}
|
||||
|
||||
private void ApplyHoldPositionOffset(Vector2 offset)
|
||||
{
|
||||
positionOffset = offset;
|
||||
if (meshGenerator != null) meshGenerator.offset = offset;
|
||||
ClearSplineSizeScaledOffset(hold?.trackPositioner);
|
||||
ClearSplineSizeScaledOffset(headPoint);
|
||||
ClearSplineSizeScaledOffset(tailPoint);
|
||||
}
|
||||
|
||||
private void ClearSplineSizeScaledOffset(SplinePositioner positioner)
|
||||
{
|
||||
if (positioner == null) return;
|
||||
positioner.motion.offset = Vector2.zero;
|
||||
}
|
||||
|
||||
private void ApplyPositionerWorldOffset(SplinePositioner positioner, float percent)
|
||||
{
|
||||
if (positioner == null || positioner.targetObject == null || positionOffset == Vector2.zero) return;
|
||||
if (positioner.sampleCount == 0) return;
|
||||
|
||||
positioner.Evaluate(percent, ref offsetSample);
|
||||
positioner.targetObject.transform.position +=
|
||||
offsetSample.right * positionOffset.x +
|
||||
offsetSample.up * positionOffset.y;
|
||||
}
|
||||
|
||||
public override void SetHighlight()
|
||||
{
|
||||
SetHitPointVisible(isHoldVisualShown);
|
||||
}
|
||||
|
||||
public void SetHoldVisualShown(bool isShown)
|
||||
{
|
||||
isHoldVisualShown = isShown;
|
||||
if (noteMain != null) noteMain.SetActive(isShown);
|
||||
SetHitPointVisible(isShown);
|
||||
}
|
||||
|
||||
private void SetHitPointVisible(bool isVisualShown)
|
||||
{
|
||||
if (extraPartList == null || extraPartList.Count == 0 || extraPartList[0] == null) return;
|
||||
extraPartList[0].SetActive(isVisualShown && isHighlighted);
|
||||
ApplyHitPointScaleIsolation();
|
||||
}
|
||||
|
||||
private void CacheHitPointTransform()
|
||||
{
|
||||
if (hitPointTransform != null) return;
|
||||
if (extraPartList == null || extraPartList.Count == 0 || extraPartList[0] == null) return;
|
||||
|
||||
hitPointTransform = extraPartList[0].transform;
|
||||
hitPointBaseLocalScale = hitPointTransform.localScale;
|
||||
}
|
||||
|
||||
private void ApplyHitPointScaleIsolation()
|
||||
{
|
||||
CacheHitPointTransform();
|
||||
if (hitPointTransform == null) return;
|
||||
|
||||
Vector3 targetWorldScale = hitPointBaseLocalScale * holdThickness;
|
||||
Transform parent = hitPointTransform.parent;
|
||||
if (parent == null)
|
||||
{
|
||||
hitPointTransform.localScale = targetWorldScale;
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 parentScale = parent.lossyScale;
|
||||
hitPointTransform.localScale = new Vector3(
|
||||
DivideScaleAxis(targetWorldScale.x, parentScale.x),
|
||||
DivideScaleAxis(targetWorldScale.y, parentScale.y),
|
||||
DivideScaleAxis(targetWorldScale.z, parentScale.z)
|
||||
);
|
||||
}
|
||||
|
||||
private float DivideScaleAxis(float targetScale, float parentScale)
|
||||
{
|
||||
return Mathf.Approximately(parentScale, 0f) ? targetScale : targetScale / parentScale;
|
||||
}
|
||||
|
||||
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))
|
||||
if (IsGenerateEffectMiddle())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
TrackTimeSubmoduleMovable trackTimeSubmoduleMovable = hold.track.trackTimeSubmodule as TrackTimeSubmoduleMovable;
|
||||
|
||||
startPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.exactJudgeTime + hold.holdingTime);
|
||||
endPercent = trackTimeSubmoduleMovable.GetTrackPercent(hold.holdEndTime);
|
||||
startPercent = GetTrackPercent(hold.exactJudgeTime);
|
||||
endPercent = GetTrackPercent(hold.holdEndTime);
|
||||
|
||||
hold.trackPositioner.SetPercent(startPercent);
|
||||
meshGenerator.SetClipRange(startPercent, endPercent);
|
||||
//Debug.Log("Range: " + startPercent + " - " + endPercent);
|
||||
//extrude.Range = new Vector2(startPercent, endPercent);
|
||||
headPoint.SetPercent(startPercent);
|
||||
tailPoint.SetPercent(endPercent);
|
||||
if (hold.isHolding)
|
||||
{
|
||||
startPercent = GetTrackPercent(hold.exactJudgeTime + hold.holdingTime);
|
||||
endPercent = GetTrackPercent(hold.holdEndTime);
|
||||
}
|
||||
else if (hold.isFinalJudged)
|
||||
{
|
||||
startPercent = GetTrackPercent(hold.holdEndTime);
|
||||
endPercent = GetTrackPercent(hold.holdEndTime);
|
||||
}
|
||||
|
||||
SetHoldPercentRange(startPercent, endPercent, true);
|
||||
}
|
||||
|
||||
public void UpdateHoldInStaticTrack()
|
||||
public void UpdateHoldInStaticTrack(float songTime)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
if (IsGenerateEffectMiddle())
|
||||
{
|
||||
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)
|
||||
{
|
||||
this.startPercent = startPercent;
|
||||
this.endPercent = endPercent;
|
||||
|
||||
if (rebuildImmediately)
|
||||
{
|
||||
hold.trackPositioner.RebuildImmediate();
|
||||
}
|
||||
|
||||
ApplyHoldPositionOffset(positionOffset);
|
||||
hold.trackPositioner.SetPercent(startPercent);
|
||||
ApplyPositionerWorldOffset(hold.trackPositioner, startPercent);
|
||||
meshGenerator.SetClipRange(startPercent, endPercent);
|
||||
ApplyHoldThicknessFromScale();
|
||||
|
||||
if (rebuildImmediately)
|
||||
{
|
||||
meshGenerator.RebuildImmediate();
|
||||
headPoint.RebuildImmediate();
|
||||
}
|
||||
|
||||
headPoint.SetPercent(startPercent);
|
||||
ApplyPositionerWorldOffset(headPoint, startPercent);
|
||||
ApplyHitPointScaleIsolation();
|
||||
|
||||
if (rebuildImmediately)
|
||||
{
|
||||
tailPoint.RebuildImmediate();
|
||||
}
|
||||
|
||||
tailPoint.SetPercent(endPercent);
|
||||
ApplyPositionerWorldOffset(tailPoint, endPercent);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region [变化监听与重置] Transform & Refresh Overrides
|
||||
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();
|
||||
ApplyHitPointScaleIsolation();
|
||||
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;
|
||||
ApplyHoldPositionOffset(GetCurrentPositionOffset());
|
||||
transformSubmodule.positionDirtyMark = false;
|
||||
willRefresh = true;
|
||||
transformSubmodule.positionOffset = Vector3.zero;
|
||||
@@ -137,13 +383,19 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
public override void Refresh()
|
||||
{
|
||||
base.Refresh();
|
||||
|
||||
Vector2 posOffset = new Vector2(transformSubmodule.currentPosition.x, transformSubmodule.currentPosition.y);
|
||||
hold.trackPositioner.motion.offset = posOffset;
|
||||
meshGenerator.offset = posOffset;
|
||||
headPoint.motion.offset = posOffset;
|
||||
tailPoint.motion.offset = posOffset;
|
||||
|
||||
foreach (EffectBase effect in GetEffects("Generate"))
|
||||
{
|
||||
if (effect.nowEffectState == EffectBase.EffectState.Middle)
|
||||
{
|
||||
effect.Recover();
|
||||
}
|
||||
}
|
||||
|
||||
ApplyHoldPositionOffset(GetCurrentPositionOffset());
|
||||
ApplyHoldThicknessFromScale();
|
||||
ApplyHitPointScaleIsolation();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user