This commit is contained in:
2026-05-02 21:08:13 +08:00
parent e02c7f5e89
commit 91bc3a269b
27 changed files with 212553 additions and 18619 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -136,6 +136,7 @@ MonoBehaviour:
type: 3}
hsvDrawer: {fileID: 8967832941118495084, guid: a6e56f21472670046ab4dfe41e9c739f,
type: 3}
slider: {fileID: 2642348292953561022, guid: 12ea40fe5365a934e81152d8279c7ca1, type: 3}
generalSecondaryWindow: {fileID: 6108546402767822149, guid: f3b40a60628cd4583bd8f92cacf1ba3e,
type: 3}
compositeParameterWindow: {fileID: 8976586735561836907, guid: 6d98a93f5b5c14ef5b7b125e407ce17d,
@@ -163,5 +164,5 @@ MonoBehaviour:
QuickMoveObj: {fileID: 2260653761532832587, guid: dba2d8dbaab1439469ac4924d33e3397,
type: 3}
defaultBackground: {fileID: 21300000, guid: fc6c02e75b66345c29e8a25e2e2bda9c, type: 3}
defaultSkyboxMaterial: {fileID: 2100000, guid: 86dabb0c8cddcb741a5690ed143e3fb2,
defaultSkyboxMaterial: {fileID: 2100000, guid: 06a20df987b317044a05ea694c976948,
type: 2}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 12ea40fe5365a934e81152d8279c7ca1
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,225 @@
using System.Collections;
using System.Collections.Generic;
using Ichni.RhythmGame;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace Ichni.Editor
{
public class DynamicUISlider : DynamicUIElement
{
public Slider slider;
public TMP_InputField valueInputField;
public TMP_InputField minInputField;
public TMP_InputField maxInputField;
private UnityAction<float> customAction;
private bool updatingInternally; // 防止输入框和滑块互相递归更新
#region [] Initialize
public override void Initialize(IBaseElement baseElement, string title, string parameterName)
{
Initialize(baseElement, title, parameterName, 0f, 1f, false);
}
public void Initialize(IBaseElement baseElement, string title, string parameterName,
float min, float max, bool wholeNumbers = false)
{
slider.minValue = min;
slider.maxValue = max;
slider.wholeNumbers = wholeNumbers;
// [对象池安全] 精准解绑业务代理
slider.onValueChanged.RemoveListener(OnSliderValueChanged);
valueInputField?.onEndEdit.RemoveListener(OnValueInputEndEdit);
minInputField?.onEndEdit.RemoveListener(OnMinInputEndEdit);
maxInputField?.onEndEdit.RemoveListener(OnMaxInputEndEdit);
customAction = null;
base.Initialize(baseElement, title, parameterName);
if (parameterName != string.Empty)
{
var val = ReflectionHelper.GetDeepValue(connectedBaseElement, parameterName);
if (val != null)
{
slider.SetValueWithoutNotify(System.Convert.ToSingle(val));
}
else
{
Debug.LogWarning($"[DynamicUI] 尝试绑定 {title} ({parameterName}) 失败,由于其值或路径无效。");
}
slider.onValueChanged.AddListener(OnSliderValueChanged);
}
else
{
slider.onValueChanged.AddListener(OnSliderValueChanged);
}
SyncAllInputFields();
}
#endregion
#region [] Slider Callback
private void OnSliderValueChanged(float value)
{
if (updatingInternally) return;
updatingInternally = true;
UpdateValueInputText(value);
if (parameterName != string.Empty)
{
ApplyParameters(value);
}
customAction?.Invoke(value);
updatingInternally = false;
}
#endregion
#region [] Input Field Callbacks
private void OnValueInputEndEdit(string text)
{
if (updatingInternally) return;
if (!float.TryParse(text, out float val)) return;
val = Mathf.Clamp(val, slider.minValue, slider.maxValue);
updatingInternally = true;
slider.SetValueWithoutNotify(val);
UpdateValueInputText(val);
if (parameterName != string.Empty)
{
ApplyParameters(val);
}
customAction?.Invoke(val);
updatingInternally = false;
}
private void OnMinInputEndEdit(string text)
{
if (updatingInternally) return;
if (!float.TryParse(text, out float val)) return;
if (val >= slider.maxValue) val = slider.maxValue - 0.0001f;
slider.minValue = val;
if (slider.value < val)
{
slider.value = val;
}
UpdateMinMaxInputTexts();
UpdateValueInputText(slider.value);
}
private void OnMaxInputEndEdit(string text)
{
if (updatingInternally) return;
if (!float.TryParse(text, out float val)) return;
if (val <= slider.minValue) val = slider.minValue + 0.0001f;
slider.maxValue = val;
if (slider.value > val)
{
slider.value = val;
}
UpdateMinMaxInputTexts();
UpdateValueInputText(slider.value);
}
#endregion
#region [] Apply Parameters
private void ApplyParameters(float value)
{
object convertedValue;
if (slider.wholeNumbers)
{
convertedValue = Mathf.RoundToInt(value);
}
else
{
convertedValue = value;
}
Ichni.Editor.Commands.CommandManager.ExecuteCommand(
new Ichni.Editor.Commands.ChangeValueCommand(connectedBaseElement, parameterName, convertedValue));
connectedBaseElement.Refresh();
}
#endregion
#region [UI ] UI Sync Helpers
private void SyncAllInputFields()
{
UpdateValueInputText(slider.value);
UpdateMinMaxInputTexts();
}
private void UpdateValueInputText(float value)
{
if (valueInputField != null)
{
valueInputField.SetTextWithoutNotify(slider.wholeNumbers
? Mathf.RoundToInt(value).ToString()
: value.ToString("F3"));
}
}
private void UpdateMinMaxInputTexts()
{
string FormatRangeVal(float v)
{
return slider.wholeNumbers ? Mathf.RoundToInt(v).ToString() : v.ToString("F3");
}
if (minInputField != null)
{
minInputField.SetTextWithoutNotify(FormatRangeVal(slider.minValue));
}
if (maxInputField != null)
{
maxInputField.SetTextWithoutNotify(FormatRangeVal(slider.maxValue));
}
}
#endregion
#region [Public API]
public void SetRange(float min, float max)
{
slider.minValue = min;
slider.maxValue = max;
UpdateMinMaxInputTexts();
UpdateValueInputText(slider.value);
}
public void SetWholeNumbers(bool wholeNumbers)
{
slider.wholeNumbers = wholeNumbers;
SyncAllInputFields();
}
public override DynamicUIElement AddListenerFunction(UnityAction action)
{
customAction += _ => action();
return this;
}
#endregion
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -59,6 +59,27 @@ namespace Ichni.Editor
}
}
/// <summary>
/// 滑块控制属性,适用于 float/int 类型字段,自动生成带范围限制的 Slider 替代 InputField。
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class DynamicUISliderAttribute : DynamicUIAttribute
{
public float Min { get; set; }
public float Max { get; set; }
public bool WholeNumbers { get; set; }
public DynamicUISliderAttribute(string name = "", string group = "Default",
float min = 0f, float max = 1f, bool wholeNumbers = false,
int span = 0, float height = 0f, bool autoUpdate = false, bool readOnly = false)
: base(name, group, span, height, autoUpdate, readOnly)
{
Min = min;
Max = max;
WholeNumbers = wholeNumbers;
}
}
/// <summary>
/// 操作按钮卡片,挂载在没有任何参数的 Method() 方法上
/// </summary>

View File

@@ -73,7 +73,7 @@ namespace Ichni.Editor
// 先排变量
foreach (var field in fieldsInGroup)
{
int span = field.Attr.Span > 0 ? field.Attr.Span : SmartInferSpan(field.ValueType);
int span = GetEffectiveSpan(field);
span = Mathf.Clamp(span, 1, 3);
// 如果该行的槽被塞满了或者装不下了
@@ -83,12 +83,12 @@ namespace Ichni.Editor
currentLineBuffer.Clear();
currentSpanCount = 0;
}
// 特殊兼容:由于 GridLayoutGroup 的强制统一 cellSize, 我们如果在同一行混搭不同 Span 宽度的,反而会让它变形。
// 因此若当前这行的空间要求和前一个需求跨度不一致,也必须强行断点分层!
if (currentLineBuffer.Count > 0)
{
var lastSpan = currentLineBuffer[0].Attr.Span > 0 ? currentLineBuffer[0].Attr.Span : SmartInferSpan(currentLineBuffer[0].ValueType);
var lastSpan = GetEffectiveSpan(currentLineBuffer[0]);
if (span != lastSpan)
{
FlushLine(element, inspector, container, currentLineBuffer, GetHighestSpanRequirement(currentLineBuffer));
@@ -124,8 +124,7 @@ namespace Ichni.Editor
// 如果一行要放 3 份Span 都是 1 拼成的),那格子数量也是 3600/3=200一个
// 但是如果是独占的Span 都是 3格子数量反而应该是 1600/1=600一个
// 为了防止排版错开变形,我们通过 3 / span 来决定 Subcontainer 内部允许的等分元素数量。
int subcontainerDivision = 3 / lineSpanCapacity;
if (subcontainerDivision < 1) subcontainerDivision = 1;
int subcontainerDivision = Mathf.Max(1, Mathf.RoundToInt(3f / lineSpanCapacity));
float rowHeight = GetHighestHeightRequirement(fields);
var sub = container.GenerateSubcontainer(subcontainerDivision, rowHeight);
@@ -169,6 +168,10 @@ namespace Ichni.Editor
{
inspector.GenerateDropdown(element, sub, title, fd.ValueType, pName);
}
else if (fd.Attr is DynamicUISliderAttribute sliderAttr)
{
inspector.GenerateSlider(element, sub, title, pName, sliderAttr.Min, sliderAttr.Max, sliderAttr.WholeNumbers);
}
else // 容错给普通的 InputField
{
inspector.GenerateInputField(element, sub, title, pName, fd.Attr.AutoUpdate);
@@ -191,12 +194,17 @@ namespace Ichni.Editor
int highest = 1;
foreach (var f in fields)
{
int span = f.Attr.Span > 0 ? f.Attr.Span : SmartInferSpan(f.ValueType);
int span = GetEffectiveSpan(f);
if (span > highest) highest = span;
}
return highest;
}
private static int GetEffectiveSpan(FieldDef fd)
{
return fd.Attr.Span > 0 ? fd.Attr.Span : SmartInferSpan(fd.ValueType);
}
private static float SmartInferHeight(FieldDef fd)
{
// EmissionColorPicker 有 Toggle/RGB滑块/Intensity输入框高度明显大于 BaseColorPicker

View File

@@ -274,5 +274,31 @@ namespace Ichni.Editor
subcontainer.dynamicUIElements.Add(hsvDrawer);
return hsvDrawer;
}
public DynamicUISlider GenerateSlider(DynamicUISubcontainer subcontainer,
string title, float defaultValue = 0.5f, float min = 0f, float max = 1f, bool wholeNumbers = false)
{
DynamicUISlider slider = LeanPool
.Spawn(EditorManager.instance.basePrefabs.slider, subcontainer.rect)
.GetComponent<DynamicUISlider>();
slider.Initialize(null, title, string.Empty, min, max, wholeNumbers);
slider.slider.SetValueWithoutNotify(defaultValue);
subcontainer.dynamicUIElements.Add(slider);
return slider;
}
public DynamicUISlider GenerateSlider(IBaseElement baseElement,
DynamicUISubcontainer subcontainer, string title, string parameterName,
float min = 0f, float max = 1f, bool wholeNumbers = false)
{
DynamicUISlider slider = LeanPool
.Spawn(EditorManager.instance.basePrefabs.slider, subcontainer.rect)
.GetComponent<DynamicUISlider>();
slider.Initialize(baseElement, title, parameterName, min, max, wholeNumbers);
var nav = new Navigation { mode = Navigation.Mode.None };
slider.slider.navigation = nav;
subcontainer.dynamicUIElements.Add(slider);
return slider;
}
}
}

View File

@@ -3,8 +3,11 @@ using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using DG.Tweening;
using Ichni.RhythmGame;
using Lean.Pool;
using Sirenix.OdinInspector;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
@@ -24,9 +27,16 @@ namespace Ichni.Editor
public Button clipLoadButton;
public Button beatmapToolsButton;
[Title("Search")]
public TMP_InputField searchInput;
public RectTransform searchResultsRoot;
public GameObject searchResultItemPrefab;
[Title("Windows")]
public GeneralSecondaryWindow clipManagementWindow;
private readonly List<GameObject> searchResultItems = new List<GameObject>();
protected override void Start()
{
base.Start();
@@ -40,6 +50,84 @@ namespace Ichni.Editor
beatmapToolsButton.onClick.AddListener(GenerateBeatmapToolsWindow);
//songInfoButton.onClick.AddListener(已经在songinfo好了);
//projectInfoButton.onClick.AddListener(已经在projectinfo好了);
SetupSearch();
}
private void SetupSearch()
{
searchInput.onValueChanged.AddListener(OnSearchValueChanged);
searchInput.onSelect.AddListener(_ =>
{
searchResultsRoot.transform.DOScaleX(1, 0.25f);
searchResultsRoot.gameObject.SetActive(true);
});
// searchInput.onDeselect.AddListener(_ =>
// {
// // 延迟隐藏,避免点击结果项时面板先消失了
//
// });
searchResultsRoot.gameObject.SetActive(false);
}
private void OnSearchValueChanged(string query)
{
ClearSearchResults();
if (string.IsNullOrWhiteSpace(query)) return;
string lowerQuery = query.ToLower();
var matches = EditorManager.instance.beatmapContainer.gameElementList
.Where(e => e != null && e.elementName.ToLower().Contains(lowerQuery))
.Take(20)
.ToList();
if (matches.Count == 0) return;
searchResultsRoot.gameObject.SetActive(true);
foreach (var element in matches)
{
var item = LeanPool.Spawn(searchResultItemPrefab, searchResultsRoot);
var itemText = item.GetComponentInChildren<TMP_Text>();
if (itemText != null)
itemText.text = element.elementName + " " + element.GetType().ToString();
var button = item.GetComponentInChildren<Button>();
if (button != null)
{
GameElement captured = element;
button.onClick.RemoveAllListeners();
button.onClick.AddListener(() =>
{
EditorManager.instance.uiManager.hierarchy.FindTab(captured);
searchResultsRoot.transform.DOScaleX(0, 0.25f).OnComplete(() =>
{
searchInput.text = string.Empty;
ClearSearchResults();
searchResultsRoot.gameObject.SetActive(false);
});
});
}
searchResultItems.Add(item);
}
}
private void ClearSearchResults()
{
foreach (var item in searchResultItems)
{
if (item != null)
LeanPool.Despawn(item);
}
searchResultItems.Clear();
}
}
@@ -214,7 +302,7 @@ namespace Ichni.Editor
flick.Refresh();
}
});
var ResetNoteAudioButton = beatmapToolsWindow.GenerateButton(beatmapToolsSettings, "Reset Note Audio", () =>
{
List<NoteBase> allNotes = EditorManager.instance.beatmapContainer.gameElementList.FindAll(x => x is NoteBase).ConvertAll(x => x as NoteBase);
@@ -227,11 +315,11 @@ namespace Ichni.Editor
{
hold.submoduleList.Remove(hold.noteAudioSubmodule);
hold.noteAudioSubmodule = null;
hold.noteAudioSubmodule = new NoteAudioSubmodule(hold,
new List<string>(){"DefaultEndHold"},
hold.noteAudioSubmodule = new NoteAudioSubmodule(hold,
new List<string>() { "DefaultEndHold" },
new List<string>(), new List<string>(),
new List<string>(), new List<string>(),
new List<string>(){"DefaultStartHold"});
new List<string>() { "DefaultStartHold" });
}
}
@@ -241,8 +329,8 @@ namespace Ichni.Editor
{
flick.submoduleList.Remove(flick.noteAudioSubmodule);
flick.noteAudioSubmodule = null;
flick.noteAudioSubmodule = new NoteAudioSubmodule(flick,
new List<string>(){"DefaultFlick"},
flick.noteAudioSubmodule = new NoteAudioSubmodule(flick,
new List<string>() { "DefaultFlick" },
new List<string>(), new List<string>(),
new List<string>(), new List<string>(),
new List<string>());

View File

@@ -61,6 +61,7 @@ namespace Ichni.RhythmGame
public GameObject baseColorPicker;
public GameObject emissionColorPicker;
public GameObject hsvDrawer;
public GameObject slider;
[Title("DynamicUI相关-Composite")] public GameObject generalSecondaryWindow;
public GameObject compositeParameterWindow;

View File

@@ -42,10 +42,10 @@ namespace Ichni
#region [] Editor Preferences
// 这些首选项字段放在 ProjectContainer 中,以便 SetUpInspector 将 this 作为 IBaseElement owner 传给 GenerateToggle
public NoteBase.NoteJudgeType currentJudgeType;
public bool useClickSelect;
public bool useNotePrefab;
public bool ExpandWhileClick;
public bool useQuickMove;
public bool useClickSelect = true;
public bool useNotePrefab = true;
public bool ExpandWhileClick = true;
public bool useQuickMove = false;
#endregion
#region [] Generation & Initialization

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c9b1b102bb37569428cfcf5d4724609b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 87b23a7f57106704ba0f0a4e7ec1c5f7
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5f95b2ad8cd26e0418cc0cdfc3750435
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 986f04cde9c76b040832e51ebdc4dacd
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because one or more lines are too long

View File

@@ -26,9 +26,9 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("DTMGlobalFog");
var subcontainer = container.GenerateSubcontainer(3);
var subcontainer = container.GenerateSubcontainer(2);
inspector.GenerateInputField(this, subcontainer, "Fog Intensity", nameof(fogIntensity)).AddListenerFunction(UpdateFogProperties);
inspector.GenerateSlider(this, subcontainer, "Fog Intensity", nameof(fogIntensity), min: 0, max: 5).AddListenerFunction(UpdateFogProperties);
var colorStartContainer = container.GenerateSubcontainer(1, 240);
inspector.GenerateEmissionColorPicker(this, colorStartContainer, "Fog Color Start", "NULL", nameof(fogColorStart), nameof(fogColorStartIntensity))
@@ -38,14 +38,14 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
inspector.GenerateEmissionColorPicker(this, colorEndContainer, "Fog Color End", "NULL", nameof(fogColorEnd), nameof(fogColorEndIntensity))
.AddListenerFunction(UpdateFogProperties);
inspector.GenerateInputField(this, subcontainer, "Fog Color Duo", nameof(fogColorDuo)).AddListenerFunction(UpdateFogProperties);
inspector.GenerateInputField(this, subcontainer, "Skybox Fog Intensity", nameof(skyboxFogIntensity)).AddListenerFunction(UpdateFogProperties);
inspector.GenerateInputField(this, subcontainer, "Skybox Fog Height", nameof(skyboxFogHeight)).AddListenerFunction(UpdateFogProperties);
inspector.GenerateInputField(this, subcontainer, "Skybox Fog Falloff", nameof(skyboxFogFalloff)).AddListenerFunction(UpdateFogProperties);
inspector.GenerateInputField(this, subcontainer, "Skybox Fog Offset", nameof(skyboxFogOffset)).AddListenerFunction(UpdateFogProperties);
inspector.GenerateSlider(this, subcontainer, "Fog Color Duo", nameof(fogColorDuo), min: 0, max: 1).AddListenerFunction(UpdateFogProperties);
inspector.GenerateSlider(this, subcontainer, "Skybox Fog Intensity", nameof(skyboxFogIntensity), min: 0, max: 5).AddListenerFunction(UpdateFogProperties);
inspector.GenerateSlider(this, subcontainer, "Skybox Fog Height", nameof(skyboxFogHeight), min: 0, max: 10).AddListenerFunction(UpdateFogProperties);
inspector.GenerateSlider(this, subcontainer, "Skybox Fog Falloff", nameof(skyboxFogFalloff), min: 0, max: 10).AddListenerFunction(UpdateFogProperties);
inspector.GenerateSlider(this, subcontainer, "Skybox Fog Offset", nameof(skyboxFogOffset), min: -10, max: 10).AddListenerFunction(UpdateFogProperties);
inspector.GenerateInputField(this, subcontainer, "Skybox Fog Bottom", nameof(skyboxFogBottom)).AddListenerFunction(UpdateFogProperties);
inspector.GenerateInputField(this, subcontainer, "Skybox Fog Fill", nameof(skyboxFogFill)).AddListenerFunction(UpdateFogProperties);
inspector.GenerateSlider(this, subcontainer, "Skybox Fog Bottom", nameof(skyboxFogBottom), min: -10, max: 10).AddListenerFunction(UpdateFogProperties);
inspector.GenerateSlider(this, subcontainer, "Skybox Fog Fill", nameof(skyboxFogFill), min: 0, max: 5).AddListenerFunction(UpdateFogProperties);
}
#endregion
}

View File

@@ -23,22 +23,22 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("DTMFramesFloor");
var subcontainer = container.GenerateSubcontainer(3);
var subcontainer = container.GenerateSubcontainer(2);
inspector.GenerateSlider(this, subcontainer, "Pattern Size X", nameof(patternSizeX), min: 0, max: 20).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Pattern Size Y", nameof(patternSizeY), min: 0, max: 20).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Grid Density", nameof(gridDensity), min: 0, max: 10).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Time Angle", nameof(timeAngle), min: 0, max: 6.28f).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Step A", nameof(stepA), min: 0, max: 1).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Step B", nameof(stepB), min: 0, max: 1).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Base Speed", nameof(baseSpeed), min: 0, max: 3).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Pattern Size X", nameof(patternSizeX)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Pattern Size Y", nameof(patternSizeY)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Grid Density", nameof(gridDensity)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Time Angle", nameof(timeAngle)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Step A", nameof(stepA)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Step B", nameof(stepB)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Base Speed", nameof(baseSpeed)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateToggle(this, subcontainer, "Enable Outer Border", nameof(enableOuterBorder)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateBaseColorPicker(this, subcontainer, "Outer Border Color", nameof(outerBorderColor)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Outer Border Width", nameof(outerBorderWidth)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Outer Border Width", nameof(outerBorderWidth), min: 0, max: 5).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Fade Far", nameof(fadeFar)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Fade Near", nameof(fadeNear)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Fade Far", nameof(fadeFar), min: 0, max: 500).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Fade Near", nameof(fadeNear), min: 0, max: 100).AddListenerFunction(UpdateMaterialProperties);
}
#endregion
}

