修改Hold使其适应

Signed-off-by: TRADER_FOER <lhf190@outlook.com>
This commit is contained in:
2026-07-17 21:09:17 +08:00
parent 80220367ae
commit df453844e4
2 changed files with 95 additions and 20 deletions

View File

@@ -288,7 +288,7 @@ namespace Dreamteck.Splines
float anglePercent = (float)lon / sides;
int index = bodyVertexCount + lon + (lat-1) * (sides + 1);
Quaternion rot = Quaternion.AngleAxis(_revolve * anglePercent + rotation + 180f, -Vector3.forward) * Quaternion.AngleAxis(latAngle, Vector3.up);
_tsMesh.vertices[index] = center + lookRot * rot * -Vector3.right * (size * 0.5f * evalResult.size);
_tsMesh.vertices[index] = center + lookRot * rot * -Vector3.right * (size * 0.5f * resultSize);
_tsMesh.colors[index] = vertexColor;
_tsMesh.normals[index] = (_tsMesh.vertices[index] - center).normalized;
float baseV = startV + capLengthPercent * latitudePercent;
@@ -348,7 +348,7 @@ namespace Dreamteck.Splines
float anglePercent = (float)lon / sides;
int index = bodyVertexCount + capVertexCount + lon + (lat - 1) * (sides + 1);
Quaternion rot = Quaternion.AngleAxis(_revolve * anglePercent + rotation + 180f, Vector3.forward) * Quaternion.AngleAxis(latAngle, -Vector3.up);
_tsMesh.vertices[index] = center + lookRot * rot * Vector3.right * size * 0.5f * evalResult.size;
_tsMesh.vertices[index] = center + lookRot * rot * Vector3.right * size * 0.5f * resultSize;
_tsMesh.normals[index] = (_tsMesh.vertices[index] - center).normalized;
_tsMesh.colors[index] = vertexColor;
float baseV = startV + capLengthPercent * latitudePercent;

View File

@@ -59,15 +59,20 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
meshGenerator.spline = hold.track.trackPathSubmodule.path;
tailPoint.spline = hold.track.trackPathSubmodule.path;
tailPoint.autoUpdate = false; // 由调度器 Phase 6 通过 RebuildImmediate 手动刷新
ConfigurePathNodeScaleIsolation();
float startPercent = GetTrackPercent(hold.exactJudgeTime);
float endPercent = GetTrackPercent(hold.holdEndTime);
startPercent = GetTrackPercent(hold.exactJudgeTime);
endPercent = GetTrackPercent(hold.holdEndTime);
ApplyHoldPositionOffset(GetCurrentPositionOffset());
hold.trackPositioner.SetPercent(startPercent);
ApplyPositionerWorldOffset(hold.trackPositioner, startPercent);
meshGenerator.SetClipRange(startPercent, endPercent);
ApplyHoldThicknessFromScale();
headPoint.SetPercent(startPercent);
ApplyPositionerWorldOffset(headPoint, startPercent);
tailPoint.SetPercent(endPercent);
ApplyPositionerWorldOffset(tailPoint, endPercent);
if (isFirstGenerated)
{
@@ -94,15 +99,15 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
{
materialPropertyBlock.SetFloat("_MainAlpha", 1f);
rend.SetPropertyBlock(materialPropertyBlock);
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();
}
foreach (EffectBase effect in effectSubmodule.effectCollection["Holding"])
foreach (EffectBase effect in GetEffects("Holding"))
{
effect.Recover();
}
@@ -110,7 +115,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public override void Refresh()
{
base.Refresh();
foreach (EffectBase effect in effectSubmodule.effectCollection["Generate"])
foreach (EffectBase effect in GetEffects("Generate"))
{
if (effect.nowEffectState == EffectBase.EffectState.Middle)
{
@@ -118,11 +123,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
}
}
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;
ApplyHoldPositionOffset(GetCurrentPositionOffset());
ApplyHoldThicknessFromScale();
}
#endregion
@@ -140,14 +141,84 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
#region [] Positional Updates
private float startPercent, endPercent;
private Vector2 positionOffset;
private SplineSample offsetSample = new();
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);
}
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 void UpdateTransform(bool refreshAll = true)
{
if (transformSubmodule == null) return;
@@ -177,6 +248,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
{
transformSubmodule.currentPosition = transformSubmodule.originalPosition + transformSubmodule.positionOffset;
transform.localPosition = transformSubmodule.currentPosition;
ApplyHoldPositionOffset(GetCurrentPositionOffset());
transformSubmodule.positionDirtyMark = false;
willRefresh = true;
transformSubmodule.positionOffset = Vector3.zero;
@@ -214,7 +286,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public void UpdateHoldInMovableTrack()
{
if (effectSubmodule.effectCollection["Generate"].Any(e => e.nowEffectState == EffectBase.EffectState.Middle))
if (IsGenerateEffectMiddle())
{
return;
}
@@ -239,7 +311,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public void UpdateHoldInStaticTrack(float songTime)
{
if (effectSubmodule.effectCollection["Generate"].Any(e => e.nowEffectState == EffectBase.EffectState.Middle))
if (IsGenerateEffectMiddle())
{
return;
}
@@ -263,13 +335,18 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public void SetHoldPercentRange(float startPercent, float endPercent, bool rebuildImmediately)
{
this.startPercent = startPercent;
this.endPercent = endPercent;
if (rebuildImmediately)
{
// autoUpdate=false 的 SplineUser 不会自行刷新,必须手动 RebuildImmediate。
hold.trackPositioner.RebuildImmediate();
}
ApplyHoldPositionOffset(positionOffset);
hold.trackPositioner.SetPercent(startPercent);
ApplyPositionerWorldOffset(hold.trackPositioner, startPercent);
meshGenerator.SetClipRange(startPercent, endPercent);
ApplyHoldThicknessFromScale();
@@ -280,6 +357,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
}
headPoint.SetPercent(startPercent);
ApplyPositionerWorldOffset(headPoint, startPercent);
if (rebuildImmediately)
{
@@ -287,6 +365,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
}
tailPoint.SetPercent(endPercent);
ApplyPositionerWorldOffset(tailPoint, endPercent);
}
public void SetTransformObserver()
@@ -303,11 +382,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
if (transformSubmodule.positionDirtyMark)
{
transformSubmodule.currentPosition = transformSubmodule.originalPosition + transformSubmodule.positionOffset;
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;
ApplyHoldPositionOffset(GetCurrentPositionOffset());
transformSubmodule.positionDirtyMark = false;
willRefresh = true;
transformSubmodule.positionOffset = Vector3.zero;