This commit is contained in:
SoulliesOfficial
2026-03-31 07:51:40 -04:00
parent e7d717aad5
commit 25b6da25ae
2054 changed files with 6065 additions and 32945 deletions

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap
{
@@ -8,29 +9,38 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap
public class DTMGlobalFog_BM : EnvironmentObject_BM
{
public float fogIntensity = 1f;
public float fogColorStartR = 0.5f, fogColorStartG = 0.75f, fogColorStartB = 1.0f, fogColorStartA = 1.0f;
public float fogColorEndR = 0.75f, fogColorEndG = 1.0f, fogColorEndB = 1.25f, fogColorEndA = 1.0f;
// 新字段(新存档使用)
public Color fogColorStart = new Color(0.5f, 0.75f, 1f, 1f);
public Color fogColorEnd = new Color(0.75f, 1f, 1.25f, 1f);
public float fogColorStartIntensity = 0f;
public float fogColorEndIntensity = 0f;
// 旧字段(保留以兼容旧存档 JSON 反序列化)
public float fogColorStartR = -1f, fogColorStartG = -1f, fogColorStartB = -1f, fogColorStartA = -1f;
public float fogColorEndR = -1f, fogColorEndG = -1f, fogColorEndB = -1f, fogColorEndA = -1f;
public float fogColorDuo = 0f;
public float skyboxFogIntensity = 1f;
public float skyboxFogHeight = 1f;
public float skyboxFogFalloff = 1f;
public float skyboxFogFalloff = 8f;
public float skyboxFogOffset = 0f;
public float skyboxFogBottom = 0f;
public float skyboxFogFill = 0f;
public DTMGlobalFog_BM()
{
}
public float skyboxFogFill = 1f;
public override void ExecuteBM()
{
// 向后兼容:如果旧版 float 字段有有效值(>=0则从旧字段构建 Color覆盖新字段默认值
if (fogColorStartR >= 0f)
fogColorStart = new Color(fogColorStartR, fogColorStartG, fogColorStartB, fogColorStartA);
if (fogColorEndR >= 0f)
fogColorEnd = new Color(fogColorEndR, fogColorEndG, fogColorEndB, fogColorEndA);
matchedElement = DTMGlobalFog.GenerateElement(elementName, elementGuid, tags, false,
themeBundleName, objectName, GetElement(attachedElementGuid), isStatic,
fogIntensity,
fogColorStartR, fogColorStartG, fogColorStartB, fogColorStartA,
fogColorEndR, fogColorEndG, fogColorEndB, fogColorEndA,
fogColorStart, fogColorEnd,
fogColorStartIntensity, fogColorEndIntensity,
fogColorDuo,
skyboxFogIntensity, skyboxFogHeight,
skyboxFogFalloff, skyboxFogOffset,

View File

@@ -22,9 +22,37 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap
public float outerBorderColorA = 1f;
public float outerBorderWidth = 0.02f;
public float fadeFar = 100f;
public float fadeNear = 20f;
public DTMRandomGridFloor_BM()
{
}
public DTMRandomGridFloor_BM(string elementName, Guid elementGuid, List<string> tags, GameElement_BM attachedElement,
string themeBundleName, string objectName, bool isStatic,
float patternSizeX, float patternSizeY, float gridDensity,
float timeAngle, float stepA, float stepB,
bool enableOuterBorder, Color outerColor, float outerBorderWidth,
float fadeFar = 100f, float fadeNear = 20f)
: base(elementName, elementGuid, tags, attachedElement, themeBundleName, objectName, isStatic)
{
this.patternSizeX = patternSizeX;
this.patternSizeY = patternSizeY;
this.gridDensity = gridDensity;
this.timeAngle = timeAngle;
this.stepA = stepA;
this.stepB = stepB;
this.enableOuterBorder = enableOuterBorder;
this.outerBorderColorR = outerColor.r;
this.outerBorderColorG = outerColor.g;
this.outerBorderColorB = outerColor.b;
this.outerBorderColorA = outerColor.a;
this.outerBorderWidth = outerBorderWidth;
this.fadeFar = fadeFar;
this.fadeNear = fadeNear;
}
public override void ExecuteBM()
@@ -35,7 +63,8 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap
themeBundleName, objectName, GetElement(attachedElementGuid), isStatic,
patternSizeX, patternSizeY, gridDensity,
timeAngle, stepA, stepB,
enableOuterBorder, outerColor, outerBorderWidth);
enableOuterBorder, outerColor, outerBorderWidth,
fadeFar, fadeNear);
}
}
}