View File

@@ -23,23 +23,23 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("DTMRandomGridTube");
var subcontainer = container.GenerateSubcontainer(3);
var subcontainer = container.GenerateSubcontainer(2);
inspector.GenerateInputField(this, subcontainer, "Pattern Size X", nameof(patternSizeX)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Pattern Size Y", nameof(patternSizeY)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Grid Density", nameof(gridDensity)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Time Angle", nameof(timeAngle)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Step A", nameof(stepA)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Step B", nameof(stepB)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Base Speed", nameof(baseSpeed)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Pattern Size X", nameof(patternSizeX), min: 0, max: 20).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Pattern Size Y", nameof(patternSizeY), min: 0, max: 20).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Grid Density", nameof(gridDensity), min: 0, max: 10).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Time Angle", nameof(timeAngle), min: 0, max: 6.28f).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Step A", nameof(stepA), min: 0, max: 1).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Step B", nameof(stepB), min: 0, max: 1).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Base Speed", nameof(baseSpeed), min: 0, max: 3).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Seam Rotation", nameof(seamRotation)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Seam Fade Width", nameof(seamFadeWidth)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Seam Fade Smoothness", nameof(seamFadeSmoothness)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Seam Rotation", nameof(seamRotation), min: -180, max: 180).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Seam Fade Width", nameof(seamFadeWidth), min: 0, max: 5).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Seam Fade Smoothness", nameof(seamFadeSmoothness), min: 0, max: 5).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Fade Far", nameof(fadeFar)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Fade Near", nameof(fadeNear)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateInputField(this, subcontainer, "Tube Radius", nameof(tubeRadius)).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Fade Far", nameof(fadeFar), min: 0, max: 500).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Fade Near", nameof(fadeNear), min: 0, max: 100).AddListenerFunction(UpdateMaterialProperties);
inspector.GenerateSlider(this, subcontainer, "Tube Radius", nameof(tubeRadius), min: 0, max: 50).AddListenerFunction(UpdateMaterialProperties);
}
#endregion
}

