爆修
This commit is contained in:
@@ -97,7 +97,7 @@ namespace Ichni.Editor
|
||||
Ichni.Editor.Commands.CommandManager.ExecuteCommand(new Ichni.Editor.Commands.ChangeValueCommand(connectedBaseElement, colorParameterName, emissionColor));
|
||||
|
||||
colorPreview.color = emissionColor;
|
||||
//connectedBaseElement.Refresh();
|
||||
connectedBaseElement.Refresh();
|
||||
}
|
||||
|
||||
public void SliderChange(float value)
|
||||
|
||||
@@ -197,10 +197,12 @@ namespace Ichni.Editor
|
||||
return highest;
|
||||
}
|
||||
|
||||
private static float SmartInferHeight(Type t)
|
||||
private static float SmartInferHeight(FieldDef fd)
|
||||
{
|
||||
if (t == typeof(Color)) return 240f;
|
||||
// 多数基础组件默认为 100 单位高度
|
||||
// EmissionColorPicker 有 Toggle/RGB滑块/Intensity输入框,高度明显大于 BaseColorPicker
|
||||
if (fd.Attr is DynamicUIEmissionColorAttribute) return 320f;
|
||||
if (fd.ValueType == typeof(Color)) return 280f;
|
||||
// 多数基础组件默认为 100
|
||||
return 100f;
|
||||
}
|
||||
|
||||
@@ -209,7 +211,7 @@ namespace Ichni.Editor
|
||||
float highest = 100f;
|
||||
foreach (var f in fields)
|
||||
{
|
||||
float height = f.Attr.Height > 0 ? f.Attr.Height : SmartInferHeight(f.ValueType);
|
||||
float height = f.Attr.Height > 0 ? f.Attr.Height : SmartInferHeight(f);
|
||||
if (height > highest) highest = height;
|
||||
}
|
||||
return highest;
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame.Beatmap
|
||||
{
|
||||
public class SpeedLinesEffect_BM : EffectBase_BM
|
||||
{
|
||||
// --- 时间控制 ---
|
||||
public float duration;
|
||||
public AnimationCurve intensityCurve;
|
||||
|
||||
// --- Lines 设置 ---
|
||||
public Color color = new Color(1f, 1f, 1f, 0.5f);
|
||||
public float peakRemap = 0f;
|
||||
public float speedLinesTiling = 200f;
|
||||
public float speedLinesRadialScale = 0.1f;
|
||||
public float speedLinesPower = 0f;
|
||||
public float speedLinesAnimation = 3f;
|
||||
|
||||
// --- Radial Mask 设置 ---
|
||||
public float maskScale = 1f;
|
||||
public float maskHardness = 0f;
|
||||
public float maskPower = 5f;
|
||||
|
||||
public SpeedLinesEffect_BM() { }
|
||||
|
||||
public SpeedLinesEffect_BM(float duration, AnimationCurve intensityCurve,
|
||||
Color color, float peakRemap = 0f,
|
||||
float speedLinesTiling = 200f, float speedLinesRadialScale = 0.1f,
|
||||
float speedLinesPower = 0f, float speedLinesAnimation = 3f,
|
||||
float maskScale = 1f, float maskHardness = 0f, float maskPower = 5f)
|
||||
{
|
||||
this.effectTime = duration;
|
||||
this.duration = duration;
|
||||
this.intensityCurve = intensityCurve;
|
||||
this.color = color;
|
||||
this.peakRemap = peakRemap;
|
||||
this.speedLinesTiling = speedLinesTiling;
|
||||
this.speedLinesRadialScale = speedLinesRadialScale;
|
||||
this.speedLinesPower = speedLinesPower;
|
||||
this.speedLinesAnimation = speedLinesAnimation;
|
||||
this.maskScale = maskScale;
|
||||
this.maskHardness = maskHardness;
|
||||
this.maskPower = maskPower;
|
||||
}
|
||||
|
||||
public override EffectBase ConvertToGameType(GameElement attachedGameElement)
|
||||
{
|
||||
return new SpeedLinesEffect(
|
||||
duration, intensityCurve,
|
||||
color, peakRemap,
|
||||
speedLinesTiling, speedLinesRadialScale, speedLinesPower, speedLinesAnimation,
|
||||
maskScale, maskHardness, maskPower)
|
||||
{
|
||||
attachedGameElement = attachedGameElement,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d3ceadc5c586f14db585dad8293db73
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Ichni.Editor;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -146,6 +147,11 @@ namespace Ichni.RhythmGame
|
||||
note.AddinNoteManager(false);
|
||||
note.Refresh();
|
||||
}
|
||||
else if (element is DTMTrail dtmTrail)
|
||||
{
|
||||
dtmTrail.ApplyTimeOffset(offset);
|
||||
dtmTrail.Refresh();
|
||||
}
|
||||
|
||||
// GameElement 本身具有层级结构,所有的 GameElement 都可能会携带子物体(如 EnvironmentObject,Track 等等)
|
||||
if (element.childElementList != null && element.childElementList.Count > 0)
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
using Ichni.Editor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public partial class SpeedLinesEffect
|
||||
{
|
||||
#region [编辑器面板] Inspector Setup
|
||||
public override void SetUpInspector()
|
||||
{
|
||||
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
|
||||
|
||||
// --- 基础时间控制(AnimationCurve 需手动生成,不在 AutoBuild 支持范围内)---
|
||||
var container = inspector.GenerateContainer("Speed Lines");
|
||||
var timeSettings = container.GenerateSubcontainer(3);
|
||||
|
||||
inspector.GenerateInputField(this, timeSettings, "Effect Time", nameof(effectTime));
|
||||
|
||||
inspector.GenerateButton(this, timeSettings, "Intensity Curve", () =>
|
||||
{
|
||||
inspector.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve))
|
||||
.SetAsCustomCurve();
|
||||
});
|
||||
|
||||
var colorSettings = container.GenerateSubcontainer(1, 240f);
|
||||
// Color(BaseColorPicker,含 Alpha 作为透明度控制)
|
||||
inspector.GenerateBaseColorPicker(this, colorSettings, "Color", nameof(color));
|
||||
|
||||
// --- Lines 参数组 ---
|
||||
var linesSettings = container.GenerateSubcontainer(3);
|
||||
|
||||
inspector.GenerateInputField(this, linesSettings, "Peak Remap", nameof(peakRemap));
|
||||
inspector.GenerateInputField(this, linesSettings, "Tiling", nameof(speedLinesTiling));
|
||||
inspector.GenerateInputField(this, linesSettings, "Radial Scale", nameof(speedLinesRadialScale));
|
||||
inspector.GenerateInputField(this, linesSettings, "Power", nameof(speedLinesPower));
|
||||
inspector.GenerateInputField(this, linesSettings, "Animation Speed", nameof(speedLinesAnimation));
|
||||
|
||||
// --- Radial Mask 参数组 ---
|
||||
var maskSettings = container.GenerateSubcontainer(3);
|
||||
|
||||
inspector.GenerateInputField(this, maskSettings, "Mask Scale", nameof(maskScale));
|
||||
inspector.GenerateInputField(this, maskSettings, "Mask Hardness", nameof(maskHardness));
|
||||
inspector.GenerateInputField(this, maskSettings, "Mask Power", nameof(maskPower));
|
||||
|
||||
SetRemove(timeSettings);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42c333b2a607c454bbec97aeaf5ad6d8
|
||||
@@ -44,6 +44,7 @@ namespace Ichni.RhythmGame
|
||||
{ "Pixelate", () => new PixelateEffect(1, 320, 180, CustomCurvePresets.Instant()) },
|
||||
{ "LowPassFilter", () => new LowPassFilterEffect(1, 10, CustomCurvePresets.Parabolic(1, 0, 1)) },
|
||||
{ "HighPassFilter", () => new HighPassFilterEffect(1, 22000, CustomCurvePresets.Parabolic(1, 0, 1)) },
|
||||
{ "SpeedLines", () => new SpeedLinesEffect(1f, CustomCurvePresets.Parabolic(1, 0, 1), new Color(1f, 1f, 1f, 0.5f), peakRemap: 0f) },
|
||||
{ "DTM_RippleEffect", () => new DTMRippleEffect(0.65f, Color.white, 0) }
|
||||
};
|
||||
#endregion
|
||||
|
||||
@@ -134,5 +134,11 @@ namespace Ichni.RhythmGame
|
||||
public interface IHaveTimeDurationSubmodule
|
||||
{
|
||||
public TimeDurationSubmodule timeDurationSubmodule { get; set; }
|
||||
|
||||
public virtual void ApplyTimeOffset(float offset)
|
||||
{
|
||||
timeDurationSubmodule.startTime += offset;
|
||||
timeDurationSubmodule.endTime += offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,12 @@ namespace Ichni.RhythmGame
|
||||
timeDurationSubmodule = new TimeDurationSubmodule(this);
|
||||
colorSubmodule = new ColorSubmodule(this);
|
||||
}
|
||||
|
||||
public virtual void ApplyTimeOffset(float offset)
|
||||
{
|
||||
(this as IHaveTimeDurationSubmodule).ApplyTimeOffset(offset);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using DG.Tweening;
|
||||
using Ichni.Editor;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
using Ichni.Editor;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using SLSUtilities.Rendering.PostProcessing;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
/// <summary>
|
||||
/// 控制 SpeedLines 后处理效果的特效脚本。
|
||||
/// 通过 intensityCurve + peakRemap 在持续时间内驱动 speedLinesRemap(数值越低效果越强)。
|
||||
/// </summary>
|
||||
public partial class SpeedLinesEffect : EffectBase
|
||||
{
|
||||
#region [运行时缓存数据] Property Caches
|
||||
// --- 时间控制 ---
|
||||
public AnimationCurve intensityCurve; // 0→1 映射到 remap:peakRemap→1f(1f=隐去,越小越强)
|
||||
|
||||
// --- Lines 设置 ---
|
||||
public Color color; // 包含 Alpha,Alpha 越大越不透明
|
||||
public float peakRemap; // 效果最强时 speedLinesRemap 的目标值(默认 0,越低越密集)
|
||||
public float speedLinesTiling; // 线条分块数量,默认 200
|
||||
public float speedLinesRadialScale; // 放射缩放,默认 0.1
|
||||
public float speedLinesPower; // 线条锐利度,默认 0
|
||||
public float speedLinesAnimation; // 移动速度,默认 3
|
||||
|
||||
// --- Radial Mask 设置 ---
|
||||
public float maskScale; // 遮罩比例,默认 1
|
||||
public float maskHardness; // 遮罩边缘硬度,默认 0
|
||||
public float maskPower; // 遮罩幂次,默认 5
|
||||
|
||||
private SpeedLines _speedLinesVolume;
|
||||
#endregion
|
||||
|
||||
#region [生成与初始化] Generation & Initialization
|
||||
public SpeedLinesEffect(float effectTime, AnimationCurve intensityCurve,
|
||||
Color color, float peakRemap = 0f,
|
||||
float speedLinesTiling = 200f, float speedLinesRadialScale = 0.1f,
|
||||
float speedLinesPower = 0f, float speedLinesAnimation = 3f,
|
||||
float maskScale = 1f, float maskHardness = 0f, float maskPower = 5f)
|
||||
: base(effectTime)
|
||||
{
|
||||
this.intensityCurve = intensityCurve;
|
||||
this.color = color;
|
||||
this.peakRemap = peakRemap;
|
||||
this.speedLinesTiling = speedLinesTiling;
|
||||
this.speedLinesRadialScale = speedLinesRadialScale;
|
||||
this.speedLinesPower = speedLinesPower;
|
||||
this.speedLinesAnimation = speedLinesAnimation;
|
||||
this.maskScale = maskScale;
|
||||
this.maskHardness = maskHardness;
|
||||
this.maskPower = maskPower;
|
||||
}
|
||||
|
||||
public override void CopyParametersFrom(EffectBase other)
|
||||
{
|
||||
if (other is SpeedLinesEffect o)
|
||||
{
|
||||
this.intensityCurve = o.intensityCurve != null ? new AnimationCurve(o.intensityCurve.keys) : null;
|
||||
this.color = o.color;
|
||||
this.peakRemap = o.peakRemap;
|
||||
this.speedLinesTiling = o.speedLinesTiling;
|
||||
this.speedLinesRadialScale = o.speedLinesRadialScale;
|
||||
this.speedLinesPower = o.speedLinesPower;
|
||||
this.speedLinesAnimation = o.speedLinesAnimation;
|
||||
this.maskScale = o.maskScale;
|
||||
this.maskHardness = o.maskHardness;
|
||||
this.maskPower = o.maskPower;
|
||||
}
|
||||
}
|
||||
|
||||
private void PrepareHandle()
|
||||
{
|
||||
if (_speedLinesVolume == null && PostProcessingManager.GlobalVolume != null)
|
||||
{
|
||||
PostProcessingManager.GlobalVolume.profile.TryGet(out _speedLinesVolume);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region [处理与更新] Update & Processing
|
||||
public override void PreExecute()
|
||||
{
|
||||
PrepareHandle();
|
||||
if (_speedLinesVolume == null) return;
|
||||
|
||||
// 静态参数在预执行时写入一次
|
||||
_speedLinesVolume.color.value = color;
|
||||
_speedLinesVolume.speedLinesTiling.value = speedLinesTiling;
|
||||
_speedLinesVolume.speedLinesRadialScale.value = speedLinesRadialScale;
|
||||
_speedLinesVolume.speedLinesPower.value = speedLinesPower;
|
||||
_speedLinesVolume.speedLinesAnimation.value = speedLinesAnimation;
|
||||
_speedLinesVolume.maskScale.value = maskScale;
|
||||
_speedLinesVolume.maskHardness.value = maskHardness;
|
||||
_speedLinesVolume.maskPower.value = maskPower;
|
||||
}
|
||||
|
||||
public override void Execute()
|
||||
{
|
||||
if (_speedLinesVolume == null) return;
|
||||
|
||||
// intensityCurve 0→1,将 remap 从 1f(无效果)插值到 peakRemap(最强效果)
|
||||
float t = intensityCurve != null ? intensityCurve.Evaluate(effectProgressPercent) : effectProgressPercent;
|
||||
_speedLinesVolume.speedLinesRemap.value = Mathf.Lerp(1f, peakRemap, t);
|
||||
}
|
||||
|
||||
public override void Adjust() { ResetEffect(); }
|
||||
public override void Recover() { ResetEffect(); }
|
||||
public override void Disrupt() { ResetEffect(); }
|
||||
|
||||
private void ResetEffect()
|
||||
{
|
||||
if (_speedLinesVolume != null)
|
||||
_speedLinesVolume.speedLinesRemap.value = 1f; // Remap=1 时 IsActive() 返回 false
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region [保存与序列化] Serialize & BM
|
||||
public override EffectBase_BM ConvertToBM()
|
||||
{
|
||||
return new SpeedLinesEffect_BM(
|
||||
effectTime, intensityCurve,
|
||||
color, peakRemap,
|
||||
speedLinesTiling, speedLinesRadialScale, speedLinesPower, speedLinesAnimation,
|
||||
maskScale, maskHardness, maskPower);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d88500debd393041bf1b0dfdeddef23
|
||||
@@ -213,11 +213,16 @@ namespace Ichni.RhythmGame
|
||||
EffectBase effectBase = generateEffects[i];
|
||||
if (effectBase is NoteGenerateEffect ge)
|
||||
{
|
||||
// 必须先重置状态,否则当 nowEffectState 处于 After 时,
|
||||
// 下一次 UpdateEffect 的 "After && nowEffectState != After" 条件为 false 而跳过 Adjust(),
|
||||
// 导致 SetActive(false) 的 noteMain 永远无法被 Adjust() 重新激活。
|
||||
ge.nowEffectState = EffectBase.EffectState.Before;
|
||||
ge.Recover();
|
||||
beyondTime = Mathf.Max(beyondTime, ge.generateTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
effectBase.nowEffectState = EffectBase.EffectState.Before;
|
||||
effectBase.Recover();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,14 @@ namespace Ichni.Editor
|
||||
{
|
||||
isRotatingSceneCamera = true;
|
||||
// 初始化当前旋转角度,防止旋转跳变
|
||||
_currentRotation = sceneCameraTransform.eulerAngles;
|
||||
// 注意:Unity 的 eulerAngles 返回 0~360,需要将 X 分量规范化到 -180~180
|
||||
// 避免 DOTween/PanelDrawer 残留的 (90,0,0) 被直接拾取后造成瞬间俯视
|
||||
Vector3 rawAngles = sceneCameraTransform.eulerAngles;
|
||||
_currentRotation = new Vector3(
|
||||
rawAngles.x > 180f ? rawAngles.x - 360f : rawAngles.x,
|
||||
rawAngles.y > 180f ? rawAngles.y - 360f : rawAngles.y,
|
||||
0f
|
||||
);
|
||||
}
|
||||
else if (mouse.rightButton.wasReleasedThisFrame)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user