View File

@@ -24,11 +24,6 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap
public float fadeNear = 20f;
public float tubeRadius = 10f;
public DTMRandomGridTube_BM()
{
}
public override void ExecuteBM()
{
matchedElement = DTMRandomGridTube.GenerateElement(elementName, elementGuid, tags, false,

View File

@@ -38,11 +38,6 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap
public float fogPower = 0.5f;
public float fogContrast = 40f;
public DTMStarrySkybox_BM()
{
}
public override void ExecuteBM()
{
matchedElement = DTMStarrySkybox.GenerateElement(

View File

@@ -1,28 +1,26 @@
using System;
using System.Collections.Generic;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap
{
public partial class DTMTrail_BM : EnvironmentObject_BM
public partial class DTMTrail_BM : EnvironmentObject_BM
{
public FlexibleFloat_BM visibleTimeLength;
public FlexibleBool_BM enableTimes;
public float enableProcessTime = 0.5f;
public float headSize = 1f;
public FlexibleFloat_BM headRotateSpeed;
public AnimationCurve widthCurve;
public Gradient trailAlphaGradient;
public override void ExecuteBM()
{
public FlexibleFloat_BM visibleTimeLength;
public FlexibleBool_BM enableTimes;
public float enableProcessTime = 0.5f;
public float headSize = 1f;
public FlexibleFloat_BM headRotateSpeed;
public DTMTrail_BM()
{
}
public override void ExecuteBM()
{
matchedElement = DTMTrail.GenerateElement(elementName, elementGuid, tags, false,
themeBundleName, objectName, GetElement(attachedElementGuid), isStatic, visibleTimeLength?.ConvertToGameType(),
enableTimes.ConvertToGameType(), headRotateSpeed?.ConvertToGameType(), enableProcessTime, headSize);
}
matchedElement = DTMTrail.GenerateElement(elementName, elementGuid, tags, false,
themeBundleName, objectName, GetElement(attachedElementGuid), isStatic, visibleTimeLength?.ConvertToGameType(),
enableTimes?.ConvertToGameType(), headRotateSpeed?.ConvertToGameType(), enableProcessTime, headSize,
widthCurve, trailAlphaGradient);
}
}
}

View File

@@ -7,14 +7,22 @@ using FogMode = AtmosphericHeightFog.FogMode;
namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
{
public class DTMGlobalFog : EnvironmentObject
public partial class DTMGlobalFog : EnvironmentObject
{
#region [] Exposed Fields
public HeightFogGlobal heightFogGlobal;
public float fogIntensity;
public float fogColorStartR = 0.5f, fogColorStartG = 0.75f, fogColorStartB = 1f, fogColorStartA = 1f;
public float fogColorEndR = 0.75f, fogColorEndG = 1f, fogColorEndB = 1.25f, fogColorEndA = 1f;
// 新字段:使用 Color + 发光强度HDR
public Color fogColorStart = new Color(0.5f, 0.75f, 1f, 1f);
public Color fogColorEnd = new Color(0.75f, 1f, 1.25f, 1f);
public float fogColorStartIntensity = 0f;
public float fogColorEndIntensity = 0f;
// 旧字段:保留以兼容旧版存档(由 BM 层 fallback 时使用)
[System.NonSerialized] public float fogColorStartR = 0.5f, fogColorStartG = 0.75f, fogColorStartB = 1f, fogColorStartA = 1f;
[System.NonSerialized] public float fogColorEndR = 0.75f, fogColorEndG = 1f, fogColorEndB = 1.25f, fogColorEndA = 1f;
public float fogColorDuo;
public float skyboxFogIntensity;
@@ -30,8 +38,8 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
bool isFirstGenerated, string themeBundleName, string objectName, GameElement parentElement,
bool isStatic,
float fogIntensity,
float fogColorStartR, float fogColorStartG, float fogColorStartB, float fogColorStartA,
float fogColorEndR, float fogColorEndG, float fogColorEndB, float fogColorEndA,
Color fogColorStart, Color fogColorEnd,
float fogColorStartIntensity, float fogColorEndIntensity,
float fogColorDuo,
float skyboxFogIntensity, float skyboxFogHeight,
float skyboxFogFalloff, float skyboxFogOffset,
@@ -41,19 +49,11 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
isFirstGenerated, themeBundleName, objectName, parentElement, isStatic).GetComponent<DTMGlobalFog>();
globalFog.fogIntensity = fogIntensity;
globalFog.fogColorStartR = fogColorStartR;
globalFog.fogColorStartG = fogColorStartG;
globalFog.fogColorStartB = fogColorStartB;
globalFog.fogColorStartA = fogColorStartA;
globalFog.fogColorEndR = fogColorEndR;
globalFog.fogColorEndG = fogColorEndG;
globalFog.fogColorEndB = fogColorEndB;
globalFog.fogColorEndA = fogColorEndA;
globalFog.fogColorStart = fogColorStart;
globalFog.fogColorEnd = fogColorEnd;
globalFog.fogColorStartIntensity = fogColorStartIntensity;
globalFog.fogColorEndIntensity = fogColorEndIntensity;
globalFog.fogColorDuo = fogColorDuo;
globalFog.skyboxFogIntensity = skyboxFogIntensity;
globalFog.skyboxFogHeight = skyboxFogHeight;
globalFog.skyboxFogFalloff = skyboxFogFalloff;
@@ -64,15 +64,15 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
return globalFog;
}
public override void FirstSetUpObject(bool isFirstGenerated)
public override void AfterInitialize()
{
if (heightFogGlobal == null)
{
heightFogGlobal = GetComponentInChildren<HeightFogGlobal>();
heightFogGlobal = GetComponent<HeightFogGlobal>();
heightFogGlobal.mainCamera = GameManager.Instance.cameraManager.gameCamera.cam;
heightFogGlobal.mainDirectional = GameObject.Find("Directional Light")?.GetComponent<Light>();
}
// Ensure fog mode is set to script settings so it accepts our overrides
if (heightFogGlobal != null)
{
heightFogGlobal.fogMode = FogMode.UseScriptSettings;
@@ -88,15 +88,17 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
#endregion
#region [] Core Effect Logic
private void UpdateFogProperties()
public void UpdateFogProperties()
{
if (heightFogGlobal == null) return;
heightFogGlobal.fogIntensity = fogIntensity;
heightFogGlobal.fogColorStart = new Color(fogColorStartR, fogColorStartG, fogColorStartB, fogColorStartA);
heightFogGlobal.fogColorEnd = new Color(fogColorEndR, fogColorEndG, fogColorEndB, fogColorEndA);
// 使用 HDR 颜色base color * 2^intensity
heightFogGlobal.fogColorStart = fogColorStart * Mathf.Pow(2, fogColorStartIntensity);
heightFogGlobal.fogColorEnd = fogColorEnd * Mathf.Pow(2, fogColorEndIntensity);
heightFogGlobal.fogColorDuo = fogColorDuo;
heightFogGlobal.skyboxFogIntensity = skyboxFogIntensity;
heightFogGlobal.skyboxFogHeight = skyboxFogHeight;
heightFogGlobal.skyboxFogFalloff = skyboxFogFalloff;

View File

@@ -5,7 +5,7 @@ using UnityEngine;
namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
{
public class DTMRandomGridFloor : EnvironmentObject
public partial class DTMRandomGridFloor : EnvironmentObject
{
#region [] Exposed Fields
public float patternSizeX;
@@ -19,6 +19,9 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public Color outerBorderColor;
public float outerBorderWidth;
public float fadeFar = 100f;
public float fadeNear = 20f;
public Renderer meshRenderer;
#endregion
@@ -30,7 +33,9 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
float timeAngle, float stepA, float stepB,
bool enableOuterBorder,
Color outerBorderColor,
float outerBorderWidth)
float outerBorderWidth,
float fadeFar = 100f,
float fadeNear = 20f)
{
DTMRandomGridFloor randomGridFloor = EnvironmentObject.GenerateElement(elementName, id, tags,
isFirstGenerated, themeBundleName, objectName, parentElement, isStatic).GetComponent<DTMRandomGridFloor>();
@@ -45,6 +50,8 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
randomGridFloor.enableOuterBorder = enableOuterBorder;
randomGridFloor.outerBorderColor = outerBorderColor;
randomGridFloor.outerBorderWidth = outerBorderWidth;
randomGridFloor.fadeFar = fadeFar;
randomGridFloor.fadeNear = fadeNear;
return randomGridFloor;
}
@@ -54,7 +61,12 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
if (meshRenderer == null)
meshRenderer = GetComponentInChildren<Renderer>();
meshRenderer.InitializeShader(); // 实例化材质 / Instantiate material
meshRenderer.InitializeShader(); // 实例化材质
}
public override void AfterInitialize()
{
base.AfterInitialize();
UpdateMaterialProperties();
}
@@ -91,7 +103,9 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
mat.SetColor("_OuterBorderColor", outerBorderColor);
mat.SetFloat("_OuterBorderWidth", outerBorderWidth);
// Base Color and Alpha Sync (Unity Color -> HDR)
mat.SetFloat("_FadeFar", fadeFar);
mat.SetFloat("_FadeNear", fadeNear);
mat.SetColor("_Color0", colorSubmodule.currentBaseColor);
}
}
@@ -99,7 +113,6 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public override void Refresh()
{
base.Refresh();
// Sync environment color changes
if (meshRenderer != null)
{
meshRenderer.material.SetColor("_Color0", colorSubmodule.currentBaseColor);

View File

@@ -5,7 +5,7 @@ using UnityEngine;
namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
{
public class DTMRandomGridTube : EnvironmentObject
public partial class DTMRandomGridTube : EnvironmentObject
{
#region [] Exposed Fields
public float patternSizeX = 2.0f;
@@ -66,10 +66,15 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
if (meshRenderer != null)
{
meshRenderer.InitializeShader(); // 实例化材质 / Instantiate material
UpdateMaterialProperties();
}
}
public override void AfterInitialize()
{
base.AfterInitialize();
UpdateMaterialProperties();
}
public override void OnDirtyRefresh(Dictionary<string, bool> flags)
{
UpdateMaterialProperties();
@@ -98,18 +103,17 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
mat.SetFloat("_FadeNear", fadeNear);
mat.SetFloat("_TubeRadius", tubeRadius);
// Sync color mapped from unified generic submodule
mat.SetColor("_Color0", colorSubmodule.currentBaseColor);
// 圆管使用发光颜色HDR
mat.SetColor("_Color0", colorSubmodule.GetCurrentEmissionColor());
}
}
public override void Refresh()
{
base.Refresh();
// Sync environment color changes
if (meshRenderer != null && meshRenderer.material != null)
{
meshRenderer.material.SetColor("_Color0", colorSubmodule.currentBaseColor);
meshRenderer.material.SetColor("_Color0", colorSubmodule.GetCurrentEmissionColor());
}
}
#endregion

View File

@@ -9,7 +9,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
/// 游星空天空盒环境物体,加载 DTM_Skybox_Starry 材质并将其设置为场景天空盒,
/// 同时暴露天空盒 Shader 的全量参数以接受 PropertyAnimation 动态控制。
/// </summary>
public class DTMStarrySkybox : EnvironmentObject
public partial class DTMStarrySkybox : EnvironmentObject
{
#region [] Exposed Fields
@@ -28,7 +28,6 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public float starSize = 75f;
public Color starColor = Color.white;
public bool preventStarsInFrontOfSun = true;
// 通过 ThemeBundle 字符串名称查找贴图
public string starMapTextureName = "None";
// --- Sun Mask ---
@@ -135,9 +134,9 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
// -- Sky --
skyboxMaterial.SetColor("_SkyColor", skyColor);
skyboxMaterial.SetColor("_Horizon", horizon);
skyboxMaterial.SetColor("_HorizonColor", horizon);
skyboxMaterial.SetFloat("_HorizonStrength", horizonStrength);
skyboxMaterial.SetFloat("_HorizonSkyHeight", horizonSkyHeight);
skyboxMaterial.SetFloat("_HorizonHeight", horizonSkyHeight);
// -- Stars --
skyboxMaterial.SetFloat("_UseStarMap", useStarMap ? 1f : 0f);
@@ -179,6 +178,17 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
DynamicGI.UpdateEnvironment();
}
public override void Refresh()
{
base.Refresh();
UpdateSkyboxProperties();
if (skyboxMaterial != null)
{
RenderSettings.skybox = skyboxMaterial;
}
}
public override void OnDelete()
{
base.OnDelete();

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
@@ -8,40 +10,57 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public partial class DTMTrail : EnvironmentObject, IHaveTrail, IHaveInteraction
{
#region [] Exposed Fields
public GameObject headPoint, headCircle;
public GameObject headPoint, headCircle, sparks;
public GameObject trailBody;
public List<Renderer> renderers = new List<Renderer>();
public bool isHeadEnabled;
public List<Renderer> renderers;
public ParticleSystem headCircleParticle;
public TrailRenderer trailRenderer { get; set; }
public AnimationCurve widthCurve; // trailBody 的宽度曲线,默认为常数 0.5
public Gradient trailAlphaGradient; // trailBody 的渐变,只控制 AlphaColor 必须为白色
public FlexibleFloat visibleTimeLength;
public FlexibleBool enableTimes;
public float enableProcessTime = 0.5f;
public float headSize = 1f;
public FlexibleFloat headRotateSpeed;
public override bool haveEmission => true;
public FlexibleFloat visibleTimeLength; // trailBody 的可见时间长度
public FlexibleBool enableTimes; // headPoint 和 headCircle 的启用/禁用时间
public float enableProcessTime = 0.5f; // head 启用/禁用过程时间
public float headSize = 1f; // head 目标大小
public FlexibleFloat headRotateSpeed; // headCircle 的旋转速度
// 默认值辅助返回常量宽度曲线0.5 常数)
private static AnimationCurve DefaultWidthCurve()
{
return AnimationCurve.Constant(0f, 1f, 0.5f);
}
// 默认值辅助:返回全不透明白色渐变
private static Gradient DefaultTrailGradient()
{
var g = new Gradient();
g.SetKeys(
new GradientColorKey[] { new GradientColorKey(Color.white, 0f), new GradientColorKey(Color.white, 1f) },
new GradientAlphaKey[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) }
);
return g;
}
#endregion
#region [] Lifecycle & Factory
public static DTMTrail GenerateElement(string elementName, Guid id, List<string> tags,
bool isFirstGenerated, string themeBundleName, string objectName, GameElement parentElement,
bool isStatic, FlexibleFloat visibleTimeLength, FlexibleBool enableTimes, FlexibleFloat headRotateSpeed, float enableProcessTime,
float headSize)
bool isFirstGenerated, string themeBundleName, string objectName, GameElement parentElement,
bool isStatic, FlexibleFloat visibleTimeLength, FlexibleBool enableTimes, FlexibleFloat headRotateSpeed, float enableProcessTime,
float headSize, AnimationCurve widthCurve = null, Gradient trailGradient = null)
{
DTMTrail dtmTrail = EnvironmentObject.GenerateElement(elementName, id, tags,
isFirstGenerated, themeBundleName, objectName, parentElement, isStatic).GetComponent<DTMTrail>();
dtmTrail.isHeadEnabled = false;
dtmTrail.visibleTimeLength = visibleTimeLength;
dtmTrail.enableTimes = enableTimes;
dtmTrail.headRotateSpeed = headRotateSpeed;
dtmTrail.enableProcessTime = enableProcessTime;
dtmTrail.headSize = headSize;
dtmTrail.widthCurve = widthCurve ?? DefaultWidthCurve();
dtmTrail.trailAlphaGradient = trailGradient ?? DefaultTrailGradient();
return dtmTrail;
}
@@ -55,16 +74,32 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public override void FirstSetUpObject(bool isFirstGenerated)
{
//SetUpTweeners();
trailRenderer = trailBody.GetComponent<TrailRenderer>();
var rotationBySpeedModule = headCircleParticle.rotationBySpeed;
rotationBySpeedModule.z = 0;
// 初始化默认值(兼容旧存档中未序列化字段)
if (widthCurve == null || widthCurve.keys.Length == 0) widthCurve = DefaultWidthCurve();
if (trailAlphaGradient == null) trailAlphaGradient = DefaultTrailGradient();
trailRenderer.widthCurve = widthCurve;
// 收集所有使用 BlendUnlit 的 Renderer
renderers.Clear();
CollectBlendUnlitRenderer(headPoint);
CollectBlendUnlitRenderer(headCircle);
CollectBlendUnlitRenderer(sparks);
CollectBlendUnlitRenderer(trailBody);
// 实例化所有材质(避免修改共享材质)
foreach (var rend in renderers)
{
rend.InitializeShader();
}
sparks.gameObject.SetActive(false);
headPoint.transform.localScale = Vector3.zero;
headCircle.transform.localScale = Vector3.zero;
trailRenderer.emitting = false;
renderers.ForEach(rend => rend.InitializeShader());
}
public override void WhenStart()
{
base.WhenStart();
@@ -75,15 +110,107 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
headCircle.gameObject.SetActive(false);
}
/// <summary>
/// 递归收集 gameObject 及其子物体中所有使用 BlendUnlit (Soullies/BlendUnlit) 的 Renderer
/// </summary>
private void CollectBlendUnlitRenderer(GameObject root)
{
if (root == null) return;
foreach (var rend in root.GetComponentsInChildren<Renderer>(true))
{
if (rend.sharedMaterial != null && rend.sharedMaterial.shader.name.Contains("BlendUnlit"))
{
renderers.Add(rend);
}
}
}
public override void Refresh()
{
base.Refresh();
renderers.ForEach(rend =>
Color baseColor = colorSubmodule.currentBaseColor;
// --- 粒子系统颜色 ---
// headPoint 和 sparksS 降至 baseColor 的四分之一
Color.RGBToHSV(baseColor, out float h, out float s, out float v);
Color desaturatedColor = Color.HSVToRGB(h, s * 0.25f, v);
desaturatedColor.a = baseColor.a;
if (headPoint != null)
{
rend.material.SetColor("_BaseColor", colorSubmodule.currentBaseColor);
rend.material.SetColor("_EmissionColor", colorSubmodule.GetCurrentEmissionColor());
});
var ps = headPoint.GetComponent<ParticleSystem>();
if (ps != null)
{
var main = ps.main;
main.startColor = desaturatedColor;
}
}
if (sparks != null)
{
var ps = sparks.GetComponent<ParticleSystem>();
if (ps != null)
{
var main = ps.main;
main.startColor = desaturatedColor;
}
}
// headCircle与 baseColor 完全一致
if (headCircle != null)
{
var ps = headCircle.GetComponent<ParticleSystem>();
if (ps != null)
{
var main = ps.main;
main.startColor = baseColor;
}
}
// --- trailRenderer 颜色 ---
// 以 baseColor 为固定颜色trailAlphaGradient 只取其 Alpha 通道
if (trailRenderer != null)
{
Gradient combinedGradient = BuildTrailColorGradient(baseColor, trailAlphaGradient);
trailRenderer.colorGradient = combinedGradient;
}
// --- BlendUnlit Renderer 材质属性BaseColor + EmissionColor---
Color emissionColor = colorSubmodule.GetCurrentEmissionColor();
foreach (var rend in renderers)
{
if (rend == null) continue;
if (colorSubmodule.emissionEnabled)
{
rend.material.EnableKeyword("_EMISSION_ON");
rend.material.SetColor("_EmissionColor", emissionColor);
}
else
{
rend.material.DisableKeyword("_EMISSION_ON");
}
}
}
/// <summary>
/// 用 baseColor 作为固定颜色,从 alphaSource 中提取 Alpha 曲线,合成最终的 TrailRenderer Gradient
/// </summary>
private static Gradient BuildTrailColorGradient(Color baseColor, Gradient alphaSource)
{
GradientAlphaKey[] alphaKeys = alphaSource != null
? alphaSource.alphaKeys
: new GradientAlphaKey[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) };
GradientColorKey[] colorKeys = new GradientColorKey[]
{
new GradientColorKey(baseColor, 0f),
new GradientColorKey(baseColor, 1f)
};
var g = new Gradient();
g.SetKeys(colorKeys, alphaKeys);
return g;
}
#endregion
@@ -92,31 +219,30 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
{
float songTime = CoreServices.TimeProvider.SongTime;
enableTimes.UpdateFlexibleBool(songTime);
if(enableTimes.value && !isHeadEnabled)
if (enableTimes.value && !isHeadEnabled)
{
//EnableHead();
EnableHead();
isHeadEnabled = true;
}
else if(!enableTimes.value && isHeadEnabled)
else if (!enableTimes.value && isHeadEnabled)
{
//DisableHead();
DisableHead();
isHeadEnabled = false;
}
visibleTimeLength.UpdateFlexibleFloat(songTime);
if (visibleTimeLength.animations.Count > 0)
if (visibleTimeLength.animations.Count > 0 && trailRenderer.time != visibleTimeLength.value)
{
trailRenderer.time = visibleTimeLength.value;
}
if (isHeadEnabled && headRotateSpeed.animations.Count > 0)
{
headRotateSpeed.UpdateFlexibleFloat(songTime);
var rotationBySpeedModule = headCircleParticle.rotationBySpeed;
rotationBySpeedModule.z = headRotateSpeed.value;
// headRotateSpeed 控制逻辑留待后续实现
}
}
private Sequence enableHeadSequence;
private Sequence disableHeadSequence;
private Sequence headBounceSequence;
@@ -125,7 +251,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
{
enableHeadSequence?.Kill(true);
disableHeadSequence?.Kill(true);
enableHeadSequence = DOTween.Sequence();
enableHeadSequence.Append(headPoint.transform.DOScale(headSize, enableProcessTime).SetEase(Ease.OutQuad));
enableHeadSequence.Join(headCircle.transform.DOScale(headSize, enableProcessTime).SetEase(Ease.OutQuad));
@@ -134,6 +260,7 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
headPoint.gameObject.SetActive(true);
headCircle.gameObject.SetActive(true);
});
enableHeadSequence.OnComplete(() => sparks.SetActive(true));
enableHeadSequence.Play();
}
@@ -141,8 +268,9 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
{
enableHeadSequence?.Kill(true);
disableHeadSequence?.Kill(true);
disableHeadSequence = DOTween.Sequence();
disableHeadSequence.OnStart(() => sparks.SetActive(false));
disableHeadSequence.Append(headPoint.transform.DOScale(0, enableProcessTime).SetEase(Ease.OutQuad));
disableHeadSequence.Join(headCircle.transform.DOScale(0, enableProcessTime).SetEase(Ease.OutQuad));
disableHeadSequence.OnComplete(() =>
@@ -155,14 +283,14 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public void TriggerInteraction()
{
headBounceSequence?.Kill(true);
headBounceSequence = DOTween.Sequence();
headBounceSequence.Append(headPoint.transform.DOBlendableScaleBy(Vector3.one * 0.2f, 0.2f).SetEase(Ease.OutBack));
headBounceSequence.Join(headCircle.transform.DOBlendableScaleBy(Vector3.one * 0.2f, 0.2f).SetEase(Ease.OutBack));
headBounceSequence.Append(headPoint.transform.DOBlendableScaleBy(Vector3.one * -0.2f, 0.2f).SetEase(Ease.OutBack));
headBounceSequence.Join(headCircle.transform.DOBlendableScaleBy(Vector3.one * -0.2f, 0.2f).SetEase(Ease.OutBack));
headBounceSequence.SetAutoKill(false);
headBounceSequence.Play();
}
#endregion
}
}