View File

@@ -42,11 +42,11 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
ew.SetAsFlexibleFloat();
});
var enableProcessTimeInputField =
inspector.GenerateInputField(this, subcontainer, "Enable Process Time", nameof(enableProcessTime));
var enableProcessTimeSlider =
inspector.GenerateSlider(this, subcontainer, "Enable Process Time", nameof(enableProcessTime), min: 0, max: 3);
var headSizeInputField =
inspector.GenerateInputField(this, subcontainer, "Head Size", nameof(headSize));
var headSizeSlider =
inspector.GenerateSlider(this, subcontainer, "Head Size", nameof(headSize), min: 0, max: 10);
var curveSettings = container.GenerateSubcontainer(3);
var widthCurveButton = inspector.GenerateButton(this, curveSettings, "Width Curve", () =>

View File

@@ -21,17 +21,17 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public Color skyColor = Color.blue;
[Ichni.Editor.DynamicUIEmissionColor("Horizon", Group = "DTMStarrySkybox - Sky")]
public Color horizon = Color.cyan;
[Ichni.Editor.DynamicUI("Horizon Strength", Group = "DTMStarrySkybox - Sky")]
[Ichni.Editor.DynamicUISlider("Horizon Strength", Group = "DTMStarrySkybox - Sky", Span = 2, Min = 0, Max = 5)]
public float horizonStrength = 2f;
[Ichni.Editor.DynamicUI("Horizon Sky Height", Group = "DTMStarrySkybox - Sky")]
[Ichni.Editor.DynamicUISlider("Horizon Sky Height", Group = "DTMStarrySkybox - Sky", Span = 2, Min = 0, Max = 2)]
public float horizonSkyHeight = 0.7f;
// --- Stars ---
[Ichni.Editor.DynamicUI("Use Star Map", Group = "DTMStarrySkybox - Stars")]
public bool useStarMap = true;
[Ichni.Editor.DynamicUI("Star Density", Group = "DTMStarrySkybox - Stars")]
[Ichni.Editor.DynamicUISlider("Star Density", Group = "DTMStarrySkybox - Stars", Span = 2, Min = 0, Max = 200)]
public float starDensity = 30f;
[Ichni.Editor.DynamicUI("Star Size", Group = "DTMStarrySkybox - Stars")]
[Ichni.Editor.DynamicUISlider("Star Size", Group = "DTMStarrySkybox - Stars", Span = 2, Min = 0, Max = 300)]
public float starSize = 75f;
[Ichni.Editor.DynamicUIEmissionColor("Star Color", Group = "DTMStarrySkybox - Stars")]
public Color starColor = Color.white;
@@ -45,27 +45,27 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public bool haveSun = false;
[Ichni.Editor.DynamicUI("Sun Mask Texture (Name)", Group = "DTMStarrySkybox - Sun", Span = 3)]
public string sunMaskTextureName = "None";
[Ichni.Editor.DynamicUI("Sun Mask Size", Group = "DTMStarrySkybox - Sun")]
[Ichni.Editor.DynamicUISlider("Sun Mask Size", Group = "DTMStarrySkybox - Sun", Span = 2, Min = 0, Max = 0.2f)]
public float sunMaskSize = 0.02f;
[Ichni.Editor.DynamicUI("Sun Mask Spherize", Group = "DTMStarrySkybox - Sun")]
[Ichni.Editor.DynamicUISlider("Sun Mask Spherize", Group = "DTMStarrySkybox - Sun", Span = 2, Min = 0, Max = 30)]
public float sunMaskSpherize = 13.2f;
[Ichni.Editor.DynamicUI("Sun Disc Size", Group = "DTMStarrySkybox - Sun")]
[Ichni.Editor.DynamicUISlider("Sun Disc Size", Group = "DTMStarrySkybox - Sun", Span = 2, Min = 0, Max = 5)]
public float sunDiscSize = 1f;
[Ichni.Editor.DynamicUIEmissionColor("Sun Color One", Group = "DTMStarrySkybox - Sun")]
public Color sunColorOne = Color.white;
[Ichni.Editor.DynamicUIEmissionColor("Sun Color Two", Group = "DTMStarrySkybox - Sun")]
public Color sunColorTwo = Color.white;
[Ichni.Editor.DynamicUI("Sun Gradient Strength", Group = "DTMStarrySkybox - Sun")]
[Ichni.Editor.DynamicUISlider("Sun Gradient Strength", Group = "DTMStarrySkybox - Sun", Span = 2, Min = 0, Max = 10)]
public float sunGradientStrength = 3.7f;
[Ichni.Editor.DynamicUI("Sun Gradient Height", Group = "DTMStarrySkybox - Sun")]
[Ichni.Editor.DynamicUISlider("Sun Gradient Height", Group = "DTMStarrySkybox - Sun", Span = 2, Min = 0, Max = 3)]
public float sunGradientHeight = 1.23f;
// --- Fog ---
[Ichni.Editor.DynamicUI("Fog Height", Group = "DTMStarrySkybox - Fog")]
[Ichni.Editor.DynamicUISlider("Fog Height", Group = "DTMStarrySkybox - Fog", Span = 2, Min = 0, Max = 5)]
public float fogHeight = 1f;
[Ichni.Editor.DynamicUI("Fog Power", Group = "DTMStarrySkybox - Fog")]
[Ichni.Editor.DynamicUISlider("Fog Power", Group = "DTMStarrySkybox - Fog", Span = 2, Min = 0, Max = 1)]
public float fogPower = 0.5f;
[Ichni.Editor.DynamicUI("Fog Contrast", Group = "DTMStarrySkybox - Fog")]
[Ichni.Editor.DynamicUISlider("Fog Contrast", Group = "DTMStarrySkybox - Fog", Span = 2, Min = 0, Max = 200)]
public float fogContrast = 40f;
#endregion
@@ -91,31 +91,31 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
isFirstGenerated, themeBundleName, objectName, parentElement, isStatic)
.GetComponent<DTMStarrySkybox>();
skybox.skyColor = skyColor;
skybox.horizon = horizon;
skybox.horizonStrength = horizonStrength;
skybox.horizonSkyHeight = horizonSkyHeight;
skybox.skyColor = skyColor;
skybox.horizon = horizon;
skybox.horizonStrength = horizonStrength;
skybox.horizonSkyHeight = horizonSkyHeight;
skybox.useStarMap = useStarMap;
skybox.starDensity = starDensity;
skybox.starSize = starSize;
skybox.starColor = starColor;
skybox.useStarMap = useStarMap;
skybox.starDensity = starDensity;
skybox.starSize = starSize;
skybox.starColor = starColor;
skybox.preventStarsInFrontOfSun = preventStarsInFrontOfSun;
skybox.starMapTextureName = starMapTextureName;
skybox.starMapTextureName = starMapTextureName;
skybox.haveSun = haveSun;
skybox.sunMaskTextureName = sunMaskTextureName;
skybox.sunMaskSize = sunMaskSize;
skybox.sunMaskSpherize = sunMaskSpherize;
skybox.sunDiscSize = sunDiscSize;
skybox.sunColorOne = sunColorOne;
skybox.sunColorTwo = sunColorTwo;
skybox.sunGradientStrength = sunGradientStrength;
skybox.sunGradientHeight = sunGradientHeight;
skybox.haveSun = haveSun;
skybox.sunMaskTextureName = sunMaskTextureName;
skybox.sunMaskSize = sunMaskSize;
skybox.sunMaskSpherize = sunMaskSpherize;
skybox.sunDiscSize = sunDiscSize;
skybox.sunColorOne = sunColorOne;
skybox.sunColorTwo = sunColorTwo;
skybox.sunGradientStrength = sunGradientStrength;
skybox.sunGradientHeight = sunGradientHeight;
skybox.fogHeight = fogHeight;
skybox.fogPower = fogPower;
skybox.fogContrast = fogContrast;
skybox.fogHeight = fogHeight;
skybox.fogPower = fogPower;
skybox.fogContrast = fogContrast;
return skybox;
}
@@ -204,11 +204,11 @@ namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse
public override void Refresh()
{
base.Refresh();
// 加入自动材质同步网:所有的数值被 UI 工具如撤回系统或滚动输入修改时UI 均会默认调用 Refresh() 结束更改。
// 此时自动将最新参数一次性烘焙至天空盒,再也无需每个 Inspector 元件去手动 AddListener()
UpdateSkyboxProperties();
if (skyboxMaterial != null)
{
RenderSettings.skybox = skyboxMaterial;