同步
This commit is contained in:
@@ -113,6 +113,21 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
{
|
||||
base.AfterInitialize();
|
||||
ApplyColorSubmodule();
|
||||
|
||||
// 一次性初始化星座(原 Update() 中的 hasInitializedSpawning 守卫逻辑)
|
||||
if (!hasInitializedSpawning)
|
||||
{
|
||||
GenerateSingleConstellation();
|
||||
hasInitializedSpawning = true;
|
||||
}
|
||||
|
||||
// 注册到调度器 Phase 7 (Effect),每帧重建连线 Mesh
|
||||
CoreServices.UpdateScheduler.Register(UpdatePhase.Effect, this);
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
CoreServices.UpdateScheduler.Unregister(UpdatePhase.Effect, this);
|
||||
}
|
||||
|
||||
public override void Refresh()
|
||||
@@ -153,74 +168,14 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
/// <summary>
|
||||
/// 调度器 Phase 7 (Effect):每帧读取粒子位置,通过 Burst Job 计算连线并重建 Mesh。
|
||||
/// 替代原先的 LateUpdate()。
|
||||
/// </summary>
|
||||
public override void ScheduledUpdate(UpdatePhase phase, float songTime)
|
||||
{
|
||||
if (!hasInitializedSpawning)
|
||||
{
|
||||
GenerateSingleConstellation();
|
||||
hasInitializedSpawning = true;
|
||||
}
|
||||
}
|
||||
if (phase != UpdatePhase.Effect) return;
|
||||
|
||||
[Button("Refresh Constellation")]
|
||||
public void GenerateSingleConstellation()
|
||||
{
|
||||
starParticleSystem.Stop();
|
||||
starParticleSystem.Clear();
|
||||
|
||||
// --- 【新增】:通过代码接管并设置 Velocity over Lifetime 模块 ---
|
||||
// 注意:如果轨道旋转不为零,则强制开启该模块
|
||||
var vol = starParticleSystem.velocityOverLifetime;
|
||||
if (orbitalVelocity != Vector3.zero)
|
||||
{
|
||||
vol.enabled = true;
|
||||
vol.orbitalX = new ParticleSystem.MinMaxCurve(orbitalVelocity.x);
|
||||
vol.orbitalY = new ParticleSystem.MinMaxCurve(orbitalVelocity.y);
|
||||
vol.orbitalZ = new ParticleSystem.MinMaxCurve(orbitalVelocity.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
vol.enabled = false;
|
||||
}
|
||||
|
||||
// --- 【新增】:通过代码接管并设置 Rotation over Lifetime 模块 ---
|
||||
var rol = starParticleSystem.rotationOverLifetime;
|
||||
if (angularVelocity != 0f)
|
||||
{
|
||||
rol.enabled = true;
|
||||
// 对于普通的 Billboard 粒子,Z 轴旋转就是屏幕空间上的二维自转
|
||||
rol.z = new ParticleSystem.MinMaxCurve(angularVelocity * Mathf.Deg2Rad); // 转换为弧度
|
||||
}
|
||||
else
|
||||
{
|
||||
rol.enabled = false;
|
||||
}
|
||||
|
||||
ParticleSystem.EmitParams emitParams = new ParticleSystem.EmitParams();
|
||||
|
||||
for (int i = 0; i < maxParticles; i++)
|
||||
{
|
||||
float x = Random.Range(-spreadSize.x * 0.5f, spreadSize.x * 0.5f);
|
||||
float y = Random.Range(-spreadSize.y * 0.5f, spreadSize.y * 0.5f);
|
||||
float z = Random.Range(-spreadSize.z * 0.5f, spreadSize.z * 0.5f);
|
||||
emitParams.position = new Vector3(x, y, z);
|
||||
|
||||
// startColor 使用 colorSubmodule 的当前 BaseColor(单色)
|
||||
emitParams.startColor = colorSubmodule != null
|
||||
? (Color32)colorSubmodule.currentBaseColor
|
||||
: new Color32(0, 255, 255, 255);
|
||||
|
||||
// 为了让自身旋转可见,可以在生成时赋予一个随机的初始旋转角度
|
||||
emitParams.rotation3D = new Vector3(0, 0, Random.Range(0f, 360f));
|
||||
|
||||
starParticleSystem.Emit(emitParams, 1);
|
||||
}
|
||||
|
||||
starParticleSystem.Play();
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if (starParticleSystem == null || lineMeshFilter == null) return;
|
||||
|
||||
int aliveCount = starParticleSystem.GetParticles(particles);
|
||||
@@ -287,6 +242,63 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
connectionCounts.Dispose();
|
||||
adjacencyMatrix.Dispose();
|
||||
}
|
||||
|
||||
[Button("Refresh Constellation")]
|
||||
public void GenerateSingleConstellation()
|
||||
{
|
||||
starParticleSystem.Stop();
|
||||
starParticleSystem.Clear();
|
||||
|
||||
// --- 【新增】:通过代码接管并设置 Velocity over Lifetime 模块 ---
|
||||
// 注意:如果轨道旋转不为零,则强制开启该模块
|
||||
var vol = starParticleSystem.velocityOverLifetime;
|
||||
if (orbitalVelocity != Vector3.zero)
|
||||
{
|
||||
vol.enabled = true;
|
||||
vol.orbitalX = new ParticleSystem.MinMaxCurve(orbitalVelocity.x);
|
||||
vol.orbitalY = new ParticleSystem.MinMaxCurve(orbitalVelocity.y);
|
||||
vol.orbitalZ = new ParticleSystem.MinMaxCurve(orbitalVelocity.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
vol.enabled = false;
|
||||
}
|
||||
|
||||
// --- 【新增】:通过代码接管并设置 Rotation over Lifetime 模块 ---
|
||||
var rol = starParticleSystem.rotationOverLifetime;
|
||||
if (angularVelocity != 0f)
|
||||
{
|
||||
rol.enabled = true;
|
||||
// 对于普通的 Billboard 粒子,Z 轴旋转就是屏幕空间上的二维自转
|
||||
rol.z = new ParticleSystem.MinMaxCurve(angularVelocity * Mathf.Deg2Rad); // 转换为弧度
|
||||
}
|
||||
else
|
||||
{
|
||||
rol.enabled = false;
|
||||
}
|
||||
|
||||
ParticleSystem.EmitParams emitParams = new ParticleSystem.EmitParams();
|
||||
|
||||
for (int i = 0; i < maxParticles; i++)
|
||||
{
|
||||
float x = Random.Range(-spreadSize.x * 0.5f, spreadSize.x * 0.5f);
|
||||
float y = Random.Range(-spreadSize.y * 0.5f, spreadSize.y * 0.5f);
|
||||
float z = Random.Range(-spreadSize.z * 0.5f, spreadSize.z * 0.5f);
|
||||
emitParams.position = new Vector3(x, y, z);
|
||||
|
||||
// startColor 使用 colorSubmodule 的当前 BaseColor(单色)
|
||||
emitParams.startColor = colorSubmodule != null
|
||||
? (Color32)colorSubmodule.currentBaseColor
|
||||
: new Color32(0, 255, 255, 255);
|
||||
|
||||
// 为了让自身旋转可见,可以在生成时赋予一个随机的初始旋转角度
|
||||
emitParams.rotation3D = new Vector3(0, 0, Random.Range(0f, 360f));
|
||||
|
||||
starParticleSystem.Emit(emitParams, 1);
|
||||
}
|
||||
|
||||
starParticleSystem.Play();
|
||||
}
|
||||
}
|
||||
|
||||
[BurstCompile(CompileSynchronously = true)]
|
||||
|
||||
@@ -7,7 +7,6 @@ using Ichni.RhythmGame.Beatmap;
|
||||
using Ichni.RhythmGame.ThemeBundles.Basic.Beatmap;
|
||||
using Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap;
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
|
||||
namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
{
|
||||
@@ -77,6 +76,17 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
return dtmTrail;
|
||||
}
|
||||
|
||||
public override void AfterInitialize()
|
||||
{
|
||||
base.AfterInitialize();
|
||||
CoreServices.UpdateScheduler.Register(UpdatePhase.Effect, this);
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
CoreServices.UpdateScheduler.Unregister(UpdatePhase.Effect, this);
|
||||
}
|
||||
|
||||
public override void SetDefaultSubmodules()
|
||||
{
|
||||
base.SetDefaultSubmodules();
|
||||
@@ -230,9 +240,14 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
#endregion
|
||||
|
||||
#region [事件动画逻辑] Event Animation Logic
|
||||
private void Update()
|
||||
/// <summary>
|
||||
/// 调度器 Phase 7 (Effect):更新 FlexibleBool/Float 动画,驱动 Head 显隐和 TrailRenderer 参数。
|
||||
/// 替代原先的 Update()。
|
||||
/// </summary>
|
||||
public override void ScheduledUpdate(UpdatePhase phase, float songTime)
|
||||
{
|
||||
float songTime = EditorManager.instance.songInformation.songTime;
|
||||
if (phase != UpdatePhase.Effect) return;
|
||||
|
||||
enableTimes.UpdateFlexibleBool(songTime);
|
||||
if (enableTimes.value && !isHeadEnabled)
|
||||
{
|
||||
@@ -246,24 +261,10 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
}
|
||||
|
||||
visibleTimeLength.UpdateFlexibleFloat(songTime);
|
||||
if (visibleTimeLength.animations.Count > 0 && EditorManager.instance.musicPlayer.isPlaying && trailRenderer.time != visibleTimeLength.value)//为的是接口里头那个用来set的
|
||||
if (visibleTimeLength.animations.Count > 0 && EditorManager.instance.musicPlayer.isPlaying && trailRenderer.time != visibleTimeLength.value)
|
||||
{
|
||||
// Debug.Log(trailRenderer == null);
|
||||
|
||||
trailRenderer.time = visibleTimeLength.value;
|
||||
}
|
||||
|
||||
if (isHeadEnabled && headRotateSpeed.animations.Count > 0)
|
||||
{
|
||||
/*headRotateSpeed.UpdateFlexibleFloat(songTime);
|
||||
var rotationBySpeedModule = headCircle.GetComponent<ParticleSystem>().rotationOverLifetime;
|
||||
rotationBySpeedModule.z = headRotateSpeed.value;*/
|
||||
}
|
||||
|
||||
if (Keyboard.current.tKey.wasPressedThisFrame)
|
||||
{
|
||||
// TriggerInteraction();
|
||||
}
|
||||
}
|
||||
|
||||
private Sequence enableHeadSequence;
|
||||
|
||||
@@ -55,8 +55,10 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
this.hold.trackPositioner.autoUpdate = false;
|
||||
|
||||
headPoint.spline = hold.track.trackPathSubmodule.path;
|
||||
headPoint.autoUpdate = false; // 由调度器 Phase 6 通过 RebuildImmediate 手动刷新
|
||||
meshGenerator.spline = hold.track.trackPathSubmodule.path;
|
||||
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);
|
||||
@@ -161,9 +163,19 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
|
||||
endPercent = trackTimeSubmoduleMovable.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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user