This commit is contained in:
SoulliesOfficial
2026-06-09 01:43:55 -04:00
parent 0fb72f5bba
commit 5fc1392747
171 changed files with 30149 additions and 22331 deletions

View File

@@ -1,5 +1,4 @@
using Ichni.Editor;
using UnityEngine;
namespace Ichni.RhythmGame
{
@@ -8,13 +7,12 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Camera Field of View");
var subcontainer = container.GenerateSubcontainer(3);
var fovButton = inspector.GenerateButton(this, subcontainer, "Field of View", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Field of View", nameof(fieldOfView)).SetAsFlexibleFloat();
});
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("Camera Field of View")
.Button("Field of View", () => insp.GenerateCompositeParameterWindow(this, "Field of View", nameof(fieldOfView)).SetAsFlexibleFloat())
.Build();
}
}
}

View File

@@ -1,5 +1,4 @@
using Ichni.Editor;
using UnityEngine;
namespace Ichni.RhythmGame
{
@@ -7,31 +6,18 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
base.SetUpInspector();
var container = inspector.GenerateContainer("Base Color Change");
var subcontainer = container.GenerateSubcontainer(3);
var colorRButton = inspector.GenerateButton(this, subcontainer, "Color R", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color R", nameof(colorR)).SetAsFlexibleFloat();
});
var colorGButton = inspector.GenerateButton(this, subcontainer, "Color G", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color G", nameof(colorG)).SetAsFlexibleFloat();
});
var colorBButton = inspector.GenerateButton(this, subcontainer, "Color B", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color B", nameof(colorB)).SetAsFlexibleFloat();
});
var colorAButton = inspector.GenerateButton(this, subcontainer, "Color A", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color A", nameof(colorA)).SetAsFlexibleFloat();
});
var graphicEditor = inspector.GenerateButton(this, subcontainer, "GraphicEditor", () =>
{
inspector.GenerateGraphicalFlexibleFloatWindow(this, "Base Color",
new FlexibleFloat[] { colorR, colorG, colorB, colorA }, new string[] { "R", "G", "B", "A" });
});
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("Base Color Change")
.Button("Color R", () => insp.GenerateCompositeParameterWindow(this, "Color R", nameof(colorR)).SetAsFlexibleFloat())
.Button("Color G", () => insp.GenerateCompositeParameterWindow(this, "Color G", nameof(colorG)).SetAsFlexibleFloat())
.Button("Color B", () => insp.GenerateCompositeParameterWindow(this, "Color B", nameof(colorB)).SetAsFlexibleFloat())
.Button("Color A", () => insp.GenerateCompositeParameterWindow(this, "Color A", nameof(colorA)).SetAsFlexibleFloat())
.Button("GraphicEditor", () => insp.GenerateGraphicalFlexibleFloatWindow(this, "Base Color",
new FlexibleFloat[] { colorR, colorG, colorB, colorA }, new string[] { "R", "G", "B", "A" }))
.Build();
}
}
}

View File

@@ -1,5 +1,4 @@
using Ichni.Editor;
using UnityEngine;
namespace Ichni.RhythmGame
{
@@ -7,31 +6,18 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
base.SetUpInspector();
var container = inspector.GenerateContainer("Emission Color Change");
var subcontainer = container.GenerateSubcontainer(3);
var colorRButton = inspector.GenerateButton(this, subcontainer, "Color R", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color R", nameof(colorR)).SetAsFlexibleFloat();
});
var colorGButton = inspector.GenerateButton(this, subcontainer, "Color G", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color G", nameof(colorG)).SetAsFlexibleFloat();
});
var colorBButton = inspector.GenerateButton(this, subcontainer, "Color B", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color B", nameof(colorB)).SetAsFlexibleFloat();
});
var colorAButton = inspector.GenerateButton(this, subcontainer, "Color A", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color I", nameof(colorI)).SetAsFlexibleFloat();
});
var graphicEditor = inspector.GenerateButton(this, subcontainer, "GraphicEditor", () =>
{
inspector.GenerateGraphicalFlexibleFloatWindow(this, "Emission Color",
new FlexibleFloat[] { colorR, colorG, colorB, colorI }, new string[] { "R", "G", "B", "I" });
});
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("Emission Color Change")
.Button("Color R", () => insp.GenerateCompositeParameterWindow(this, "Color R", nameof(colorR)).SetAsFlexibleFloat())
.Button("Color G", () => insp.GenerateCompositeParameterWindow(this, "Color G", nameof(colorG)).SetAsFlexibleFloat())
.Button("Color B", () => insp.GenerateCompositeParameterWindow(this, "Color B", nameof(colorB)).SetAsFlexibleFloat())
.Button("Color I", () => insp.GenerateCompositeParameterWindow(this, "Color I", nameof(colorI)).SetAsFlexibleFloat())
.Button("GraphicEditor", () => insp.GenerateGraphicalFlexibleFloatWindow(this, "Emission Color",
new FlexibleFloat[] { colorR, colorG, colorB, colorI }, new string[] { "R", "G", "B", "I" }))
.Build();
}
}
}

View File

@@ -15,37 +15,23 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
base.SetUpInspector();
var container = inspector.GenerateContainer("Property Animation Color");
var settings = container.GenerateSubcontainer(3);
inspector.GenerateInputField(this, settings, "Component Name", nameof(componentName)).AddListenerFunction(() => AfterInitialize());
inspector.GenerateInputField(this, settings, "Property Name", nameof(propertyName)).AddListenerFunction(() => AfterInitialize());
var graphicEditor = inspector.GenerateButton(this, settings, "GraphicEditor", () =>
{
inspector.GenerateGraphicalFlexibleFloatWindow(this, "Property Color",
new FlexibleFloat[] { propertyValueR, propertyValueG, propertyValueB, propertyValueA }, new string[] { "R", "G", "B", "A" });
});
var colorRButton = inspector.GenerateButton(this, settings, "Color R", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color R", nameof(propertyValueR)).SetAsFlexibleFloat();
});
var colorGButton = inspector.GenerateButton(this, settings, "Color G", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color G", nameof(propertyValueG)).SetAsFlexibleFloat();
});
var colorBButton = inspector.GenerateButton(this, settings, "Color B", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color B", nameof(propertyValueB)).SetAsFlexibleFloat();
});
var colorAButton = inspector.GenerateButton(this, settings, "Color A", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color A", nameof(propertyValueA)).SetAsFlexibleFloat();
});
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("Property Animation Color")
.InputField(nameof(componentName), "Component Name")
.OnChanged(() => AfterInitialize())
.InputField(nameof(propertyName), "Property Name")
.OnChanged(() => AfterInitialize())
.Button("GraphicEditor", () => insp.GenerateGraphicalFlexibleFloatWindow(this, "Property Color",
new FlexibleFloat[] { propertyValueR, propertyValueG, propertyValueB, propertyValueA },
new string[] { "R", "G", "B", "A" }))
.Button("Color R", () => insp.GenerateCompositeParameterWindow(this, "Color R", nameof(propertyValueR)).SetAsFlexibleFloat())
.Button("Color G", () => insp.GenerateCompositeParameterWindow(this, "Color G", nameof(propertyValueG)).SetAsFlexibleFloat())
.Button("Color B", () => insp.GenerateCompositeParameterWindow(this, "Color B", nameof(propertyValueB)).SetAsFlexibleFloat())
.Button("Color A", () => insp.GenerateCompositeParameterWindow(this, "Color A", nameof(propertyValueA)).SetAsFlexibleFloat())
.Build();
}
}
}

View File

@@ -14,25 +14,19 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
base.SetUpInspector();
var container = inspector.GenerateContainer("Property Animation Float");
var settings = container.GenerateSubcontainer(3);
inspector.GenerateInputField(this, settings, "Component Name", nameof(componentName)).AddListenerFunction(() => AfterInitialize());
inspector.GenerateInputField(this, settings, "Property Name", nameof(propertyName)).AddListenerFunction(() => AfterInitialize());
var graphicEditor = inspector.GenerateButton(this, settings, "GraphicEditor", () =>
{
inspector.GenerateGraphicalFlexibleFloatWindow(this, "Property Float",
new FlexibleFloat[] { propertyValue }, new string[] { "Value" });
});
var floatButton = inspector.GenerateButton(this, settings, "Float Value", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Float Value", nameof(propertyValue)).SetAsFlexibleFloat();
});
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("Property Animation Float")
.InputField(nameof(componentName), "Component Name")
.OnChanged(() => AfterInitialize())
.InputField(nameof(propertyName), "Property Name")
.OnChanged(() => AfterInitialize())
.Button("GraphicEditor", () => insp.GenerateGraphicalFlexibleFloatWindow(this, "Property Float",
new FlexibleFloat[] { propertyValue }, new string[] { "Value" }))
.Button("Float Value", () => insp.GenerateCompositeParameterWindow(this, "Float Value", nameof(propertyValue)).SetAsFlexibleFloat())
.Build();
}
}
}

View File

@@ -14,33 +14,21 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
base.SetUpInspector();
var container = inspector.GenerateContainer("Property Animation Vector3");
var settings = container.GenerateSubcontainer(3);
inspector.GenerateInputField(this, settings, "Component Name", nameof(componentName)).AddListenerFunction(() => AfterInitialize());
inspector.GenerateInputField(this, settings, "Property Name", nameof(propertyName)).AddListenerFunction(() => AfterInitialize());
var graphicEditor = inspector.GenerateButton(this, settings, "GraphicEditor", () =>
{
inspector.GenerateGraphicalFlexibleFloatWindow(this, "Property Vector3",
new FlexibleFloat[] { propertyValueX, propertyValueY, propertyValueZ }, new string[] { "X", "Y", "Z" });
});
var xButton = inspector.GenerateButton(this, settings, "Vector X", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Vector X", nameof(propertyValueX)).SetAsFlexibleFloat();
});
var yButton = inspector.GenerateButton(this, settings, "Vector Y", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Vector Y", nameof(propertyValueY)).SetAsFlexibleFloat();
});
var zButton = inspector.GenerateButton(this, settings, "Vector Z", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Vector Z", nameof(propertyValueZ)).SetAsFlexibleFloat();
});
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("Property Animation Vector3")
.InputField(nameof(componentName), "Component Name")
.OnChanged(() => AfterInitialize())
.InputField(nameof(propertyName), "Property Name")
.OnChanged(() => AfterInitialize())
.Button("GraphicEditor", () => insp.GenerateGraphicalFlexibleFloatWindow(this, "Property Vector3",
new FlexibleFloat[] { propertyValueX, propertyValueY, propertyValueZ }, new string[] { "X", "Y", "Z" }))
.Button("Vector X", () => insp.GenerateCompositeParameterWindow(this, "Vector X", nameof(propertyValueX)).SetAsFlexibleFloat())
.Button("Vector Y", () => insp.GenerateCompositeParameterWindow(this, "Vector Y", nameof(propertyValueY)).SetAsFlexibleFloat())
.Button("Vector Z", () => insp.GenerateCompositeParameterWindow(this, "Vector Z", nameof(propertyValueZ)).SetAsFlexibleFloat())
.Build();
}
}
}

View File

@@ -11,30 +11,36 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Displacement Tracker");
var effectSettings = container.GenerateSubcontainer(2);
var connectedGameElementInputField = inspector.GenerateInputField(effectSettings, "Try Get Displacement");
var connectGameElementButton = inspector.GenerateButton(this, effectSettings, "Connect Displacement", () =>
{
ICanBeTrackedDisplacement targetElement = EditorManager.instance.beatmapContainer.gameElementList.OfType<ICanBeTrackedDisplacement>()
.First(e => ((GameElement)e).elementName == connectedGameElementInputField.GetValue<string>());
if (targetElement == null)
{
LogWindow.Log("Game Element not found.", Color.yellow);
}
SetTargetDisplacement(targetElement);
inspectorMain.SetInspector(this);
});
string ShowConnection() => targetDisplacement == null ? "No Displacement Connected" : "Connected With: " + ((GameElement)targetDisplacement).elementName;
var connectHintText = inspector.GenerateHintText(this, effectSettings, ShowConnection);
var InputField = inspector.GenerateInputField(this, effectSettings, "Offset", nameof(TimeOffset));
var interferometerButton = inspector.GenerateButton(this, effectSettings, "Interferometer", () =>
{
Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(), new List<string>(), true,
this, InterferomType.Additive, Vector3.zero);
});
var nameRef = new ElementRef<DynamicUIInputField>();
InspectorBuilder.For(this)
.Section("Displacement Tracker")
.UnboundInputField("Try Get Displacement").WithRef(nameRef)
.Button("Connect Displacement", () =>
{
ICanBeTrackedDisplacement found = EditorManager.instance.beatmapContainer.gameElementList
.OfType<ICanBeTrackedDisplacement>()
.FirstOrDefault(e => ((GameElement)e).elementName == nameRef.Value?.GetValue<string>());
if (found == null)
{
LogWindow.Log("Game Element not found.", Color.yellow);
return;
}
SetTargetDisplacement(found);
inspectorMain.SetInspector(this);
})
.HintText(() => targetDisplacement == null
? "No Displacement Connected"
: "Connected With: " + ((GameElement)targetDisplacement).elementName)
.InputField(nameof(TimeOffset), "Offset")
.Button("Interferometer", () =>
{
Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(),
new List<string>(), true, this, InterferomType.Additive, Vector3.zero);
})
.Build();
}
}
}

View File

@@ -11,31 +11,36 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Scale Tracker");
var effectSettings = container.GenerateSubcontainer(2);
var connectedGameElementInputField = inspector.GenerateInputField(effectSettings, "Try Get Scale");
var connectGameElementButton = inspector.GenerateButton(this, effectSettings, "Connect Scale", () =>
{
ICanBeTrackedScale targetElement = EditorManager.instance.beatmapContainer.gameElementList.OfType<ICanBeTrackedScale>()
.First(e => ((GameElement)e).elementName == connectedGameElementInputField.GetValue<string>());
if (targetElement == null)
{
LogWindow.Log("Game Element not found.", Color.yellow);
}
targetScale = targetElement;
inspectorMain.SetInspector(this);
});
string ShowConnection() => targetScale == null ? "No Scale Connected" : "Connected With: " + ((GameElement)targetScale).elementName;
var connectHintText = inspector.GenerateHintText(this, effectSettings, ShowConnection);
var InputField = inspector.GenerateInputField(this, effectSettings, "Offset", nameof(TimeOffset));
var interferometerButton = inspector.GenerateButton(this, effectSettings, "Interferometer", () =>
{
Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(), new List<string>(), true,
this, InterferomType.Additive, Vector3.zero);
});
var nameRef = new ElementRef<DynamicUIInputField>();
InspectorBuilder.For(this)
.Section("Scale Tracker")
.UnboundInputField("Try Get Scale").WithRef(nameRef)
.Button("Connect Scale", () =>
{
ICanBeTrackedScale found = EditorManager.instance.beatmapContainer.gameElementList
.OfType<ICanBeTrackedScale>()
.FirstOrDefault(e => ((GameElement)e).elementName == nameRef.Value?.GetValue<string>());
if (found == null)
{
LogWindow.Log("Game Element not found.", Color.yellow);
return;
}
targetScale = found;
inspectorMain.SetInspector(this);
})
.HintText(() => targetScale == null
? "No Scale Connected"
: "Connected With: " + ((GameElement)targetScale).elementName)
.InputField(nameof(TimeOffset), "Offset")
.Button("Interferometer", () =>
{
Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(),
new List<string>(), true, this, InterferomType.Additive, Vector3.zero);
})
.Build();
}
}
}

View File

@@ -11,31 +11,36 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Swirl Tracker");
var effectSettings = container.GenerateSubcontainer(2);
var connectedGameElementInputField = inspector.GenerateInputField(effectSettings, "Try Get Swirl");
var connectGameElementButton = inspector.GenerateButton(this, effectSettings, "Connect Swirl", () =>
{
ICanBeTrackedSwirl targetElement = EditorManager.instance.beatmapContainer.gameElementList.OfType<ICanBeTrackedSwirl>()
.First(e => ((GameElement)e).elementName == connectedGameElementInputField.GetValue<string>());
if (targetElement == null)
{
LogWindow.Log("Game Element not found.", Color.yellow);
}
targetSwirl = targetElement;
inspectorMain.SetInspector(this);
});
string ShowConnection() => targetSwirl == null ? "No Swirl Connected" : "Connected With: " + ((GameElement)targetSwirl).elementName;
var connectHintText = inspector.GenerateHintText(this, effectSettings, ShowConnection);
var InputField = inspector.GenerateInputField(this, effectSettings, "Offset", nameof(TimeOffset));
var interferometerButton = inspector.GenerateButton(this, effectSettings, "Interferometer", () =>
{
Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(), new List<string>(), true,
this, InterferomType.Additive, Vector3.zero);
});
var nameRef = new ElementRef<DynamicUIInputField>();
InspectorBuilder.For(this)
.Section("Swirl Tracker")
.UnboundInputField("Try Get Swirl").WithRef(nameRef)
.Button("Connect Swirl", () =>
{
ICanBeTrackedSwirl found = EditorManager.instance.beatmapContainer.gameElementList
.OfType<ICanBeTrackedSwirl>()
.FirstOrDefault(e => ((GameElement)e).elementName == nameRef.Value?.GetValue<string>());
if (found == null)
{
LogWindow.Log("Game Element not found.", Color.yellow);
return;
}
targetSwirl = found;
inspectorMain.SetInspector(this);
})
.HintText(() => targetSwirl == null
? "No Swirl Connected"
: "Connected With: " + ((GameElement)targetSwirl).elementName)
.InputField(nameof(TimeOffset), "Offset")
.Button("Interferometer", () =>
{
Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(),
new List<string>(), true, this, InterferomType.Additive, Vector3.zero);
})
.Build();
}
}
}

View File

@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame
{
@@ -11,11 +7,12 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Vector3 Interferometer");
var subcontainer = container.GenerateSubcontainer(1);
inspector.GenerateVector3InputField(this, subcontainer, "Interferom Value", nameof(InterferomValueVector3));
inspector.GenerateDropdown(this, subcontainer, "Interferom Type", typeof(InterferomType), nameof(InterferomType));
InspectorBuilder.For(this)
.Section("Vector3 Interferometer")
.Vector3Field(nameof(InterferomValueVector3), "Interferom Value")
.Dropdown<InterferomType>(nameof(InterferomType), "Interferom Type")
.Build();
}
}
}

View File

@@ -1,5 +1,4 @@
using Ichni.Editor;
using UnityEngine;
namespace Ichni.RhythmGame
{
@@ -7,32 +6,18 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
base.SetUpInspector();
var container = inspector.GenerateContainer("Track Global Color Change");
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
var subcontainer = container.GenerateSubcontainer(3);
var colorRButton = inspector.GenerateButton(this, subcontainer, "Color R", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color R", nameof(colorR)).SetAsFlexibleFloat();
});
var colorGButton = inspector.GenerateButton(this, subcontainer, "Color G", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color G", nameof(colorG)).SetAsFlexibleFloat();
});
var colorBButton = inspector.GenerateButton(this, subcontainer, "Color B", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color B", nameof(colorB)).SetAsFlexibleFloat();
});
var colorAButton = inspector.GenerateButton(this, subcontainer, "Color A", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Color A", nameof(colorA)).SetAsFlexibleFloat();
});
var graphicEditor = inspector.GenerateButton(this, subcontainer, "GraphicEditor", () =>
{
inspector.GenerateGraphicalFlexibleFloatWindow(this, "Track Global Color Change",
new FlexibleFloat[] { colorR, colorG, colorB, colorA }, new string[] { "ColorR", "ColorG", "ColorB", "ColorA" });
});
InspectorBuilder.For(this)
.Section("Track Global Color Change")
.Button("Color R", () => insp.GenerateCompositeParameterWindow(this, "Color R", nameof(colorR)).SetAsFlexibleFloat())
.Button("Color G", () => insp.GenerateCompositeParameterWindow(this, "Color G", nameof(colorG)).SetAsFlexibleFloat())
.Button("Color B", () => insp.GenerateCompositeParameterWindow(this, "Color B", nameof(colorB)).SetAsFlexibleFloat())
.Button("Color A", () => insp.GenerateCompositeParameterWindow(this, "Color A", nameof(colorA)).SetAsFlexibleFloat())
.Button("GraphicEditor", () => insp.GenerateGraphicalFlexibleFloatWindow(this, "Track Global Color Change",
new FlexibleFloat[] { colorR, colorG, colorB, colorA }, new string[] { "ColorR", "ColorG", "ColorB", "ColorA" }))
.Build();
}
}
}

View File

@@ -1,5 +1,4 @@
using Ichni.Editor;
using UnityEngine;
namespace Ichni.RhythmGame
{
@@ -7,14 +6,13 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
base.SetUpInspector();
var container = inspector.GenerateContainer("Track Total Time Change");
var subcontainer = container.GenerateSubcontainer(3);
var totalTimeButton = inspector.GenerateButton(this, subcontainer, "Total Time", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Total Time", nameof(totalTime)).SetAsFlexibleFloat();
});
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("Track Total Time Change")
.Button("Total Time", () => insp.GenerateCompositeParameterWindow(this, "Total Time", nameof(totalTime)).SetAsFlexibleFloat())
.Build();
}
}
}

View File

@@ -9,35 +9,22 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
base.SetUpInspector();
var container = inspector.GenerateContainer("Displacement");
var subcontainer = container.GenerateSubcontainer(3);
var positionXButton = inspector.GenerateButton(this, subcontainer, "Position X", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Position X", nameof(positionX)).SetAsFlexibleFloat();
});
var positionYButton = inspector.GenerateButton(this, subcontainer, "Position Y", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Position Y", nameof(positionY)).SetAsFlexibleFloat();
});
var positionZButton = inspector.GenerateButton(this, subcontainer, "Position Z", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Position Z", nameof(positionZ)).SetAsFlexibleFloat();
});
var graphicEditor = inspector.GenerateButton(this, subcontainer, "GraphicEditor", () =>
{
inspector.GenerateGraphicalFlexibleFloatWindow(this, "Displacement",
new FlexibleFloat[] { positionX, positionY, positionZ }, new string[] { "PosX", "PosY", "PosZ" });
});
var subcontainer2 = container.GenerateSubcontainer(1);
var valuetext = inspector.GenerateParameterText(this, subcontainer2, "value:", nameof(PreviewValue), true);
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
var interferometerButton = inspector.GenerateButton(this, subcontainer2, "Interferometer", () =>
{
Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(), new List<string>(), true,
this, InterferomType.Additive, Vector3.zero);
});
InspectorBuilder.For(this)
.Section("Displacement")
.Button("Position X", () => insp.GenerateCompositeParameterWindow(this, "Position X", nameof(positionX)).SetAsFlexibleFloat())
.Button("Position Y", () => insp.GenerateCompositeParameterWindow(this, "Position Y", nameof(positionY)).SetAsFlexibleFloat())
.Button("Position Z", () => insp.GenerateCompositeParameterWindow(this, "Position Z", nameof(positionZ)).SetAsFlexibleFloat())
.Button("GraphicEditor", () => insp.GenerateGraphicalFlexibleFloatWindow(this, "Displacement",
new FlexibleFloat[] { positionX, positionY, positionZ }, new string[] { "PosX", "PosY", "PosZ" }))
.ParameterText(nameof(PreviewValue), "value:", autoUpdate: true)
.Span(3)
.Button("Interferometer", () => Vector3Interferometer.GenerateElement("New Vector3 Interferometer",
Guid.NewGuid(), new List<string>(), true, this, InterferomType.Additive, Vector3.zero))
.Span(3)
.Build();
}
}
}

View File

@@ -8,32 +8,35 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
IHaveInspection inspection = inspectorMain;
var container = inspector.GenerateContainer("Look At");
var effectSettings = container.GenerateSubcontainer(2);
var connectedGameElementInputField = inspector.GenerateInputField(effectSettings, "Try Get Element");
var connectGameElementButton = inspector.GenerateButton(this, effectSettings, "Connect Game Element", () =>
{
GameElement targetElement = EditorManager.instance.beatmapContainer.gameElementList
.First(e => e.elementName == connectedGameElementInputField.GetValue<string>());
var nameRef = new ElementRef<DynamicUIInputField>();
if (targetElement == null)
{
LogWindow.Log("Game Element not found.", Color.yellow);
}
lookAtObject = targetElement;
inspectorMain.SetInspector(this);
});
string ShowConnection() => lookAtObject == null ? "No Game Element Connected" : "Connected With: " + lookAtObject.elementName;
var connectHintText = inspector.GenerateHintText(this, effectSettings, ShowConnection);
var enablingButton = inspector.GenerateButton(this, effectSettings, "Enabling", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Enabling", nameof(enabling)).SetAsFlexibleBool();
});
InspectorBuilder.For(this)
.Section("Look At")
.UnboundInputField("Try Get Element").WithRef(nameRef)
.Button("Connect Game Element", () =>
{
GameElement found = EditorManager.instance.beatmapContainer.gameElementList
.FirstOrDefault(e => e.elementName == nameRef.Value?.GetValue<string>());
if (found == null)
{
LogWindow.Log("Game Element not found.", Color.yellow);
return;
}
lookAtObject = found;
inspectorMain.SetInspector(this);
})
.HintText(() => lookAtObject == null
? "No Game Element Connected"
: "Connected With: " + lookAtObject.elementName)
.Button("Enabling", () =>
{
inspection.GenerateCompositeParameterWindow(this, "Enabling", nameof(enabling))
.SetAsFlexibleBool();
})
.Build();
}
}
}

View File

@@ -10,35 +10,22 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Scale");
var subcontainer = container.GenerateSubcontainer(3);
var scaleXButton = inspector.GenerateButton(this, subcontainer, "Scale X", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Scale X", nameof(scaleX)).SetAsFlexibleFloat();
});
var scaleYButton = inspector.GenerateButton(this, subcontainer, "Scale Y", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Scale Y", nameof(scaleY)).SetAsFlexibleFloat();
});
var scaleZButton = inspector.GenerateButton(this, subcontainer, "Scale Z", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Scale Z", nameof(scaleZ)).SetAsFlexibleFloat();
});
var graphicEditor = inspector.GenerateButton(this, subcontainer, "GraphicEditor", () =>
{
inspector.GenerateGraphicalFlexibleFloatWindow(this, "Scale",
new FlexibleFloat[] { scaleX, scaleY, scaleZ },
new string[] { "ScaleX", "ScaleY", "ScaleZ" });
});
var subcontainer2 = container.GenerateSubcontainer(1);
var valuetext = inspector.GenerateParameterText(this, subcontainer2, "value:", nameof(PreviewValue), true);
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
var interferometerButton = inspector.GenerateButton(this, subcontainer2, "Interferometer", () =>
{
Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(), new List<string>(), true,
this, InterferomType.Additive, Vector3.zero);
});
InspectorBuilder.For(this)
.Section("Scale")
.Button("Scale X", () => insp.GenerateCompositeParameterWindow(this, "Scale X", nameof(scaleX)).SetAsFlexibleFloat())
.Button("Scale Y", () => insp.GenerateCompositeParameterWindow(this, "Scale Y", nameof(scaleY)).SetAsFlexibleFloat())
.Button("Scale Z", () => insp.GenerateCompositeParameterWindow(this, "Scale Z", nameof(scaleZ)).SetAsFlexibleFloat())
.Button("GraphicEditor", () => insp.GenerateGraphicalFlexibleFloatWindow(this, "Scale",
new FlexibleFloat[] { scaleX, scaleY, scaleZ },
new string[] { "ScaleX", "ScaleY", "ScaleZ" }))
.ParameterText(nameof(PreviewValue), "value:", autoUpdate: true)
.Span(3)
.Button("Interferometer", () => Vector3Interferometer.GenerateElement("New Vector3 Interferometer",
Guid.NewGuid(), new List<string>(), true, this, InterferomType.Additive, Vector3.zero))
.Span(3)
.Build();
}
}
}

View File

@@ -10,35 +10,22 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Swirl");
var subcontainer = container.GenerateSubcontainer(3);
var eulerAngleXButton = inspector.GenerateButton(this, subcontainer, "Euler Angle X", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Euler Angle X", nameof(eulerAngleX)).SetAsFlexibleFloat();
});
var eulerAngleYButton = inspector.GenerateButton(this, subcontainer, "Euler Angle Y", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Euler Angle Y", nameof(eulerAngleY)).SetAsFlexibleFloat();
});
var eulerAngleZButton = inspector.GenerateButton(this, subcontainer, "Euler Angle Z", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Euler Angle Z", nameof(eulerAngleZ)).SetAsFlexibleFloat();
});
var graphicEditor = inspector.GenerateButton(this, subcontainer, "GraphicEditor", () =>
{
inspector.GenerateGraphicalFlexibleFloatWindow(this, "Swirl",
new FlexibleFloat[] { eulerAngleX, eulerAngleY, eulerAngleZ },
new string[] { "EulerX", "EulerY", "EulerZ" });
});
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
var subcontainer2 = container.GenerateSubcontainer(1);
var valuetext = inspector.GenerateParameterText(this, subcontainer2, "value:", nameof(PreviewValue), true);
var interferometerButton = inspector.GenerateButton(this, subcontainer2, "Interferometer", () =>
{
Vector3Interferometer.GenerateElement("New Vector3 Interferometer", Guid.NewGuid(), new List<string>(), true,
this, InterferomType.Additive, Vector3.zero);
});
InspectorBuilder.For(this)
.Section("Swirl")
.Button("Euler Angle X", () => insp.GenerateCompositeParameterWindow(this, "Euler Angle X", nameof(eulerAngleX)).SetAsFlexibleFloat())
.Button("Euler Angle Y", () => insp.GenerateCompositeParameterWindow(this, "Euler Angle Y", nameof(eulerAngleY)).SetAsFlexibleFloat())
.Button("Euler Angle Z", () => insp.GenerateCompositeParameterWindow(this, "Euler Angle Z", nameof(eulerAngleZ)).SetAsFlexibleFloat())
.Button("GraphicEditor", () => insp.GenerateGraphicalFlexibleFloatWindow(this, "Swirl",
new FlexibleFloat[] { eulerAngleX, eulerAngleY, eulerAngleZ },
new string[] { "EulerX", "EulerY", "EulerZ" }))
.ParameterText(nameof(PreviewValue), "value:", autoUpdate: true)
.Span(3)
.Button("Interferometer", () => Vector3Interferometer.GenerateElement("New Vector3 Interferometer",
Guid.NewGuid(), new List<string>(), true, this, InterferomType.Additive, Vector3.zero))
.Span(3)
.Build();
}
}
}

View File

@@ -11,38 +11,57 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Color");
// ColorSubmodule 的 BaseColorPicker ↔ HsvDrawer 双向引用需要
// 直接操作控件实例,使用 RawSection 处理这一复杂交互
var builder = InspectorBuilder.For(this);
if ((attachedGameElement as IHaveColorSubmodule).haveBaseColor)
{
var subBase = container.GenerateSubcontainer(1, 280f);
var baseColor = inspector.GenerateBaseColorPicker(this, subBase, "Base Color", nameof(originalBaseColor));
baseColor.AddListenerFunction(Refresh);
var hsvDrawer = inspector.GenerateHsvDrawer(this, subBase, "HSV", nameof(originalBaseColor));
hsvDrawer.AddListenerFunction(Refresh);
baseColor.hsvDrawer = hsvDrawer;
hsvDrawer.baseColorPicker = baseColor;
if (attachedGameElement.childElementList.Exists(x => x is BaseColorChange))
builder.RawSection("Color", int.MaxValue, (insp, container) =>
{
baseColor.title.text += " (Occupied by Animation)";
baseColor.canvasGroup.interactable = false;
hsvDrawer.title.text += " (Occupied by Animation)";
hsvDrawer.gameObject.SetActive(false);
}
bool occupiedByAnimation = attachedGameElement.childElementList.Exists(x => x is BaseColorChange);
var subBase = container.GenerateSubcontainer(1, 280f);
var baseColor = insp.GenerateBaseColorPicker(this, subBase, "Base Color", nameof(originalBaseColor));
baseColor.AddListenerFunction(Refresh);
var hsvDrawer = insp.GenerateHsvDrawer(this, subBase, "HSV", nameof(originalBaseColor));
hsvDrawer.AddListenerFunction(Refresh);
// 双向引用
baseColor.hsvDrawer = hsvDrawer;
hsvDrawer.baseColorPicker = baseColor;
if (occupiedByAnimation)
{
baseColor.title.text += " (Occupied by Animation)";
baseColor.canvasGroup.interactable = false;
hsvDrawer.title.text += " (Occupied by Animation)";
hsvDrawer.gameObject.SetActive(false);
}
});
}
if ((attachedGameElement as IHaveColorSubmodule).haveEmissionColor)
{
var subEmission = container.GenerateSubcontainer(1, 320f);
var emissionColor = inspector.GenerateEmissionColorPicker(this, subEmission, "Emission Color",
nameof(emissionEnabled), nameof(originalEmissionColor), nameof(originalEmissionIntensity));
emissionColor.AddListenerFunction(Refresh);
if (attachedGameElement.childElementList.Exists(x => x is EmissionColorChange))
builder.RawSection("Emission", int.MaxValue, (insp, container) =>
{
emissionColor.title.text += " (Occupied by Animation)";
emissionColor.canvasGroup.interactable = false;
}
bool occupiedByAnimation = attachedGameElement.childElementList.Exists(x => x is EmissionColorChange);
var subEmission = container.GenerateSubcontainer(1, 320f);
var emissionColor = insp.GenerateEmissionColorPicker(this, subEmission, "Emission Color",
nameof(emissionEnabled), nameof(originalEmissionColor), nameof(originalEmissionIntensity));
emissionColor.AddListenerFunction(Refresh);
if (occupiedByAnimation)
{
emissionColor.title.text += " (Occupied by Animation)";
emissionColor.canvasGroup.interactable = false;
}
});
}
builder.Build();
}
}
}

View File

@@ -8,35 +8,38 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
foreach (var effect in effectCollection)
{
var container = inspector.GenerateContainer(effect.Key);
var subcontainer = container.GenerateSubcontainer(3);
var effectNameInputField = inspector.GenerateInputField(subcontainer, "Effect Name");
var addEffectButton = inspector.GenerateButton(this, subcontainer, "Add Effect", () =>
{
if (EffectCollection.TryGetValue(effectNameInputField.GetValue<string>(), out var factory))
{
EffectBase newEffect = factory.Invoke();
newEffect.attachedGameElement = attachedGameElement;
var list = effectCollection[effect.Key];
if (list.Count > 0)
var nameRef = new ElementRef<DynamicUIInputField>();
string effectKey = effect.Key;
InspectorBuilder.For(this)
.Section(effectKey)
.UnboundInputField("Effect Name").WithRef(nameRef)
.Button("Add Effect", () =>
{
var last = list[list.Count - 1];
newEffect.CopyParametersFrom(last);
}
list.Add(newEffect);
newEffect.AccommodatingList = list;
inspectorMain.SetInspector(attachedGameElement);
}
else
{
LogWindow.Log("Effect Type not found.", Color.yellow);
}
});
if (EffectCollection.TryGetValue(nameRef.Value?.GetValue<string>(), out var factory))
{
EffectBase newEffect = factory.Invoke();
newEffect.attachedGameElement = attachedGameElement;
var list = effectCollection[effectKey];
if (list.Count > 0)
{
var last = list[list.Count - 1];
newEffect.CopyParametersFrom(last);
}
list.Add(newEffect);
newEffect.AccommodatingList = list;
inspectorMain.SetInspector(attachedGameElement);
}
else
{
LogWindow.Log("Effect Type not found.", Color.yellow);
}
})
.Build();
foreach (var effectBase in effect.Value)
{

View File

@@ -1,5 +1,4 @@
using Ichni.Editor;
using UnityEngine;
namespace Ichni.RhythmGame
{
@@ -7,21 +6,30 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Time Duration");
var subcontainer = container.GenerateSubcontainer(3);
var overrideToggle = inspector.GenerateToggle(this, subcontainer, "Override Duration", nameof(isOverridingDuration));
var startTimeInputField = inspector.GenerateInputField(this, subcontainer, "Start Time", nameof(startTime));
var endTimeInputField = inspector.GenerateInputField(this, subcontainer, "End Time", nameof(endTime));
void SetInputFieldInteractable(bool interactable)
{
startTimeInputField.inputField.interactable = interactable;
endTimeInputField.inputField.interactable = interactable;
}
SetInputFieldInteractable(isOverridingDuration);
overrideToggle.AddListenerFunction(() => SetInputFieldInteractable(isOverridingDuration));
InspectorBuilder.For(this)
.Section("Time Duration")
.Toggle(nameof(isOverridingDuration), "Override Duration")
.OnChanged(() =>
{
var insp = EditorManager.instance.uiManager.inspector as IHaveInspection;
if (insp.MarkedElements.TryGetValue("tdStartTime", out var st))
{
st.canvasGroup.interactable = isOverridingDuration;
st.canvasGroup.alpha = isOverridingDuration ? 1f : 0.5f;
}
if (insp.MarkedElements.TryGetValue("tdEndTime", out var et))
{
et.canvasGroup.interactable = isOverridingDuration;
et.canvasGroup.alpha = isOverridingDuration ? 1f : 0.5f;
}
})
.InputField(nameof(startTime), "Start Time")
.EnabledIf(() => isOverridingDuration)
.Mark("tdStartTime")
.InputField(nameof(endTime), "End Time")
.EnabledIf(() => isOverridingDuration)
.Mark("tdEndTime")
.Build();
}
}
}

View File

@@ -7,33 +7,28 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var builder = InspectorBuilder.For(this)
.Section("Transform")
.Vector3Field(nameof(originalPosition), "Start Position")
.AutoUpdate().OnChanged(Refresh)
.Vector3Field(nameof(originalEulerAngles), "Start Rotation")
.AutoUpdate().OnChanged(Refresh)
.Vector3Field(nameof(originalScale), "Start Scale")
.AutoUpdate().OnChanged(Refresh)
.ParameterText(nameof(currentPosition), "Current Position", autoUpdate: true)
.Span(3)
.ParameterText(nameof(currentEulerAngles), "Current Rotation", autoUpdate: true)
.Span(3);
var container = inspector.GenerateContainer("Transform");
var subcontainer = container.GenerateSubcontainer(1);
var originalPosInputField =
inspector.GenerateVector3InputField(this, subcontainer, "Start Position", nameof(originalPosition), true);
var originalRotInputField =
inspector.GenerateVector3InputField(this, subcontainer, "Start Rotation", nameof(originalEulerAngles), true);
var originalScaleInputField =
inspector.GenerateVector3InputField(this, subcontainer, "Start Scale", nameof(originalScale), true);
var currentPosText =
inspector.GenerateParameterText(this, subcontainer, "Current Position", nameof(currentPosition), true);
var currentRotText =
inspector.GenerateParameterText(this, subcontainer, "Current Rotation", nameof(currentEulerAngles), true);
if (attachedGameElement is PathNode or Trail) // 如果是PathNode显示法线方向
if (attachedGameElement is PathNode or Trail)
{
var currentNormalText =
inspector.GenerateHintText(this, subcontainer, () => "Normal: " + attachedGameElement.transform.forward);
builder.HintText(() => "Normal: " + attachedGameElement.transform.forward)
.Span(3);
}
var currentScaleText =
inspector.GenerateParameterText(this, subcontainer, "Current Scale", nameof(currentScale), true);
originalPosInputField.AddListenerFunction(Refresh);
originalRotInputField.AddListenerFunction(Refresh);
originalScaleInputField.AddListenerFunction(Refresh);
builder.ParameterText(nameof(currentScale), "Current Scale", autoUpdate: true)
.Span(3)
.Build();
}
}
}

View File

@@ -20,45 +20,45 @@ namespace Ichni.RhythmGame
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Generate");
var builder = InspectorBuilder.For(this)
.Section("Generate")
.Button("Environment Object", () =>
TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(),
new List<string>(), true, this))
.Toggle(nameof(isStatic), "Is Static")
.OnChanged(() => gameObject.isStatic = isStatic)
.Preset(InspectorBuilder.TransformPreset)
.Section("Generate Animations")
.Button("Base Color Change", () =>
BaseColorChange.GenerateElement("New Base Color Change", Guid.NewGuid(), new List<string>(), true,
this,
new FlexibleFloat(new List<AnimatedFloat> { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.r, colorSubmodule.originalBaseColor.r, animationCurveType: AnimationCurveType.Linear) }),
new FlexibleFloat(new List<AnimatedFloat> { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.g, colorSubmodule.originalBaseColor.g, animationCurveType: AnimationCurveType.Linear) }),
new FlexibleFloat(new List<AnimatedFloat> { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.b, colorSubmodule.originalBaseColor.b, animationCurveType: AnimationCurveType.Linear) }),
new FlexibleFloat(new List<AnimatedFloat> { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.a, colorSubmodule.originalBaseColor.a, animationCurveType: AnimationCurveType.Linear) })
));
var objectSettings = container.GenerateSubcontainer(3);
var environmentObjectButton = inspector.GenerateButton(this, objectSettings, "Environment Object",
() => TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List<string>(),
true, this));
var isStaticToggle = inspector.GenerateToggle(this, objectSettings, "Is Static", nameof(isStatic))
.AddListenerFunction(() => gameObject.isStatic = isStatic);
StandardInspectionElement.GenerateForTransform(this, container); //关于有Transform的元素
var generateAnimation = container.GenerateSubcontainer(3);
var generateBaseColorChangeButton = inspector.GenerateButton(this, generateAnimation, "Base Color Change",
() => BaseColorChange.GenerateElement("New Base Color Change", Guid.NewGuid(), new List<string>(), true,
this,
new FlexibleFloat(new List<AnimatedFloat> { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.r, colorSubmodule.originalBaseColor.r, animationCurveType: AnimationCurveType.Linear) }),
new FlexibleFloat(new List<AnimatedFloat> { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.g, colorSubmodule.originalBaseColor.g, animationCurveType: AnimationCurveType.Linear) }),
new FlexibleFloat(new List<AnimatedFloat> { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.b, colorSubmodule.originalBaseColor.b, animationCurveType: AnimationCurveType.Linear) }),
new FlexibleFloat(new List<AnimatedFloat> { new AnimatedFloat(0f, 0.1f, colorSubmodule.originalBaseColor.a, colorSubmodule.originalBaseColor.a, animationCurveType: AnimationCurveType.Linear) })
));
if (haveEmissionColor)
{
var generateEmissionColorChangeButton = inspector.GenerateButton(this, generateAnimation, "Emission Color Change",
() => EmissionColorChange.GenerateElement("New Emission Color Change", Guid.NewGuid(), new List<string>(), true,
this, new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat()));
builder.Button("Emission Color Change", () =>
EmissionColorChange.GenerateElement("New Emission Color Change", Guid.NewGuid(),
new List<string>(), true, this,
new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat()));
}
var generatePropertyAnimationColor = inspector.GenerateButton(this, generateAnimation, "Property Animation Color",
() => PropertyAnimationColor.GenerateElement("New Property Animation Color", Guid.NewGuid(), new List<string>(), true,
this, this.GetType().FullName, "", new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat()));
var generatePropertyAnimationFloat = inspector.GenerateButton(this, generateAnimation, "Property Animation Float",
() => PropertyAnimationFloat.GenerateElement("New Property Animation Float", Guid.NewGuid(), new List<string>(), true,
this, this.GetType().FullName, "", new FlexibleFloat()));
var generatePropertyAnimationVector3 = inspector.GenerateButton(this, generateAnimation, "Property Animation Vector3",
() => PropertyAnimationVector3.GenerateElement("New Property Animation Vector3", Guid.NewGuid(), new List<string>(), true,
this, this.GetType().FullName, "", new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat()));
builder
.Button("Property Animation Color", () =>
PropertyAnimationColor.GenerateElement("New Property Animation Color", Guid.NewGuid(),
new List<string>(), true, this, GetType().FullName, "",
new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat()))
.Button("Property Animation Float", () =>
PropertyAnimationFloat.GenerateElement("New Property Animation Float", Guid.NewGuid(),
new List<string>(), true, this, GetType().FullName, "", new FlexibleFloat()))
.Button("Property Animation Vector3", () =>
PropertyAnimationVector3.GenerateElement("New Property Animation Vector3", Guid.NewGuid(),
new List<string>(), true, this, GetType().FullName, "",
new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat()))
.Build();
}
#endregion
}

View File

@@ -22,83 +22,71 @@ namespace Ichni.RhythmGame
#region [] Inspector GUI
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
base.SetUpInspector();
var container = inspector.GenerateContainer("Generate");
var generateBase = container.GenerateSubcontainer(3);
var folderButton = inspector.GenerateButton(this, generateBase, "Folder",
() => ElementFolder.GenerateElement("New Folder", Guid.NewGuid(), new List<string>(), true, this));
var trackButton = inspector.GenerateButton(this, generateBase, "Track",
() => Track.GenerateElement("New Track", Guid.NewGuid(), new List<string>(), true, this));
var cameraButton = inspector.GenerateButton(this, generateBase, "Camera",
() => GameCamera.GenerateElement("New Camera", Guid.NewGuid(), new List<string>(), true, this,
GameCamera.CameraViewType.Perspective, 60, 10));
var crossTrackPoint = inspector.GenerateButton(this, generateBase, "Cross Track Point",
() => CrossTrackPoint.GenerateElement("New Cross Track Point", Guid.NewGuid(), new List<string>(), true,
this, new FlexibleInt(), new FlexibleFloat()));
StandardInspectionElement.GenerateForTransform(this, container); // 关于有Transform的元素
var generateNote = container.GenerateSubcontainer(3);
var tapButton = inspector.GenerateButton(this, generateNote, "Tap",
() => Tap.GenerateElement("New Tap", Guid.NewGuid(), new List<string>(), true, this, 0f));
var stayButton = inspector.GenerateButton(this, generateNote, "Stay",
() => Stay.GenerateElement("New Stay", Guid.NewGuid(), new List<string>(), true, this, 0f));
var holdButton = inspector.GenerateButton(this, generateNote, "Hold",
() => Hold.GenerateElement("New Hold", Guid.NewGuid(), new List<string>(), true, this, 0f, 1f));
var flickButton = inspector.GenerateButton(this, generateNote, "Flick",
() => Flick.GenerateElement("New Flick", Guid.NewGuid(), new List<string>(), true, this, 0f,
new List<Vector2>()));
InspectorBuilder.For(this)
.Section("Generate", sectionOrder: 10)
.Button("Folder", () => ElementFolder.GenerateElement("New Folder", Guid.NewGuid(), new List<string>(), true, this))
.Button("Track", () => Track.GenerateElement("New Track", Guid.NewGuid(), new List<string>(), true, this))
.Button("Camera", () => GameCamera.GenerateElement("New Camera", Guid.NewGuid(), new List<string>(), true, this, GameCamera.CameraViewType.Perspective, 60, 10))
.Button("Cross Track Point", () => CrossTrackPoint.GenerateElement("New Cross Track Point", Guid.NewGuid(), new List<string>(), true, this, new FlexibleInt(), new FlexibleFloat()))
.Build();
var generateEnvironment = container.GenerateSubcontainer(3);
var environmentObjectButton = inspector.GenerateButton(this, generateEnvironment, "Environment Object",
() => TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List<string>(),
true, this));
var timeEffectsCollectionButton = inspector.GenerateButton(this, generateEnvironment, "Time Effects Collection",
() => TimeEffectsCollection.GenerateElement("New Time Effects Collection", Guid.NewGuid(),
new List<string>(), true, this, 0));
var generateParticleEmitterButton = inspector.GenerateButton(this, generateEnvironment, "Generate Particle Emitter", () =>
{
ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List<string>(), true,
this, "", "", false, 0, 1, ParticleSystemSimulationSpace.World,
10, 5, 1, 1, true, Vector3.zero);
});
var generateTools = container.GenerateSubcontainer(1);
inspector.GenerateButton(this, generateTools, "Time Shift Tool", () =>
{
GeneralSecondaryWindow timeShiftWindow = UnityEngine.Object.Instantiate(
EditorManager.instance.basePrefabs.generalSecondaryWindow,
EditorManager.instance.uiManager.WindowsCanvas.GetComponent<RectTransform>())
.GetComponent<GeneralSecondaryWindow>();
timeShiftWindow.Initialize("Time Shift Tool");
var windowContainer = timeShiftWindow.GenerateContainer("Settings");
InspectorBuilder.For(this)
.Section("Generate Elements", sectionOrder: 15)
.Preset(InspectorBuilder.TransformPreset)
.Section("Generate Notes", sectionOrder: 20)
.Button("Tap", () => Tap.GenerateElement("New Tap", Guid.NewGuid(), new List<string>(), true, this, 0f))
.Button("Stay", () => Stay.GenerateElement("New Stay", Guid.NewGuid(), new List<string>(), true, this, 0f))
.Button("Hold", () => Hold.GenerateElement("New Hold", Guid.NewGuid(), new List<string>(), true, this, 0f, 1f))
.Button("Flick", () => Flick.GenerateElement("New Flick", Guid.NewGuid(), new List<string>(), true, this, 0f, new List<Vector2>()))
.Section("Generate Environment", sectionOrder: 30)
.Button("Environment Object", () => TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List<string>(), true, this))
.Button("Time Effects Collection", () => TimeEffectsCollection.GenerateElement("New Time Effects Collection", Guid.NewGuid(),
new List<string>(), true, this, 0))
.Button("Particle Emitter", () =>
{
ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List<string>(), true,
this, "", "", false, 0, 1, ParticleSystemSimulationSpace.World,
10, 5, 1, 1, true, Vector3.zero);
})
var subBase = windowContainer.GenerateSubcontainer(3);
var affectNoteToggle = timeShiftWindow.GenerateToggle(subBase, "Affect Notes", true);
var offsetInput = timeShiftWindow.GenerateInputField(subBase, "Time Offset (seconds)", "0");
.Section("Tools", sectionOrder: 40)
.Button("Time Shift Tool", () =>
{
GeneralSecondaryWindow timeShiftWindow = UnityEngine.Object.Instantiate(
EditorManager.instance.basePrefabs.generalSecondaryWindow,
EditorManager.instance.uiManager.WindowsCanvas.GetComponent<RectTransform>())
.GetComponent<GeneralSecondaryWindow>();
var btnBase = windowContainer.GenerateSubcontainer(2);
timeShiftWindow.GenerateButton(btnBase, "Apply", () =>
{
if (float.TryParse(offsetInput.inputField.text, out float offset))
{
ApplyTimeShiftRecursive(affectNoteToggle.toggle.isOn, offset);
UnityEngine.Object.Destroy(timeShiftWindow.gameObject);
LogWindow.Log($"Time shifted by {offset}.", Color.green);
}
else
{
LogWindow.Log("Invalid number format!", Color.red);
}
});
timeShiftWindow.GenerateButton(btnBase, "Cancel", () =>
{
UnityEngine.Object.Destroy(timeShiftWindow.gameObject);
});
});
timeShiftWindow.Initialize("Time Shift Tool");
var windowContainer = timeShiftWindow.GenerateContainer("Settings");
var subBase = windowContainer.GenerateSubcontainer(3);
var affectNoteToggle = timeShiftWindow.GenerateToggle(subBase, "Affect Notes", true);
var offsetInput = timeShiftWindow.GenerateInputField(subBase, "Time Offset (seconds)", "0");
var btnBase = windowContainer.GenerateSubcontainer(2);
timeShiftWindow.GenerateButton(btnBase, "Apply", () =>
{
if (float.TryParse(offsetInput.inputField.text, out float offset))
{
ApplyTimeShiftRecursive(affectNoteToggle.toggle.isOn, offset);
UnityEngine.Object.Destroy(timeShiftWindow.gameObject);
LogWindow.Log($"Time shifted by {offset}.", Color.green);
}
else
{
LogWindow.Log("Invalid number format!", Color.red);
}
});
timeShiftWindow.GenerateButton(btnBase, "Cancel", () =>
{
UnityEngine.Object.Destroy(timeShiftWindow.gameObject);
});
})
.Span(3)
.Build();
}
#endregion

View File

@@ -18,12 +18,13 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
base.SetUpInspector();
var container = inspector.GenerateContainer("Settings");
var settingsSubcontainer = container.GenerateSubcontainer(3);
var farClipRangeButton = inspector.GenerateInputField(this, settingsSubcontainer, "Far Clip Range",
nameof(farClipRange)).AddListenerFunction(ApplyExtension);
InspectorBuilder.For(this)
.Section("Settings")
.InputField(nameof(farClipRange), "Far Clip Range")
.OnChanged(ApplyExtension)
.Build();
}
#endregion
}

View File

@@ -18,21 +18,22 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
base.SetUpInspector();
var container = inspector.GenerateContainer("Generate");
StandardInspectionElement.GenerateForTransform(this, container); //关于有Transform的元素
var generateAnimation = container.GenerateSubcontainer(3);
var fovAnimationButton = inspector.GenerateButton(this, generateAnimation, "Field of View",
() => CameraFieldOfView.GenerateElement("New Field of View", Guid.NewGuid(),
new List<string>(), true, this, new FlexibleFloat(new List<AnimatedFloat>
{
new AnimatedFloat(0f, 1f, 60f, 60f, AnimationCurveType.Linear)
})));
var extensionButton = inspector.GenerateButton(this, generateAnimation, "Extension",
() => GameCameraExtension.GenerateElement("New Extension", Guid.NewGuid(),
new List<string>(), true, this, 1000f));
InspectorBuilder.For(this)
.Section("Generate Elements")
.Preset(InspectorBuilder.TransformPreset)
.Section("Generate")
.Button("Field of View", () =>
CameraFieldOfView.GenerateElement("New Field of View", Guid.NewGuid(),
new List<string>(), true, this, new FlexibleFloat(new List<AnimatedFloat>
{
new AnimatedFloat(0f, 1f, 60f, 60f, AnimationCurveType.Linear)
})))
.Button("Extension", () =>
GameCameraExtension.GenerateElement("New Extension", Guid.NewGuid(),
new List<string>(), true, this, 1000f))
.Build();
}
#endregion

View File

@@ -101,41 +101,31 @@ namespace Ichni.RhythmGame
public virtual void SetUpInspector()
{
ScanAndAddEnableTypes();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Element Info");
var info = container.GenerateSubcontainer(3);
var nameInputField = inspector.GenerateInputField(this, info, GetType().Name + "'s Name", nameof(elementName));
var guidText = inspector.GenerateParameterText(this, info, "Element GUID", nameof(elementGuid));
var tagsListButton = inspector.GenerateButton(this, info, "Tags List", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Tags List", nameof(tags)).SetAsStringList();
});
if (enableTypes != null && enableTypes.Count > 0)
{
var elcontainer = inspector.GenerateContainer("Enable Children Display");
var enableTypeContainer = elcontainer.GenerateSubcontainer(3);
var type = enableTypes.GetType().GetGenericArguments()[0];
int elcount = 0;
for (int idx = 0; idx < enableTypes.Count; idx++)
{
elcount++;
if (elcount > 3)
// Element Info
InspectorBuilder.For(this)
.Section("Element Info", sectionOrder: 0)
.InputField(nameof(elementName), GetType().Name + "'s Name")
.ParameterText(nameof(elementGuid), "Element GUID")
.Button("Tags List", () =>
{
elcount = 0;
enableTypeContainer = elcontainer.GenerateSubcontainer(3);
}
var et = enableTypes[idx];
inspector.GenerateToggle(
et,
enableTypeContainer,
et.type.Name,
nameof(et.enable)
);
}
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
insp.GenerateCompositeParameterWindow(this, "Tags List", nameof(tags)).SetAsStringList();
})
.Build();
// Enable Children Display — 每个 Toggle 绑定不同 EnableType 实例
if (enableTypes is { Count: > 0 })
{
var enableBuilder = InspectorBuilder.For(this)
.Section("Enable Children Display", sectionOrder: 1);
enableBuilder.ForEach(enableTypes, (b, et, i) =>
{
b.Toggle(nameof(EnableType.enable), et.type.Name).BoundTo(et);
});
enableBuilder.Build();
}
foreach (var submodule in submoduleList)
{
submodule.SetUpInspector();

View File

@@ -1,11 +1,11 @@
using System;
using System.Collections.Generic;
using Ichni.Editor; // 仅限于在Editor中处理Inspector
using Ichni.Editor;
using UnityEngine;
namespace Ichni.RhythmGame
{
public partial class TemporaryObject // Editor UI Setup Partial
public partial class TemporaryObject
{
public List<string> themeBundleList;
public List<string> objectNameList;
@@ -13,42 +13,30 @@ namespace Ichni.RhythmGame
#region [Inspector面版定制] Override Inspector UI Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Temporary Object");
// 生成实体
var generate = container.GenerateSubcontainer(3);
var themeBundleDropdown =
inspector.GenerateDropdown(this, generate, "Theme Bundle", themeBundleList, nameof(themeBundleName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
if (themeBundleName != String.Empty && ThemeBundleManager.instance.TryGetThemeBundle(themeBundleName, out ThemeBundle themeBundle))
{
objectNameList = themeBundle.assetList_GameObject.ConvertAll(x => x.name);
var objectNameDropdown =
inspector.GenerateDropdown(this, generate, "Object Name", objectNameList, nameof(objectName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
}
else
{
var objectNameDropdown =
inspector.GenerateDropdown(this, generate, "Object Name", new List<string>(), nameof(objectName));
objectNameDropdown.dropdown.interactable = false;
} // 如果没有选择主题包,则物体名称下拉框不可用
bool hasThemeBundle = themeBundleName != String.Empty;
ThemeBundle themeBundle = null;
if (hasThemeBundle)
hasThemeBundle = ThemeBundleManager.instance.TryGetThemeBundle(themeBundleName, out themeBundle);
objectNameList = hasThemeBundle ? themeBundle.assetList_GameObject.ConvertAll(x => x.name) : new List<string>();
var generateButton = inspector.GenerateButton(this, generate, "Generate", () =>
{
EditorManager.instance.operationManager.CopyPasteDeleteModule.DeleteElement(this);
inspectorMain.ClearInspector();
SubstantialObject.GenerateElement(elementName, elementGuid, tags, true, themeBundleName, objectName, parentElement);
});
if (themeBundleName == String.Empty || objectName == String.Empty)
{
generateButton.button.interactable = false;
}
InspectorBuilder.For(this)
.Section("Temporary Object")
.Dropdown(nameof(themeBundleName), themeBundleList, "Theme Bundle")
.OnChanged(() => inspectorMain.SetInspector(this))
.Dropdown(nameof(objectName), objectNameList, "Object Name")
.EnabledIf(() => hasThemeBundle)
.OnChanged(() => inspectorMain.SetInspector(this))
.Button("Generate", () =>
{
EditorManager.instance.operationManager.CopyPasteDeleteModule.DeleteElement(this);
inspectorMain.ClearInspector();
SubstantialObject.GenerateElement(elementName, elementGuid, tags, true,
themeBundleName, objectName, parentElement);
})
.EnabledIf(() => themeBundleName != String.Empty && objectName != String.Empty)
.Build();
}
#endregion
}

View File

@@ -16,24 +16,18 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Variables Container");
var subcontainer = container.GenerateSubcontainer(3);
var originalVariablesButton = inspector.GenerateButton(this, subcontainer, "Original Variables", () =>
{
var ov =
inspector.GenerateCompositeParameterWindow(this, "Original Variables List", nameof(originalVariables))
.SetAsStringIntDictionary()
.AddListenerFunction(RevertAllVariables);
});
var currentVariablesButton = inspector.GenerateButton(this, subcontainer, "Current Variables", () =>
{
var cv =
inspector.GenerateCompositeParameterWindow(this, "Current Variables List", nameof(currentVariables))
.SetAsStringIntDictionary();
});
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("Variables Container")
.Button("Original Variables", () =>
insp.GenerateCompositeParameterWindow(this, "Original Variables List", nameof(originalVariables))
.SetAsStringIntDictionary()
.AddListenerFunction(RevertAllVariables))
.Button("Current Variables", () =>
insp.GenerateCompositeParameterWindow(this, "Current Variables List", nameof(currentVariables))
.SetAsStringIntDictionary())
.Build();
}
#endregion
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
namespace Ichni.RhythmGame
{
@@ -9,17 +6,15 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Bloom Shake");
var effectSettings = container.GenerateSubcontainer(3);
var effectTimeField = inspector.GenerateInputField(this, effectSettings, "Bloom Time", nameof(effectTime));
var bloomPeakField = inspector.GenerateInputField(this, effectSettings, "Bloom Peak", nameof(peak));
var intensityCurveButton = inspector.GenerateButton(this, effectSettings, "Intensity Curve", () =>
{
var intensityCurveWindow =
inspector.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve();
});
SetRemove(effectSettings);
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("Bloom Shake")
.InputField(nameof(effectTime), "Bloom Time")
.InputField(nameof(peak), "Bloom Peak")
.Button("Intensity Curve", () => insp.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve())
.Button("Remove", () => { nowEffectState = EffectState.Before; AccommodatingList.Remove(this); EditorManager.instance.uiManager.inspector.SetInspector(attachedGameElement); })
.Build();
}
}
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
namespace Ichni.RhythmGame
{
@@ -9,19 +6,15 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Camera Tilt");
var subcontainer1 = container.GenerateSubcontainer(3);
var durationField = inspector.GenerateInputField(this, subcontainer1, "Duration", nameof(effectTime));
var curveButton = inspector.GenerateButton(this, subcontainer1, "Offset Curve", () =>
{
var intensityCurveWindow =
inspector.GenerateCompositeParameterWindow(this, "Offset Curve", nameof(offsetCurve)).SetAsCustomCurve();
});
var subcontainer2 = container.GenerateSubcontainer(1);
var offsetPeakField = inspector.GenerateVector3InputField(this, subcontainer2, "Offset Value", nameof(offsetValue));
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
SetRemove(subcontainer2);
InspectorBuilder.For(this)
.Section("Camera Offset")
.InputField(nameof(effectTime), "Duration")
.Button("Offset Curve", () => insp.GenerateCompositeParameterWindow(this, "Offset Curve", nameof(offsetCurve)).SetAsCustomCurve())
.Vector3Field(nameof(offsetValue), "Offset Value")
.Button("Remove", () => { nowEffectState = EffectState.Before; AccommodatingList.Remove(this); EditorManager.instance.uiManager.inspector.SetInspector(attachedGameElement); })
.Build();
}
}
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
namespace Ichni.RhythmGame
{
@@ -9,15 +6,15 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Camera Shake");
var effectSettings = container.GenerateSubcontainer(3);
var durationInputField = inspector.GenerateInputField(this, effectSettings, "Effect Time", nameof(effectTime));
var frequencyInputField = inspector.GenerateInputField(this, effectSettings, "Frequency", nameof(frequency));
var amplitudeXInputField = inspector.GenerateInputField(this, effectSettings, "Amplitude X", nameof(amplitudeX));
var amplitudeYInputField = inspector.GenerateInputField(this, effectSettings, "Amplitude Y", nameof(amplitudeY));
var amplitudeZInputField = inspector.GenerateInputField(this, effectSettings, "Amplitude Z", nameof(amplitudeZ));
SetRemove(effectSettings);
InspectorBuilder.For(this)
.Section("Camera Shake")
.InputField(nameof(effectTime), "Effect Time")
.InputField(nameof(frequency), "Frequency")
.InputField(nameof(amplitudeX), "Amplitude X")
.InputField(nameof(amplitudeY), "Amplitude Y")
.InputField(nameof(amplitudeZ), "Amplitude Z")
.Button("Remove", () => { nowEffectState = EffectState.Before; AccommodatingList.Remove(this); EditorManager.instance.uiManager.inspector.SetInspector(attachedGameElement); })
.Build();
}
}
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
namespace Ichni.RhythmGame
{
@@ -9,20 +6,15 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Camera Tilt");
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
var subcontainer1 = container.GenerateSubcontainer(3);
var durationField = inspector.GenerateInputField(this, subcontainer1, "Duration", nameof(effectTime));
var tiltCurveButton = inspector.GenerateButton(this, subcontainer1, "Tilt Curve", () =>
{
var intensityCurveWindow =
inspector.GenerateCompositeParameterWindow(this, "Tilt Curve", nameof(tiltCurve)).SetAsCustomCurve();
});
var subcontainer2 = container.GenerateSubcontainer(1);
var tiltValueField = inspector.GenerateVector3InputField(this, subcontainer2, "Tilt Value", nameof(tiltValue));
SetRemove(subcontainer2);
InspectorBuilder.For(this)
.Section("Camera Tilt")
.InputField(nameof(effectTime), "Duration")
.Button("Tilt Curve", () => insp.GenerateCompositeParameterWindow(this, "Tilt Curve", nameof(tiltCurve)).SetAsCustomCurve())
.Vector3Field(nameof(tiltValue), "Tilt Value")
.Button("Remove", () => { nowEffectState = EffectState.Before; AccommodatingList.Remove(this); EditorManager.instance.uiManager.inspector.SetInspector(attachedGameElement); })
.Build();
}
}
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
namespace Ichni.RhythmGame
{
@@ -9,17 +6,15 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Camera Zoom");
var effectSettings = container.GenerateSubcontainer(3);
var zoomDurationInputField = inspector.GenerateInputField(this, effectSettings, "Zoom Duration", nameof(effectTime));
var relativeZoomInputField = inspector.GenerateInputField(this, effectSettings, "Relative Zoom", nameof(relativeZoom));
var zoomCurveButton = inspector.GenerateButton(this, effectSettings, "Intensity Curve", () =>
{
var zoomCurveWindow =
inspector.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(zoomCurve)).SetAsCustomCurve();
});
SetRemove(effectSettings);
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("Camera Zoom")
.InputField(nameof(effectTime), "Zoom Duration")
.InputField(nameof(relativeZoom), "Relative Zoom")
.Button("Intensity Curve", () => insp.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(zoomCurve)).SetAsCustomCurve())
.Button("Remove", () => { nowEffectState = EffectState.Before; AccommodatingList.Remove(this); EditorManager.instance.uiManager.inspector.SetInspector(attachedGameElement); })
.Build();
}
}
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
namespace Ichni.RhythmGame
{
@@ -9,17 +6,15 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Chromatic Aberration");
var effectSettings = container.GenerateSubcontainer(3);
var effectTimeField = inspector.GenerateInputField(this, effectSettings, "Duration", nameof(effectTime));
var bloomPeakField = inspector.GenerateInputField(this, effectSettings, "Peak Value", nameof(peak));
var intensityCurveButton = inspector.GenerateButton(this, effectSettings, "Intensity Curve", () =>
{
var intensityCurveWindow =
inspector.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve();
});
SetRemove(effectSettings);
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("Chromatic Aberration")
.InputField(nameof(effectTime), "Duration")
.InputField(nameof(peak), "Peak Value")
.Button("Intensity Curve", () => insp.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve())
.Button("Remove", () => { nowEffectState = EffectState.Before; AccommodatingList.Remove(this); EditorManager.instance.uiManager.inspector.SetInspector(attachedGameElement); })
.Build();
}
}
}

View File

@@ -11,37 +11,40 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Enable Control");
var effectSettings = container.GenerateSubcontainer(3);
var connectedGameElementInputField = inspector.GenerateInputField(effectSettings, "Game Element Name");
var connectGameElementButton = inspector.GenerateButton(this, effectSettings, "Connect Game Element", () =>
{
connectedGameElement = EditorManager.instance.beatmapContainer.gameElementList
.First(e => e.elementName == connectedGameElementInputField.GetValue<string>());
var nameRef = new ElementRef<DynamicUIInputField>();
if (connectedGameElement == null)
{
LogWindow.Log("Game Element not found.", Color.red);
}
inspectorMain.SetInspector(connectedGameElement);
});
string ShowConnection() => connectedGameElement == null ? "No Game Element Connected" : "Connected With: " + connectedGameElement.elementName;
var connectHintText = inspector.GenerateHintText(this, effectSettings, ShowConnection);
var connectedVariableNameInputField = inspector.GenerateInputField(this, effectSettings, "Connected Variable Name", nameof(connectedVariableName));
var enableValueInputField = inspector.GenerateInputField(this, effectSettings, "Enable Value", nameof(enableValue));
// 自定义表达式暂时不可用
var useExpressionToggle = inspector.GenerateToggle(this, effectSettings, "Use Expression", nameof(useExpression));
useExpressionToggle.toggle.interactable = false;
var expressionInputField = inspector.GenerateInputField(this, effectSettings, "Expression", nameof(expression));
expressionInputField.inputField.interactable = false;
SetRemove(effectSettings);
InspectorBuilder.For(this)
.Section("Enable Control")
.UnboundInputField("Game Element Name").WithRef(nameRef)
.Button("Connect Game Element", () =>
{
connectedGameElement = EditorManager.instance.beatmapContainer.gameElementList
.FirstOrDefault(e => e.elementName == nameRef.Value?.GetValue<string>());
if (connectedGameElement == null)
{
LogWindow.Log("Game Element not found.", Color.red);
return;
}
inspectorMain.SetInspector(connectedGameElement);
})
.HintText(() => connectedGameElement == null
? "No Game Element Connected"
: "Connected With: " + connectedGameElement.elementName)
.InputField(nameof(connectedVariableName), "Connected Variable Name")
.InputField(nameof(enableValue), "Enable Value")
.Toggle(nameof(useExpression), "Use Expression")
.EnabledIf(() => false)
.InputField(nameof(expression), "Expression")
.EnabledIf(() => false)
.Button("Remove", () =>
{
nowEffectState = EffectState.Before;
AccommodatingList.Remove(this);
inspectorMain.SetInspector(attachedGameElement);
})
.Build();
}
}
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
namespace Ichni.RhythmGame
{
@@ -9,18 +6,16 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("High Pass Filter");
var effectSettings = container.GenerateSubcontainer(3);
var effectTimeField = inspector.GenerateInputField(this, effectSettings, "EffectTime", nameof(effectTime));
var bloomPeakField = inspector.GenerateInputField(this, effectSettings, "Bottom", nameof(peak));
var useEQToggle = inspector.GenerateToggle(this, effectSettings, "Use EQ", nameof(useEQ));
var intensityCurveButton = inspector.GenerateButton(this, effectSettings, "Intensity Curve", () =>
{
var intensityCurveWindow =
inspector.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve();
});
SetRemove(effectSettings);
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("High Pass Filter")
.InputField(nameof(effectTime), "EffectTime")
.InputField(nameof(peak), "Bottom")
.Toggle(nameof(useEQ), "Use EQ")
.Button("Intensity Curve", () => insp.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve())
.Button("Remove", () => { nowEffectState = EffectState.Before; AccommodatingList.Remove(this); EditorManager.instance.uiManager.inspector.SetInspector(attachedGameElement); })
.Build();
}
}
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
namespace Ichni.RhythmGame
{
@@ -9,18 +6,16 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Low Pass Filter");
var effectSettings = container.GenerateSubcontainer(3);
var effectTimeField = inspector.GenerateInputField(this, effectSettings, "Duration", nameof(effectTime));
var bloomPeakField = inspector.GenerateInputField(this, effectSettings, "Bottom", nameof(bottom));
var useEQToggle = inspector.GenerateToggle(this, effectSettings, "Use EQ", nameof(useEQ));
var intensityCurveButton = inspector.GenerateButton(this, effectSettings, "Intensity Curve", () =>
{
var intensityCurveWindow =
inspector.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve();
});
SetRemove(effectSettings);
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("Low Pass Filter")
.InputField(nameof(effectTime), "Duration")
.InputField(nameof(bottom), "Bottom")
.Toggle(nameof(useEQ), "Use EQ")
.Button("Intensity Curve", () => insp.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve())
.Button("Remove", () => { nowEffectState = EffectState.Before; AccommodatingList.Remove(this); EditorManager.instance.uiManager.inspector.SetInspector(attachedGameElement); })
.Build();
}
}
}

View File

@@ -20,69 +20,49 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Particle Tracker");
// 确保 themeBundleList 初始化
if (themeBundleList == null)
themeBundleList = ThemeBundleManager.instance.loadedThemeBundleList.ConvertAll(x => x.themeBundleName);
DynamicUISubcontainer particleSettings0 = container.GenerateSubcontainer(3);
inspector.GenerateToggle(this, particleSettings0, "Prewarm", nameof(prewarm))
.AddListenerFunction(() => particlesContainer.SetPrewarm(prewarm));
inspector.GenerateInputField(this, particleSettings0, "Play Time", nameof(playTime));
inspector.GenerateInputField(this, particleSettings0, "Stop Time", nameof(stopTime));
bool hasThemeBundle = themeBundleName != String.Empty;
ThemeBundle themeBundle = null;
if (hasThemeBundle)
hasThemeBundle = ThemeBundleManager.instance.TryGetThemeBundle(themeBundleName, out themeBundle);
materialNameList = hasThemeBundle ? themeBundle.assetList_Material.ConvertAll(x => x.name) : new List<string>();
DynamicUISubcontainer particleSettings2 = container.GenerateSubcontainer(3);
inspector.GenerateDropdown(this, particleSettings2, "Simulation Space", typeof(UnityEngine.ParticleSystemSimulationSpace), nameof(simulationSpace))
.AddListenerFunction(() => particlesContainer.SetSimulationSpace(simulationSpace));
inspector.GenerateInputField(this, particleSettings2, "Density", nameof(density))
.AddListenerFunction(() => particlesContainer.SetDensity(density));
inspector.GenerateInputField(this, particleSettings2, "Life Time", nameof(lifeTime))
.AddListenerFunction(() => particlesContainer.SetLifeTime(lifeTime));
inspector.GenerateInputField(this, particleSettings2, "Speed", nameof(speed))
.AddListenerFunction(() => particlesContainer.SetSpeed(speed));
inspector.GenerateInputField(this, particleSettings2, "Radius", nameof(radius))
.AddListenerFunction(() => particlesContainer.SetRadius(radius));
DynamicUISubcontainer particleSettings3_0 = container.GenerateSubcontainer(3);
inspector.GenerateToggle(this, particleSettings3_0, "Is Auto Orient", nameof(isAutoOrient))
.AddListenerFunction(() => particlesContainer.SetAlignment(isAutoOrient, particleRotation));
DynamicUISubcontainer particleSettings3_1 = container.GenerateSubcontainer(1);
inspector.GenerateVector3InputField(this, particleSettings3_1, "Particle Rotation", nameof(particleRotation))
.AddListenerFunction(() => particlesContainer.SetParticleRotation(particleRotation));
DynamicUISubcontainer materialSettings = container.GenerateSubcontainer(3);
var themeBundleDropdown =
inspector.GenerateDropdown(this, materialSettings, "Theme Bundle", themeBundleList, nameof(themeBundleName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
if (themeBundleName != String.Empty && ThemeBundleManager.instance.TryGetThemeBundle(themeBundleName, out ThemeBundle themeBundle))
{
materialNameList = themeBundle.assetList_Material.ConvertAll(x => x.name);
var objectNameDropdown =
inspector.GenerateDropdown(this, materialSettings, "Material Name", materialNameList, nameof(materialName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
}
else
{
materialNameList = new List<string>(); // 防止为null
var objectNameDropdown =
inspector.GenerateDropdown(this, materialSettings, "Material Name", materialNameList, nameof(materialName));
objectNameDropdown.dropdown.interactable = false;
} // 如果没有选择主题包,则材质名称下拉框不可用
var setMaterialButton = inspector.GenerateButton(this, materialSettings, "Set Material", () =>
{
particlesContainer.SetParticleMaterial(themeBundleName, materialName);
});
if (themeBundleName == String.Empty || materialName == String.Empty)
{
setMaterialButton.button.interactable = false;
}
InspectorBuilder.For(this)
.Section("Particle Tracker")
.Toggle(nameof(prewarm), "Prewarm")
.OnChanged(() => particlesContainer.SetPrewarm(prewarm))
.InputField(nameof(playTime), "Play Time")
.InputField(nameof(stopTime), "Stop Time")
.Section("Physics")
.Dropdown(nameof(simulationSpace), typeof(UnityEngine.ParticleSystemSimulationSpace), "Simulation Space")
.OnChanged(() => particlesContainer.SetSimulationSpace(simulationSpace))
.InputField(nameof(density), "Density")
.OnChanged(() => particlesContainer.SetDensity(density))
.InputField(nameof(lifeTime), "Life Time")
.OnChanged(() => particlesContainer.SetLifeTime(lifeTime))
.InputField(nameof(speed), "Speed")
.OnChanged(() => particlesContainer.SetSpeed(speed))
.InputField(nameof(radius), "Radius")
.OnChanged(() => particlesContainer.SetRadius(radius))
.Section("Orientation")
.Toggle(nameof(isAutoOrient), "Is Auto Orient")
.OnChanged(() => particlesContainer.SetAlignment(isAutoOrient, particleRotation))
.Vector3Field(nameof(particleRotation), "Particle Rotation")
.OnChanged(() => particlesContainer.SetParticleRotation(particleRotation))
.Section("Material")
.Dropdown(nameof(themeBundleName), themeBundleList, "Theme Bundle")
.OnChanged(() => inspectorMain.SetInspector(this))
.Dropdown(nameof(materialName), materialNameList, "Material Name")
.EnabledIf(() => hasThemeBundle)
.OnChanged(() => inspectorMain.SetInspector(this))
.Button("Set Material", () =>
particlesContainer.SetParticleMaterial(themeBundleName, materialName))
.EnabledIf(() => themeBundleName != String.Empty && materialName != String.Empty)
.Build();
}
#endregion
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
namespace Ichni.RhythmGame
{
@@ -9,23 +6,17 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Pixelate Effect");
var effectSettings = container.GenerateSubcontainer(3);
var effectTimeField = inspector.GenerateInputField(this, effectSettings, "Effect Time", nameof(effectTime));
var bottomXField = inspector.GenerateInputField(this, effectSettings, "Bottom X", nameof(bottomX));
var bottomYField = inspector.GenerateInputField(this, effectSettings, "Bottom Y", nameof(bottomY));
var intensityCurveButton = inspector.GenerateButton(this, effectSettings, "Intensity Curve", () =>
{
var intensityCurveWindow =
inspector.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve();
});
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
var clearButton = inspector.GenerateButton(this, effectSettings, "Clear Pixelate", () =>
{
Recover();
});
SetRemove(effectSettings);
InspectorBuilder.For(this)
.Section("Pixelate Effect")
.InputField(nameof(effectTime), "Effect Time")
.InputField(nameof(bottomX), "Bottom X")
.InputField(nameof(bottomY), "Bottom Y")
.Button("Intensity Curve", () => insp.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve())
.Button("Clear Pixelate", Recover)
.Button("Remove", () => { nowEffectState = EffectState.Before; AccommodatingList.Remove(this); EditorManager.instance.uiManager.inspector.SetInspector(attachedGameElement); })
.Build();
}
}
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
namespace Ichni.RhythmGame
{
@@ -9,18 +6,17 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Radial Blur Effect");
var effectSettings = container.GenerateSubcontainer(3);
inspector.GenerateInputField(this, effectSettings, "Effect Time", nameof(duration));
inspector.GenerateInputField(this, effectSettings, "Peak Intensity", nameof(peakIntensity));
inspector.GenerateInputField(this, effectSettings, "Radial Center X", nameof(radialCenterX));
inspector.GenerateInputField(this, effectSettings, "Radial Center Y", nameof(radialCenterY));
inspector.GenerateButton(this, effectSettings, "Intensity Curve", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve();
});
SetRemove(effectSettings);
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
InspectorBuilder.For(this)
.Section("Radial Blur Effect")
.InputField(nameof(duration), "Effect Time")
.InputField(nameof(peakIntensity), "Peak Intensity")
.InputField(nameof(radialCenterX), "Radial Center X")
.InputField(nameof(radialCenterY), "Radial Center Y")
.Button("Intensity Curve", () => insp.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve())
.Button("Remove", () => { nowEffectState = EffectState.Before; AccommodatingList.Remove(this); EditorManager.instance.uiManager.inspector.SetInspector(attachedGameElement); })
.Build();
}
}
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
namespace Ichni.RhythmGame
{
@@ -9,15 +6,15 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Set Integer");
var effectSettings = container.GenerateSubcontainer(3);
var targetVariableNameInputField = inspector.GenerateInputField(this, effectSettings, "Target Variable Name", nameof(targetVariableName));
var targetValueInputField = inspector.GenerateInputField(this, effectSettings, "Target Value", nameof(targetValue));
var isRandomToggle = inspector.GenerateToggle(this, effectSettings, "Is Random", nameof(isRandom));
var minValueInputField = inspector.GenerateInputField(this, effectSettings, "Min Value", nameof(minValue));
var maxValueInputField = inspector.GenerateInputField(this, effectSettings, "Max Value", nameof(maxValue));
SetRemove(effectSettings);
InspectorBuilder.For(this)
.Section("Set Integer")
.InputField(nameof(targetVariableName), "Target Variable Name")
.InputField(nameof(targetValue), "Target Value")
.Toggle(nameof(isRandom), "Is Random")
.InputField(nameof(minValue), "Min Value")
.InputField(nameof(maxValue), "Max Value")
.Button("Remove", () => { nowEffectState = EffectState.Before; AccommodatingList.Remove(this); EditorManager.instance.uiManager.inspector.SetInspector(attachedGameElement); })
.Build();
}
}
}

View File

@@ -1,5 +1,4 @@
using Ichni.Editor;
using UnityEngine;
namespace Ichni.RhythmGame
{
@@ -8,41 +7,23 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
IHaveInspection insp = 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);
// ColorBaseColorPicker含 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);
InspectorBuilder.For(this)
.Section("Speed Lines")
.InputField(nameof(effectTime), "Effect Time")
.Button("Intensity Curve", () => insp.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve())
.ColorPicker(nameof(color), "Color")
.InputField(nameof(peakRemap), "Peak Remap")
.InputField(nameof(speedLinesTiling), "Tiling")
.InputField(nameof(speedLinesRadialScale), "Radial Scale")
.InputField(nameof(speedLinesPower), "Power")
.InputField(nameof(speedLinesAnimation), "Animation Speed")
.InputField(nameof(maskScale), "Mask Scale")
.InputField(nameof(maskHardness), "Mask Hardness")
.InputField(nameof(maskPower), "Mask Power")
.Button("Remove", () => { nowEffectState = EffectState.Before; AccommodatingList.Remove(this); EditorManager.instance.uiManager.inspector.SetInspector(attachedGameElement); })
.Build();
}
#endregion
}

View File

@@ -21,11 +21,10 @@ namespace Ichni.RhythmGame
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Time Effects Collection");
var collectionSettings = container.GenerateSubcontainer(3);
var timeInputField = inspector.GenerateInputField(this, collectionSettings, "Time", nameof(time));
InspectorBuilder.For(this)
.Section("Time Effects Collection")
.InputField(nameof(time), "Time")
.Build();
}
#endregion
}

View File

@@ -1,7 +1,4 @@
using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
namespace Ichni.RhythmGame
{
@@ -9,21 +6,17 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Vignette");
var effectSettings = container.GenerateSubcontainer(3);
var durationField = inspector.GenerateInputField(this, effectSettings, "Duration", nameof(effectTime));
var peakField = inspector.GenerateInputField(this, effectSettings, "Peak Value", nameof(peak));
var smoothnessField = inspector.GenerateInputField(this, effectSettings, "Smoothness", nameof(smoothness));
var intensityCurveButton = inspector.GenerateButton(this, effectSettings, "Intensity Curve", () =>
{
var intensityCurveWindow =
inspector.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve();
});
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
var colorSettings = container.GenerateSubcontainer(1, 280f);
var colorField = inspector.GenerateBaseColorPicker(this, colorSettings, "Color", nameof(color));
SetRemove(effectSettings);
InspectorBuilder.For(this)
.Section("Vignette")
.InputField(nameof(effectTime), "Duration")
.InputField(nameof(peak), "Peak Value")
.InputField(nameof(smoothness), "Smoothness")
.Button("Intensity Curve", () => insp.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve())
.ColorPicker(nameof(color), "Color")
.Button("Remove", () => { nowEffectState = EffectState.Before; AccommodatingList.Remove(this); EditorManager.instance.uiManager.inspector.SetInspector(attachedGameElement); })
.Build();
}
}
}

View File

@@ -17,7 +17,6 @@ namespace Ichni.RhythmGame
#endregion
#region [(Editor专用)] Editor Property Caches
// 新增:用于在 Inspector 中显示的列表数据
[HideInInspector] private List<string> themeBundleListForSelection;
[HideInInspector] private List<string> skyboxNameListForSelection;
#endregion
@@ -34,77 +33,67 @@ namespace Ichni.RhythmGame
skyboxNameListForSelection = themeBundle.assetList_Material.ConvertAll(x => x.name);
}
}
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector; // 引用主检查器用于刷新
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Background Setter");
var backgroundSettings = container.GenerateSubcontainer(3);
// 1. 开关
var useSkyboxToggle = inspector.GenerateToggle(this, backgroundSettings, "Use Skybox", nameof(useSkybox));
// 刷新可选列表
UpdateSelectionLists();
bool hasSkyboxBundle = !string.IsNullOrEmpty(skyboxThemeBundleName) && skyboxNameListForSelection.Count > 0;
// 2. 天空盒资源包下拉框 (同步 SkyboxSubsetter 逻辑)
var themeDropdown = inspector.GenerateDropdown(this, backgroundSettings, "Skybox Theme Bundle",
themeBundleListForSelection, nameof(skyboxThemeBundleName));
themeDropdown.AddListenerFunction(() =>
{
UpdateSelectionLists();
inspectorMain.SetInspector(this); // 选择包后刷新 UI 以加载材质列表
});
// 3. 天空盒材质下拉框 (同步 SkyboxSubsetter 逻辑)
var materialDropdown = inspector.GenerateDropdown(this, backgroundSettings, "Skybox Material",
skyboxNameListForSelection, nameof(skyboxMaterialName));
if (string.IsNullOrEmpty(skyboxThemeBundleName) || skyboxNameListForSelection.Count == 0)
{
materialDropdown.dropdown.interactable = false;
}
// 4. 背景图片输入框 (保持原样)
var backgroundSpriteField = inspector.GenerateInputField(this, backgroundSettings, "Background Sprite", nameof(backgroundSpriteName));
// 5. 应用按钮
var applyButton = inspector.GenerateButton(this, backgroundSettings, "Apply", Refresh);
// 控制交互性
void SetInputFields(bool value)
{
themeDropdown.dropdown.interactable = value;
materialDropdown.dropdown.interactable = value && !string.IsNullOrEmpty(skyboxThemeBundleName);
backgroundSpriteField.inputField.interactable = !value;
}
SetInputFields(useSkybox);
useSkyboxToggle.AddListenerFunction(() =>
{
EditorManager.instance.backgroundController.EnableBackground(!useSkybox);
SetInputFields(useSkybox);
});
// 生成 Skybox Subsetter 的按钮部分
var generateContainer = inspector.GenerateContainer("Advanced Controls");
var generateSubContainer = generateContainer.GenerateSubcontainer(3);
inspector.GenerateButton(this, generateSubContainer, "Create Skybox Controller", () =>
{
if (skyboxSubsetter == null)
// 使用 RawSection 处理 Toggle ↔ Dropdown 交互性联动
InspectorBuilder.For(this)
.RawSection("Background Setter", int.MaxValue, (insp, container) =>
{
SkyboxSubsetter.GenerateElement("New Skybox Subsetter", Guid.NewGuid(), new List<string>(), true, this,
new List<string>(), new List<string>(), new List<float>(), new List<float>());
}
else
{
LogWindow.Log("There is already a Skybox Subsetter in the scene.", Color.yellow);
}
});
var settings = container.GenerateSubcontainer(3);
var useSkyboxToggle = insp.GenerateToggle(this, settings, "Use Skybox", nameof(useSkybox));
var themeDropdown = insp.GenerateDropdown(this, settings, "Skybox Theme Bundle",
themeBundleListForSelection, nameof(skyboxThemeBundleName));
themeDropdown.AddListenerFunction(() =>
{
UpdateSelectionLists();
inspectorMain.SetInspector(this);
});
var materialDropdown = insp.GenerateDropdown(this, settings, "Skybox Material",
skyboxNameListForSelection, nameof(skyboxMaterialName));
if (!hasSkyboxBundle)
materialDropdown.dropdown.interactable = false;
var bgSpriteField = insp.GenerateInputField(this, settings, "Background Sprite", nameof(backgroundSpriteName));
var applyButton = insp.GenerateButton(this, settings, "Apply", Refresh);
// 初始化交互性
void SetInputFields(bool skyboxEnabled)
{
themeDropdown.dropdown.interactable = skyboxEnabled;
materialDropdown.dropdown.interactable = skyboxEnabled && !string.IsNullOrEmpty(skyboxThemeBundleName);
bgSpriteField.inputField.interactable = !skyboxEnabled;
}
SetInputFields(useSkybox);
useSkyboxToggle.AddListenerFunction(() =>
{
EditorManager.instance.backgroundController.EnableBackground(!useSkybox);
SetInputFields(useSkybox);
});
})
.Section("Advanced Controls")
.Button("Create Skybox Controller", () =>
{
if (skyboxSubsetter == null)
{
SkyboxSubsetter.GenerateElement("New Skybox Subsetter", Guid.NewGuid(),
new List<string>(), true, this,
new List<string>(), new List<string>(), new List<float>(), new List<float>());
}
else
{
LogWindow.Log("There is already a Skybox Subsetter in the scene.", Color.yellow);
}
})
.Build();
}
#endregion
}

View File

@@ -19,130 +19,123 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
IHaveInspection inspection = inspectorMain;
var container = inspector.GenerateContainer("Skybox Subsetter");
DynamicUISubcontainer mainSettings = container.GenerateSubcontainer(3);
var blendSpeedListButton = inspector.GenerateButton(this, mainSettings, "Blend Speed List", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Blend Speed List", nameof(blendSpeedList))
.SetAsFloatList();
});
var blendTimeListButton = inspector.GenerateButton(this, mainSettings, "Blend Time List", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Blend Time List", nameof(blendTimeList))
.SetAsFloatList();
});
DynamicUISubcontainer materialSettings = container.GenerateSubcontainer(3);
for (int i = 0; i < (skyBoxThemeBundleList?.Count ?? 0); i++)
{
try
// SkyboxSubsetter 的 UI 包含:
// 1. 两个按钮打开 CompositeParameterWindow (blendSpeed/blendTime)
// 2. 一个动态循环,为每个已有天空盒生成编辑行
// 3. 底部的 "Add Skybox" 条件 Dropdown + 按钮
// 使用 RawSection 处理动态循环部分
InspectorBuilder.For(this)
.RawSection("Skybox Subsetter", int.MaxValue, (insp, container) =>
{
DynamicUISubcontainer Textsettings = container.GenerateSubcontainer(3);
// 安全访问元素:检查索引是否在所有列表的有效范围内
string bundleName = i < skyBoxThemeBundleList.Count ? skyBoxThemeBundleList[i] : "<Missing Bundle>";
string name = i < skyboxNameList.Count ? skyboxNameList[i] : "<Missing Name>";
if (i > 0)
var mainSettings = container.GenerateSubcontainer(3);
insp.GenerateButton(this, mainSettings, "Blend Speed List", () =>
{
inspector.GenerateInputField(this, Textsettings, "Time", $"{nameof(blendTimeList)}.{i - 1}");
inspector.GenerateInputField(this, Textsettings, "Speed", $"{nameof(blendSpeedList)}.{i - 1}");
}
else
insp.GenerateCompositeParameterWindow(this, "Blend Speed List", nameof(blendSpeedList))
.SetAsFloatList();
});
insp.GenerateButton(this, mainSettings, "Blend Time List", () =>
{
inspector.GenerateHintText(this, Textsettings, "The First");
inspector.GenerateHintText(this, Textsettings, "0");
}
insp.GenerateCompositeParameterWindow(this, "Blend Time List", nameof(blendTimeList))
.SetAsFloatList();
});
inspector.GenerateHintText(this, Textsettings, $"{i + 1}. {name}");
inspector.GenerateDropdown(this, Textsettings, "B", themeBundleListForSelection, $"{nameof(skyBoxThemeBundleList)}.{i}")
.AddListenerFunction(() => inspectorMain.SetInspector(this));
List<string> skyboxNameListForSelection = new List<string>();
string selectedThemeBundleL = skyBoxThemeBundleList[i];
if (selectedThemeBundleL != String.Empty && ThemeBundleManager.instance.TryGetThemeBundle(selectedThemeBundleL, out ThemeBundle themeBundleLoop))
{
skyboxNameListForSelection = themeBundleLoop.assetList_Material.ConvertAll(x => x.name);
var objectNameDropdown =
inspector.GenerateDropdown(this, Textsettings, "Material Name", skyboxNameListForSelection, $"{nameof(skyboxNameList)}.{i}")
.AddListenerFunction(() => inspectorMain.SetInspector(this))
.AddListenerFunction(RefreshSkyboxes);
}
// 创建局部变量解决闭包问题
int index = i;
inspector.GenerateButton(this, Textsettings, "Remove Skybox", () =>
// 动态循环:已有天空盒列表
for (int i = 0; i < (skyBoxThemeBundleList?.Count ?? 0); i++)
{
try
{
// 移除前检查所有列表的索引有效性
if (index < skyBoxThemeBundleList.Count)
skyBoxThemeBundleList.RemoveAt(index);
else
Debug.LogError($"Cannot remove: skyBoxThemeBundleList index {index} out of range");
var textSettings = container.GenerateSubcontainer(3);
string bundleName = i < skyBoxThemeBundleList.Count ? skyBoxThemeBundleList[i] : "<Missing Bundle>";
string skyboxName = i < skyboxNameList.Count ? skyboxNameList[i] : "<Missing Name>";
if (index < skyboxNameList.Count)
skyboxNameList.RemoveAt(index);
if (i > 0)
{
insp.GenerateInputField(this, textSettings, "Time", $"{nameof(blendTimeList)}.{i - 1}");
insp.GenerateInputField(this, textSettings, "Speed", $"{nameof(blendSpeedList)}.{i - 1}");
}
else
Debug.LogError($"Cannot remove: skyboxNameList index {index} out of range");
{
insp.GenerateHintText(this, textSettings, "The First");
insp.GenerateHintText(this, textSettings, "0");
}
if (index < skyboxMaterialList.Count)
skyboxMaterialList.RemoveAt(index);
else
Debug.LogError($"Cannot remove: skyboxMaterialList index {index} out of range");
insp.GenerateHintText(this, textSettings, $"{i + 1}. {skyboxName}");
if (index < skyboxBlender.skyboxMaterials.Count)
skyboxBlender.skyboxMaterials.RemoveAt(index);
else
Debug.LogError($"Cannot remove: skyboxMaterials index {index} out of range");
insp.GenerateDropdown(this, textSettings, "B", themeBundleListForSelection,
$"{nameof(skyBoxThemeBundleList)}.{i}")
.AddListenerFunction(() => inspectorMain.SetInspector(this));
inspectorMain.SetInspector(this);
string selectedBundle = skyBoxThemeBundleList[i];
if (selectedBundle != String.Empty
&& ThemeBundleManager.instance.TryGetThemeBundle(selectedBundle, out ThemeBundle tbLoop))
{
var matList = tbLoop.assetList_Material.ConvertAll(x => x.name);
insp.GenerateDropdown(this, textSettings, "Material Name", matList,
$"{nameof(skyboxNameList)}.{i}")
.AddListenerFunction(() => inspectorMain.SetInspector(this))
.AddListenerFunction(RefreshSkyboxes);
}
int index = i;
insp.GenerateButton(this, textSettings, "Remove Skybox", () =>
{
try
{
if (index < skyBoxThemeBundleList.Count)
skyBoxThemeBundleList.RemoveAt(index);
if (index < skyboxNameList.Count)
skyboxNameList.RemoveAt(index);
if (index < skyboxMaterialList.Count)
skyboxMaterialList.RemoveAt(index);
if (index < skyboxBlender.skyboxMaterials.Count)
skyboxBlender.skyboxMaterials.RemoveAt(index);
inspectorMain.SetInspector(this);
}
catch (Exception ex)
{
Debug.LogError($"Error during removal: {ex.Message}");
}
});
}
catch (Exception ex)
{
Debug.LogError($"Error during removal: {ex.Message}");
Debug.LogError($"Error generating UI for index {i}: {ex.Message}");
}
});
}
catch (Exception ex)
{
Debug.LogError($"Error generating UI for index {i}: {ex.Message}");
}
}
}
var themeBundleDropdown =
inspector.GenerateDropdown(this, materialSettings, "Theme Bundle", themeBundleListForSelection, nameof(selectedThemeBundle))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
if (selectedThemeBundle != String.Empty && ThemeBundleManager.instance.TryGetThemeBundle(selectedThemeBundle, out ThemeBundle themeBundle))
{
skyboxNameListForSelection = themeBundle.assetList_Material.ConvertAll(x => x.name);
var objectNameDropdown =
inspector.GenerateDropdown(this, materialSettings, "Material Name", skyboxNameListForSelection, nameof(selectedSkybox))
// 底部:添加天空盒的条件 Dropdown
var materialSettings = container.GenerateSubcontainer(3);
insp.GenerateDropdown(this, materialSettings, "Theme Bundle", themeBundleListForSelection,
nameof(selectedThemeBundle))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
}
else
{
var objectNameDropdown =
inspector.GenerateDropdown(this, materialSettings, "Material Name", new List<string>(), nameof(selectedSkybox));
objectNameDropdown.dropdown.interactable = false;
} // 如果没有选择主题包,则材质名称下拉框不可用
var setMaterialButton = inspector.GenerateButton(this, materialSettings, "Add Skybox", () =>
{
AddSkybox(selectedThemeBundle, selectedSkybox);
inspectorMain.SetInspector(this);
});
if (selectedThemeBundle != String.Empty
&& ThemeBundleManager.instance.TryGetThemeBundle(selectedThemeBundle, out ThemeBundle tb))
{
skyboxNameListForSelection = tb.assetList_Material.ConvertAll(x => x.name);
insp.GenerateDropdown(this, materialSettings, "Material Name", skyboxNameListForSelection,
nameof(selectedSkybox))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
}
else
{
var emptyDropdown = insp.GenerateDropdown(this, materialSettings, "Material Name",
new List<string>(), nameof(selectedSkybox));
emptyDropdown.dropdown.interactable = false;
}
if (selectedThemeBundle == String.Empty || selectedSkybox == String.Empty)
{
setMaterialButton.button.interactable = false;
}
var addButton = insp.GenerateButton(this, materialSettings, "Add Skybox", () =>
{
AddSkybox(selectedThemeBundle, selectedSkybox);
inspectorMain.SetInspector(this);
});
if (selectedThemeBundle == String.Empty || selectedSkybox == String.Empty)
addButton.button.interactable = false;
})
.Build();
}
#endregion
}

View File

@@ -17,37 +17,34 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Audio Submodule");
var submoduleSettings = container.GenerateSubcontainer(3);
var generalJudgeAudioListButton = inspector.GenerateButton(this, submoduleSettings, "General Judge", () =>
{
inspector.GenerateCompositeParameterWindow(this, "General Judge Sound List", nameof(generalJudgeAudioList)).SetAsStringList();
});
var perfectAudioListButton = inspector.GenerateButton(this, submoduleSettings, "Perfect", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Perfect Sound List", nameof(perfectAudioList)).SetAsStringList();
});
var goodAudioListButton = inspector.GenerateButton(this, submoduleSettings, "Good", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Good Sound List", nameof(goodAudioList)).SetAsStringList();
});
var badAudioListButton = inspector.GenerateButton(this, submoduleSettings, "Bad", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Bad Sound List", nameof(badAudioList)).SetAsStringList();
});
var missAudioListButton = inspector.GenerateButton(this, submoduleSettings, "Miss", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Miss Sound List", nameof(missAudioList)).SetAsStringList();
});
IHaveInspection inspection = EditorManager.instance.uiManager.inspector;
var builder = InspectorBuilder.For(this)
.Section("Audio Submodule")
.Button("General Judge", () =>
inspection.GenerateCompositeParameterWindow(this, "General Judge Sound List",
nameof(generalJudgeAudioList)).SetAsStringList())
.Button("Perfect", () =>
inspection.GenerateCompositeParameterWindow(this, "Perfect Sound List",
nameof(perfectAudioList)).SetAsStringList())
.Button("Good", () =>
inspection.GenerateCompositeParameterWindow(this, "Good Sound List",
nameof(goodAudioList)).SetAsStringList())
.Button("Bad", () =>
inspection.GenerateCompositeParameterWindow(this, "Bad Sound List",
nameof(badAudioList)).SetAsStringList())
.Button("Miss", () =>
inspection.GenerateCompositeParameterWindow(this, "Miss Sound List",
nameof(missAudioList)).SetAsStringList());
if (note is Hold)
{
var holdStartAudioListButton = inspector.GenerateButton(this, submoduleSettings, "Hold Start", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Hold Start Sound List", nameof(holdStartAudioList)).SetAsStringList();
});
builder.Button("Hold Start", () =>
inspection.GenerateCompositeParameterWindow(this, "Hold Start Sound List",
nameof(holdStartAudioList)).SetAsStringList());
}
builder.Build();
}
#endregion
}

View File

@@ -6,20 +6,17 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Full Screen Near Time Judge Unit");
var judgeModuleSettings = container.GenerateSubcontainer(3);
var isShowingJudgeField =
inspector.GenerateToggle(this, judgeModuleSettings, "Is Showing Judge", nameof(isShowingJudge))
.AddListenerFunction(() => SetShowingJudge(isShowingJudge));
var removeButton = inspector.GenerateButton(this, judgeModuleSettings, "Remove", () =>
{
SetShowingJudge(false);
note.noteJudgeSubmodule.judgeUnitList.Remove(this);
inspectorMain.SetInspector(note);
});
InspectorBuilder.For(this)
.Section("Full Screen Near Time Judge Unit")
.Toggle(nameof(isShowingJudge), "Is Showing Judge")
.OnChanged(() => SetShowingJudge(isShowingJudge))
.Button("Remove", () =>
{
SetShowingJudge(false);
note.noteJudgeSubmodule.judgeUnitList.Remove(this);
EditorManager.instance.uiManager.inspector.SetInspector(note);
})
.Build();
}
}
}

View File

@@ -18,17 +18,19 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Judge Submodule");
var submoduleSettings = container.GenerateSubcontainer(3);
var effectNameInputField = inspector.GenerateInputField(submoduleSettings, "Judge Unit Name");
var addJudgeUnitButton = inspector.GenerateButton(this, submoduleSettings, "Add Judge Unit",
() =>
{
AddJudgeUnit(effectNameInputField.GetValue<string>());
inspectorMain.SetInspector(note);
});
var nameRef = new ElementRef<DynamicUIInputField>();
InspectorBuilder.For(this)
.Section("Judge Submodule")
.UnboundInputField("Judge Unit Name").WithRef(nameRef)
.Button("Add Judge Unit", () =>
{
AddJudgeUnit(nameRef.Value?.GetValue<string>());
inspectorMain.SetInspector(note);
})
.Build();
foreach (var judgeUnit in judgeUnitList)
{

View File

@@ -6,21 +6,18 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Touch Area Judge Unit");
var judgeModuleSettings = container.GenerateSubcontainer(3);
var isShowingJudgeField =
inspector.GenerateToggle(this, judgeModuleSettings, "Is Showing Judge", nameof(isShowingJudge))
.AddListenerFunction(() => SetShowingJudge(isShowingJudge));
var areaRadiusField = inspector.GenerateInputField(this, judgeModuleSettings, "Area Radius", nameof(areaRadius));
var removeButton = inspector.GenerateButton(this, judgeModuleSettings, "Remove", () =>
{
SetShowingJudge(false);
note.noteJudgeSubmodule.judgeUnitList.Remove(this);
inspectorMain.SetInspector(note);
});
InspectorBuilder.For(this)
.Section("Touch Area Judge Unit")
.Toggle(nameof(isShowingJudge), "Is Showing Judge")
.OnChanged(() => SetShowingJudge(isShowingJudge))
.InputField(nameof(areaRadius), "Area Radius")
.Button("Remove", () =>
{
SetShowingJudge(false);
note.noteJudgeSubmodule.judgeUnitList.Remove(this);
EditorManager.instance.uiManager.inspector.SetInspector(note);
})
.Build();
}
}
}

View File

@@ -6,37 +6,36 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Trigger Connect Judge Unit");
var judgeModuleSettings = container.GenerateSubcontainer(3);
var isShowingJudgeField =
inspector.GenerateToggle(this, judgeModuleSettings, "Is Showing Judge", nameof(isShowingJudge))
.AddListenerFunction(() => SetShowingJudge(isShowingJudge));
var triggerNameField = inspector.GenerateInputField(judgeModuleSettings, "Trigger Name");
var connectTriggerButton = inspector.GenerateButton(this, judgeModuleSettings, "Connect Trigger", () =>
{
GameElement trigger = EditorManager.instance.operationManager.FindingModule.FindGameElementByName(triggerNameField.GetValue<string>());
if (trigger is not IHaveNoteJudgeTriggerSubmodule)
{
LogWindow.Log("The element you are trying to connect is not a Note Judge Trigger.");
return;
}
connectedJudgeTrigger = trigger;
(trigger as IHaveNoteJudgeTriggerSubmodule).noteJudgeTriggerSubmodule.connectedNotes.Add(note);
});
var removeButton = inspector.GenerateButton(this, judgeModuleSettings, "Remove", () =>
{
SetShowingJudge(false);
note.noteJudgeSubmodule.judgeUnitList.Remove(this);
inspectorMain.SetInspector(note);
});
var nameRef = new ElementRef<DynamicUIInputField>();
InspectorBuilder.For(this)
.Section("Trigger Connect Judge Unit")
.Toggle(nameof(isShowingJudge), "Is Showing Judge")
.OnChanged(() => SetShowingJudge(isShowingJudge))
.UnboundInputField("Trigger Name").WithRef(nameRef)
.Button("Connect Trigger", () =>
{
GameElement trigger = EditorManager.instance.operationManager.FindingModule
.FindGameElementByName(nameRef.Value?.GetValue<string>());
if (trigger is not IHaveNoteJudgeTriggerSubmodule)
{
LogWindow.Log("The element you are trying to connect is not a Note Judge Trigger.");
return;
}
connectedJudgeTrigger = trigger;
(trigger as IHaveNoteJudgeTriggerSubmodule).noteJudgeTriggerSubmodule.connectedNotes.Add(note);
})
.Button("Remove", () =>
{
SetShowingJudge(false);
note.noteJudgeSubmodule.judgeUnitList.Remove(this);
inspectorMain.SetInspector(note);
})
.Build();
}
}
}

View File

@@ -20,16 +20,13 @@ namespace Ichni.RhythmGame
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
var flickSpecial = inspector.GenerateContainer("Flick Special");
var flickSpecialSubcontainer = flickSpecial.GenerateSubcontainer(3);
var availableDirectionsButton =
inspector.GenerateButton(this, flickSpecialSubcontainer, "Available Directions", () =>
{
var widthCurveWindow = inspector.GenerateCompositeParameterWindow(this, "Available Directions", nameof(availableFlickDirections));
widthCurveWindow.SetAsFlexibleFloat();
});
InspectorBuilder.For(this)
.Section("Flick Special")
.Button("Available Directions", () =>
insp.GenerateCompositeParameterWindow(this, "Available Directions", nameof(availableFlickDirections)).SetAsFlexibleFloat())
.Build();
}
#endregion
}

View File

@@ -18,42 +18,56 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var holdSpecial = inspector.GenerateContainer("Hold");
var holdSpecialSubcontainer = holdSpecial.GenerateSubcontainer(3);
var holdEndTimeInputField = inspector.GenerateInputField(this, holdSpecialSubcontainer, "holdEndTime", nameof(holdEndTime), true);
var holdingTimeInputField = inspector.GenerateInputField(holdSpecialSubcontainer, "holdingTime", (holdEndTime - exactJudgeTime).ToString());
holdEndTimeInputField.AddListenerFunction(() =>
{
holdingTimeInputField.inputField.text = (holdEndTime - exactJudgeTime).ToString();
noteVisual?.effectSubmodule.effectCollection["Holding"].ForEach(effect =>
{
effect.effectTime = holdEndTime - exactJudgeTime;
});
});
holdingTimeInputField.AddListenerFunction(() =>
{
holdEndTime = float.Parse(holdingTimeInputField.inputField.text) + exactJudgeTime;
holdEndTimeInputField.inputField.text = holdEndTime.ToString();
holdEndTimeInputField.inputField.onEndEdit.Invoke(holdEndTimeInputField.inputField.text);
});
inspector.MarkedElements["ExactJudgeTime"].AddListenerFunction(() =>
{
noteVisual?.effectSubmodule.effectCollection["Holding"].ForEach(effect =>
{
effect.effectTime = holdEndTime - exactJudgeTime;
});
// Hold 需要 holdEndTime 和 holdingTime 的双向联动,
// 以及监听 base 创建的 MarkedElement["ExactJudgeTime"]。
// 使用 RawSection 处理这些复杂交互。
var holdEndRef = new ElementRef<DynamicUIInputField>();
var holdingRef = new ElementRef<DynamicUIInputField>();
float holdingTimeValue;
if (float.TryParse(holdingTimeInputField.inputField.text, out holdingTimeValue))
InspectorBuilder.For(this)
.RawSection("Hold", int.MaxValue, (insp, container) =>
{
holdEndTime = exactJudgeTime + holdingTimeValue;
holdEndTimeInputField.inputField.text = holdEndTime.ToString();
}
var sub = container.GenerateSubcontainer(3);
var holdEndTimeField = insp.GenerateInputField(this, sub, "holdEndTime", nameof(holdEndTime), true);
var holdingTimeField = insp.GenerateInputField(sub, "holdingTime", (holdEndTime - exactJudgeTime).ToString());
});
holdEndTimeField.AddListenerFunction(() =>
{
holdingTimeField.inputField.text = (holdEndTime - exactJudgeTime).ToString();
noteVisual?.effectSubmodule.effectCollection["Holding"].ForEach(effect =>
{
effect.effectTime = holdEndTime - exactJudgeTime;
});
});
holdingTimeField.AddListenerFunction(() =>
{
holdEndTime = float.Parse(holdingTimeField.inputField.text) + exactJudgeTime;
holdEndTimeField.inputField.text = holdEndTime.ToString();
holdEndTimeField.inputField.onEndEdit.Invoke(holdEndTimeField.inputField.text);
});
// 监听 base.SetUpInspector 创建的 ExactJudgeTime MarkedElement
if (insp.MarkedElements.TryGetValue("ExactJudgeTime", out var exactJudgeElem))
{
exactJudgeElem.AddListenerFunction(() =>
{
noteVisual?.effectSubmodule.effectCollection["Holding"].ForEach(effect =>
{
effect.effectTime = holdEndTime - exactJudgeTime;
});
if (float.TryParse(holdingTimeField.inputField.text, out float holdingTimeValue))
{
holdEndTime = exactJudgeTime + holdingTimeValue;
holdEndTimeField.inputField.text = holdEndTime.ToString();
}
});
}
})
.Build();
}
#endregion
}

View File

@@ -39,52 +39,46 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
// 不调用 base.SetUpInspector() —— 手动控制 Element Info 和子模块顺序
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Element Info");
//基础信息
var info = container.GenerateSubcontainer(3);
var nameInputField = inspector.GenerateInputField(this, info, GetType().Name + "'s Name", nameof(elementName));
var guidText = inspector.GenerateParameterText(this, info, "Element GUID", nameof(elementGuid));
var tagsListButton = inspector.GenerateButton(this, info, "Tags List", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Tags List", nameof(tags)).SetAsStringList();
});
InspectorBuilder.For(this)
.Section("Element Info", sectionOrder: 0)
.InputField(nameof(elementName), GetType().Name + "'s Name")
.ParameterText(nameof(elementGuid), "Element GUID")
.Button("Tags List", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Tags List", nameof(tags)).SetAsStringList();
})
.Build();
if (noteVisual != null)
{
noteVisual.transformSubmodule.SetUpInspector();
}
//次级模块
foreach (var submodule in submoduleList)
{
submodule.SetUpInspector();
}
//为了设置便捷Transform编辑手动更改原方法而不是用Base
var infoContainer = inspector.GenerateContainer("Note Info");
var noteBaseSettings = infoContainer.GenerateSubcontainer(3);
var exactJudgeTimeInputField =
inspector.GenerateInputField(this, noteBaseSettings, "exactJudgeTime", nameof(exactJudgeTime))
.AddListenerFunction(()=>UpdateNoteInTrack(CoreServices.TimeProvider.SongTime)).Mark("ExactJudgeTime");
var saveNotePrefabButton =
inspector.GenerateButton(this, noteBaseSettings, "Save Note Prefab", () =>
{
EditorManager.instance.projectManager.notePrefabManager.SaveNotePrefab(this, GetNoteTypeName(this) + "_Prefab");
});
var noteScreenPositionText = inspector.GenerateHintText(this, noteBaseSettings,
() => "Note Screen Position: " + noteScreenPosition);
var noteVisualContainer = inspector.GenerateContainer("Note Visual");
var noteVisualGeneration = noteVisualContainer.GenerateSubcontainer(3);
var generateNoteVisualButton = inspector.GenerateButton(this, noteVisualGeneration, "Generate Note Visual", () =>
{
TemporaryObject.GenerateElement("New Note Visual", Guid.NewGuid(), new List<string>(), true, this);
});
if (noteVisual != null)
{
generateNoteVisualButton.button.interactable = false;
}
InspectorBuilder.For(this)
.Section("Note Info")
.InputField(nameof(exactJudgeTime), "exactJudgeTime")
.OnChanged(() => UpdateNoteInTrack(CoreServices.TimeProvider.SongTime))
.Mark("ExactJudgeTime")
.Button("Save Note Prefab", () =>
{
EditorManager.instance.projectManager.notePrefabManager.SaveNotePrefab(this, GetNoteTypeName(this) + "_Prefab");
})
.HintText(() => "Note Screen Position: " + noteScreenPosition)
.Section("Note Visual")
.Button("Generate Note Visual", () =>
{
TemporaryObject.GenerateElement("New Note Visual", Guid.NewGuid(), new List<string>(), true, this);
})
.EnabledIf(() => noteVisual == null)
.Build();
}
#endregion
}

View File

@@ -12,15 +12,13 @@ namespace Ichni.RhythmGame
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Generate");
StandardInspectionElement.GenerateForTransform(this, container);
var settings = inspector.GenerateContainer("Settings");
var settingsSubcontainer = settings.GenerateSubcontainer(3);
var highlightToggle =
inspector.GenerateToggle(this, settingsSubcontainer, "Highlight", nameof(isHighlighted))
.AddListenerFunction(SetHighlight);
InspectorBuilder.For(this)
.Section("Generate Elements")
.Preset(InspectorBuilder.TransformPreset)
.Section("Settings")
.Toggle(nameof(isHighlighted), "Highlight")
.OnChanged(SetHighlight)
.Build();
}
#endregion

View File

@@ -24,17 +24,18 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.SetUpInspector();
// 呼叫流式特性打包器接管此类的所有常规属性!
DynamicUIAutoBuilder.AutoBuild(this, EditorManager.instance.uiManager.inspector);
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
// 保留极具复杂结构定制的骨骼生成方法
var container = inspector.GenerateContainer("Path Node Transformation");
StandardInspectionElement.GenerateForTransform(this, container);
InspectorBuilder.For(this)
.Section("Path Node")
.Toggle(nameof(isShowingSphere), "Is Showing Sphere")
.HintText(() => "Index: " + TrackIndex)
.Section("Path Node Animation")
.Button("Base Color Change", GenerateBaseColorChange)
.Section("Path Node Transformation")
.Preset(InspectorBuilder.TransformPreset)
.Build();
}
[DynamicUIButton("Base Color Change", Group = "Path Node Animation")]
public void GenerateBaseColorChange()
{
BaseColorChange.GenerateElement("New Base Color Change", Guid.NewGuid(), new List<string>(), true,

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame
{
@@ -21,44 +22,37 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
base.SetUpInspector();
var container = inspector.GenerateContainer("Cross Track Point");
var pointSettings = container.GenerateSubcontainer(3);
var trackSwitchButton = inspector.GenerateButton(this, pointSettings, "Track Switch", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Track Switch", nameof(trackSwitch)).SetAsFlexibleInt();
});
var trackPercentButton = inspector.GenerateButton(this, pointSettings, "Track Percent", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Track Percent", nameof(trackPercent)).SetAsFlexibleFloat();
});
var pasteTrackListButton = inspector.GenerateButton(this, pointSettings, "Paste Track List", PasteTrackList);
// 新增MotionAngles开关
var motionAnglesToggle = inspector.GenerateToggle(this, pointSettings, "Motion With Angles", nameof(MotionAngles));
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
var generation = container.GenerateSubcontainer(3);
var generateCameraButton = inspector.GenerateButton(this, generation, "Game Camera",
() => GameCamera.GenerateElement("New Game Camera", Guid.NewGuid(), new List<string>(),
true, this, GameCamera.CameraViewType.Perspective, 60, 10));
var generateTrailButton = inspector.GenerateButton(this, generation, "Trail",
() => Trail.GenerateElement("New Trail", Guid.NewGuid(), new List<string>(),
true, this, 1, true, 1,
UnityEngine.AnimationCurve.Constant(0, 1, 1), ColorExtensions.DefaultGradient(), "", ""));
var environmentObjectButton = inspector.GenerateButton(this, generation, "Environment Object",
() => TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List<string>(),
true, this));
var generateParticleEmitterButton = inspector.GenerateButton(this, generation, "Generate Particle Emitter", () =>
{
ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List<string>(), true,
this, "", "",false,0, 1, UnityEngine.ParticleSystemSimulationSpace.World,
10, 5, 1, 1 ,true, UnityEngine.Vector3.zero);
});
InspectorBuilder.For(this)
.Section("Cross Track Point")
.Button("Track Switch", () =>
insp.GenerateCompositeParameterWindow(this, "Track Switch", nameof(trackSwitch)).SetAsFlexibleInt())
.Button("Track Percent", () =>
insp.GenerateCompositeParameterWindow(this, "Track Percent", nameof(trackPercent)).SetAsFlexibleFloat())
.Button("Paste Track List", PasteTrackList)
.Toggle(nameof(MotionAngles), "Motion With Angles")
.Section("Generate")
.Button("Game Camera", () =>
GameCamera.GenerateElement("New Game Camera", Guid.NewGuid(), new List<string>(),
true, this, GameCamera.CameraViewType.Perspective, 60, 10))
.Button("Trail", () =>
Trail.GenerateElement("New Trail", Guid.NewGuid(), new List<string>(),
true, this, 1, true, 1,
AnimationCurve.Constant(0, 1, 1), ColorExtensions.DefaultGradient(), "", ""))
.Button("Environment Object", () =>
TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List<string>(),
true, this))
.Button("Generate Particle Emitter", () =>
ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List<string>(), true,
this, "", "", false, 0, 1, ParticleSystemSimulationSpace.World,
10, 5, 1, 1, true, Vector3.zero))
.Build();
}
#endregion
#region [] Tool Methods
private void PasteTrackList()
{

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame
{
@@ -10,8 +11,7 @@ namespace Ichni.RhythmGame
#region [] Save & Serialize
public override void SaveBM()
{
// 保存MotionAngles到BM
matchedBM = new TrackHeadPoint_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM,
matchedBM = new TrackHeadPoint_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM,
motionApplyRotation, motionEulerAngles);
}
#endregion
@@ -21,31 +21,25 @@ namespace Ichni.RhythmGame
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Track Percent Point");
var motionAngles0 = container.GenerateSubcontainer(3);
var motionAnglesApplyToggle = inspector.GenerateToggle(this, motionAngles0, "Motion With Angles", nameof(motionApplyRotation))
.AddListenerFunction(() => trackPositioner.motion.applyRotation = motionApplyRotation);
var motionAngles1 = container.GenerateSubcontainer(1);
var motionAnglesValueInputField = inspector.GenerateVector3InputField(this, motionAngles1, "Motion Angles", nameof(motionEulerAngles))
.AddListenerFunction(()=> trackPositioner.motion.rotationOffset = motionEulerAngles);
var generation = container.GenerateSubcontainer(3);
var generateTrailButton = inspector.GenerateButton(this, generation, "Generate Trail", () =>
{
Trail.GenerateElement("New Trail", Guid.NewGuid(), new List<string>(), true,
this, 1, true, 1,
UnityEngine.AnimationCurve.Constant(0, 1, 1), ColorExtensions.DefaultGradient(), "", "");
});
var environmentObjectButton = inspector.GenerateButton(this, generation, "Environment Object",
() => TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List<string>(),
true, this));
var generateParticleEmitterButton = inspector.GenerateButton(this, generation, "Generate Particle Emitter", () =>
{
ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List<string>(), true,
this, "", "",false,0, 1, UnityEngine.ParticleSystemSimulationSpace.World,
10, 5, 1, 1 ,true, UnityEngine.Vector3.zero);
});
InspectorBuilder.For(this)
.Section("Track Percent Point")
.Toggle(nameof(motionApplyRotation), "Motion With Angles")
.OnChanged(() => trackPositioner.motion.applyRotation = motionApplyRotation)
.Vector3Field(nameof(motionEulerAngles), "Motion Angles")
.OnChanged(() => trackPositioner.motion.rotationOffset = motionEulerAngles)
.Section("Generate")
.Button("Generate Trail", () =>
Trail.GenerateElement("New Trail", Guid.NewGuid(), new List<string>(), true,
this, 1, true, 1,
AnimationCurve.Constant(0, 1, 1), ColorExtensions.DefaultGradient(), "", ""))
.Button("Environment Object", () =>
TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List<string>(),
true, this))
.Button("Generate Particle Emitter", () =>
ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List<string>(), true,
this, "", "", false, 0, 1, ParticleSystemSimulationSpace.World,
10, 5, 1, 1, true, Vector3.zero))
.Build();
}
#endregion
}

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using Ichni.Editor;
using Ichni.RhythmGame.Beatmap;
using UnityEngine;
namespace Ichni.RhythmGame
{
@@ -23,31 +24,26 @@ namespace Ichni.RhythmGame
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Track Percent Point");
var pointSettings = container.GenerateSubcontainer(3);
var trackPercentButton = inspector.GenerateButton(this, pointSettings, "Track Percent",
() => { inspector.GenerateCompositeParameterWindow(this, "Track Percent", nameof(trackPercent)).SetAsFlexibleFloat(); });
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
// 新增MotionAngles开关
var motionAnglesToggle = inspector.GenerateToggle(this, pointSettings, "Motion With Angles", nameof(MotionAngles));
var generation = container.GenerateSubcontainer(3);
var generateTrailButton = inspector.GenerateButton(this, generation, "Generate Trail", () =>
{
Trail.GenerateElement("New Trail", Guid.NewGuid(), new List<string>(), true,
this, 1, true, 1,
UnityEngine.AnimationCurve.Constant(0, 1, 1), ColorExtensions.DefaultGradient(), "", "");
});
var environmentObjectButton = inspector.GenerateButton(this, generation, "Environment Object",
() => TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List<string>(),
true, this));
var generateParticleEmitterButton = inspector.GenerateButton(this, generation, "Generate Particle Emitter", () =>
{
ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List<string>(), true,
this, "", "", false, 0, 1, UnityEngine.ParticleSystemSimulationSpace.World,
10, 5, 1, 1, true, UnityEngine.Vector3.zero);
});
InspectorBuilder.For(this)
.Section("Track Percent Point")
.Button("Track Percent", () =>
insp.GenerateCompositeParameterWindow(this, "Track Percent", nameof(trackPercent)).SetAsFlexibleFloat())
.Toggle(nameof(MotionAngles), "Motion With Angles")
.Section("Generate")
.Button("Generate Trail", () =>
Trail.GenerateElement("New Trail", Guid.NewGuid(), new List<string>(), true,
this, 1, true, 1,
AnimationCurve.Constant(0, 1, 1), ColorExtensions.DefaultGradient(), "", ""))
.Button("Environment Object", () =>
TemporaryObject.GenerateElement("New Environment Object", Guid.NewGuid(), new List<string>(),
true, this))
.Button("Generate Particle Emitter", () =>
ParticleEmitter.GenerateElement("New Particle Emitter", Guid.NewGuid(), new List<string>(), true,
this, "", "", false, 0, 1, ParticleSystemSimulationSpace.World,
10, 5, 1, 1, true, Vector3.zero))
.Build();
}
#endregion
}

View File

@@ -17,26 +17,21 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Track Path");
var trackPathSubmoduleSettings = container.GenerateSubcontainer(3);
var trackSpaceDropdown =
inspector.GenerateDropdown(this, trackPathSubmoduleSettings, "Space Type", typeof(Track.TrackSpaceType), nameof(trackSpaceType));
var trackSamplingDropdown =
inspector.GenerateDropdown(this, trackPathSubmoduleSettings, "Sampling Type", typeof(Track.TrackSamplingType), nameof(trackSamplingType));
var trackSampleRateInput =
inspector.GenerateInputField(this, trackPathSubmoduleSettings, "Sample Rate", nameof(sampleRate))
.AddListenerFunction(() => { path.sampleRate = sampleRate; Refresh(); });
var isClosedToggle =
inspector.GenerateToggle(this, trackPathSubmoduleSettings, "Is Closed", nameof(isClosed))
.AddListenerFunction(ClosePath);
var generatePathNodeButton = inspector.GenerateButton(this, trackPathSubmoduleSettings, "Generate Path Node", () =>
{
PathNode.GenerateElement("New Path Node", Guid.NewGuid(), new List<string>(), true, track, true);
});
var showDisplayToggle = inspector.GenerateToggle(this, trackPathSubmoduleSettings, "Show Display", nameof(isShowingDisplay))
.AddListenerFunction(() => SetDisplay(isShowingDisplay));
InspectorBuilder.For(this)
.Section("Track Path")
.Dropdown<Track.TrackSpaceType>(nameof(trackSpaceType), "Space Type")
.Dropdown<Track.TrackSamplingType>(nameof(trackSamplingType), "Sampling Type")
.InputField(nameof(sampleRate), "Sample Rate")
.OnChanged(() => { path.sampleRate = sampleRate; Refresh(); })
.Toggle(nameof(isClosed), "Is Closed")
.OnChanged(ClosePath)
.Button("Generate Path Node", () =>
{
PathNode.GenerateElement("New Path Node", Guid.NewGuid(), new List<string>(), true, track, true);
})
.Toggle(nameof(isShowingDisplay), "Show Display")
.OnChanged(() => SetDisplay(isShowingDisplay))
.Build();
}
#endregion

View File

@@ -11,134 +11,114 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Track Renderer " + submoduleName[submoduleNameIndex] + (meshGenerator.baked ? " (Baked)" : ""));
var zWriteSettings = container.GenerateSubcontainer(3);
// Material dropdown lists
bool hasMaterialBundle = materialThemeBundleName != String.Empty;
ThemeBundle matBundle = null;
if (hasMaterialBundle)
hasMaterialBundle = ThemeBundleManager.instance.TryGetThemeBundle(materialThemeBundleName, out matBundle);
List<string> materialNameList = hasMaterialBundle
? matBundle.assetList_Material.ConvertAll(x => x.name)
: new List<string>();
var zWriteToggle =
inspector.GenerateToggle(this, zWriteSettings, "Enable ZWrite", nameof(zWrite))
.AddListenerFunction(SetEnableZWrite);
var emissionSettings = container.GenerateSubcontainer(3);
var enableEmissionToggle =
inspector.GenerateToggle(this, emissionSettings, "Enable Emission", nameof(enableEmission))
.AddListenerFunction(SetEnableEmission);
var emissionIntensityInputField =
inspector.GenerateInputField(this, emissionSettings, "Emission Intensity", nameof(emissionIntensity))
.AddListenerFunction(SetEmissionIntensity);
var uvSettings = container.GenerateSubcontainer(1);
var uvScaleInputField =
inspector.GenerateVector2InputField(this, uvSettings, "UV Scale", nameof(uvScale))
.AddListenerFunction(SetUV);
var uvOffsetInputField =
inspector.GenerateVector2InputField(this, uvSettings, "UV Offset", nameof(uvOffset))
.AddListenerFunction(SetUV);
var meshSettings = container.GenerateSubcontainer(3);
inspector.GenerateDropdown(this, meshSettings, "UV Mode", typeof(Dreamteck.Splines.MeshGenerator.UVMode), nameof(uvMode))
.AddListenerFunction(SetUV);
inspector.GenerateInputField(this, meshSettings, "UV Rotation", nameof(uvRotation))
.AddListenerFunction(SetUV);
inspector.GenerateInputField(this, meshSettings, "Size", nameof(size))
.AddListenerFunction(SetUV);
var materialSettings = container.GenerateSubcontainer(3);
var themeBundleDropdown = inspector
.GenerateDropdown(this, materialSettings, "Theme Bundle", ThemeBundleManager.instance.selectedThemeBundleList, nameof(materialThemeBundleName))
.AddListenerFunction(() => inspectorMain.SetInspector(track));
if (materialThemeBundleName != String.Empty && ThemeBundleManager.instance.TryGetThemeBundle(materialThemeBundleName, out ThemeBundle themeBundle))
// Texture dropdown lists
bool hasTextureBundle = customTextureThemeBundleName != String.Empty;
ThemeBundle texBundle = null;
if (hasTextureBundle)
hasTextureBundle = ThemeBundleManager.instance.TryGetThemeBundle(customTextureThemeBundleName, out texBundle);
List<string> texNameList = new List<string> { "None" };
if (hasTextureBundle)
{
List<string> materialNameList = themeBundle.assetList_Material.ConvertAll(x => x.name);
var objectNameDropdown = inspector.GenerateDropdown(this, materialSettings, "Material Name", materialNameList, nameof(materialName))
.AddListenerFunction(() => inspectorMain.SetInspector(track));
}
else
{
var objectNameDropdown = inspector.GenerateDropdown(this, materialSettings, "Material Name", new List<string>(), nameof(materialName));
objectNameDropdown.dropdown.interactable = false;
}
var applyMaterialButton = inspector.GenerateButton(this, materialSettings, "Apply Material", () => { ApplyMaterial(materialThemeBundleName, materialName); });
var textureSettings = container.GenerateSubcontainer(3);
var textureThemeBundleDropdown = inspector
.GenerateDropdown(this, textureSettings, "Tex Bundle", ThemeBundleManager.instance.selectedThemeBundleList, nameof(customTextureThemeBundleName))
.AddListenerFunction(() => inspectorMain.SetInspector(track));
if (customTextureThemeBundleName != String.Empty && ThemeBundleManager.instance.TryGetThemeBundle(customTextureThemeBundleName, out ThemeBundle texThemeBundle))
{
List<string> texNameList = new List<string>();
texNameList.Add("None");
var textureNames = new List<string>();
if (texThemeBundle.assetList_Texture != null) textureNames.AddRange(texThemeBundle.assetList_Texture.ConvertAll(x => x.name));
if (texThemeBundle.assetList_Other != null) textureNames.AddRange(texThemeBundle.assetList_Other.FindAll(x => x is Sprite).ConvertAll(x => x.name));
// Remove duplicates
if (texBundle.assetList_Texture != null)
textureNames.AddRange(texBundle.assetList_Texture.ConvertAll(x => x.name));
if (texBundle.assetList_Other != null)
textureNames.AddRange(texBundle.assetList_Other.FindAll(x => x is Sprite).ConvertAll(x => x.name));
texNameList.AddRange(new HashSet<string>(textureNames));
var textureNameDropdown = inspector.GenerateDropdown(this, textureSettings, "Texture Name", texNameList, nameof(customTextureName))
.AddListenerFunction(() => inspectorMain.SetInspector(track));
}
else
{
var textureNameDropdown = inspector.GenerateDropdown(this, textureSettings, "Texture Name", new List<string>() { "None" }, nameof(customTextureName));
textureNameDropdown.dropdown.interactable = false;
}
var applyTextureButton = inspector.GenerateButton(this, textureSettings, "Apply Texture", () => { Refresh(); });
string sectionTitle = "Track Renderer " + submoduleName[submoduleNameIndex]
+ (meshGenerator.baked ? " (Baked)" : "");
var delete = container.GenerateSubcontainer(3);
var deleteButton = inspector.GenerateButton(this, delete, "Delete", () =>
{
Delete();
track.trackRendererSubmodule = null;
inspectorMain.SetInspector(track);
track.Refresh();
});
InspectorBuilder.For(this)
.Section(sectionTitle)
// ZWrite & Emission
.Toggle(nameof(zWrite), "Enable ZWrite")
.OnChanged(SetEnableZWrite)
.Toggle(nameof(enableEmission), "Enable Emission")
.OnChanged(SetEnableEmission)
.InputField(nameof(emissionIntensity), "Emission Intensity")
.OnChanged(SetEmissionIntensity)
// UV
.Vector2Field(nameof(uvScale), "UV Scale")
.OnChanged(SetUV)
.Vector2Field(nameof(uvOffset), "UV Offset")
.OnChanged(SetUV)
// Mesh
.Dropdown(nameof(uvMode), typeof(Dreamteck.Splines.MeshGenerator.UVMode), "UV Mode")
.OnChanged(SetUV)
.InputField(nameof(uvRotation), "UV Rotation")
.OnChanged(SetUV)
.InputField(nameof(size), "Size")
.OnChanged(SetUV)
.Section("Material Selection")
.Dropdown(nameof(materialThemeBundleName), ThemeBundleManager.instance.selectedThemeBundleList, "Theme Bundle")
.OnChanged(() => inspectorMain.SetInspector(track))
.Dropdown(nameof(materialName), materialNameList, "Material Name")
.EnabledIf(() => hasMaterialBundle)
.OnChanged(() => inspectorMain.SetInspector(track))
.Button("Apply Material", () => ApplyMaterial(materialThemeBundleName, materialName))
.Section("Texture Selection")
.Dropdown(nameof(customTextureThemeBundleName), ThemeBundleManager.instance.selectedThemeBundleList, "Tex Bundle")
.OnChanged(() => inspectorMain.SetInspector(track))
.Dropdown(nameof(customTextureName), texNameList, "Texture Name")
.EnabledIf(() => hasTextureBundle)
.OnChanged(() => inspectorMain.SetInspector(track))
.Button("Apply Texture", () => Refresh())
.Section("Danger Zone")
.Button("Delete", () =>
{
Delete();
track.trackRendererSubmodule = null;
inspectorMain.SetInspector(track);
track.Refresh();
})
.Build();
}
#endregion
#region [] Editor Interactions
protected void SetEnableEmission()
{
// 仅保留关键字控制,具体颜色由 Refresh 的 property block 控制
if (enableEmission)
{
meshRenderer.material.EnableKeyword("_EMISSION_ON");
}
else
{
meshRenderer.material.DisableKeyword("_EMISSION_ON");
}
}
protected void SetEnableZWrite()
{
var block = new UnityEngine.MaterialPropertyBlock();
var block = new MaterialPropertyBlock();
meshRenderer.GetPropertyBlock(block);
// ZWrite
block.SetFloat("_ZWrite", zWrite ? 1f : 0f);
meshRenderer.SetPropertyBlock(block);
}
protected void SetEmissionIntensity()
{
var block = new UnityEngine.MaterialPropertyBlock();
var block = new MaterialPropertyBlock();
meshRenderer.GetPropertyBlock(block);
// Emission
if (enableEmission)
{
meshRenderer.material.EnableKeyword("_EMISSION_ON");
block.SetColor("_EmissionColor", UnityEngine.Color.white * UnityEngine.Mathf.Pow(2, emissionIntensity));
block.SetColor("_EmissionColor", Color.white * Mathf.Pow(2, emissionIntensity));
}
else
{
meshRenderer.material.DisableKeyword("_EMISSION_ON");
block.SetColor("_EmissionColor", UnityEngine.Color.black);
block.SetColor("_EmissionColor", Color.black);
}
meshRenderer.SetPropertyBlock(block);
}
@@ -158,14 +138,11 @@ namespace Ichni.RhythmGame
{
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Tube Settings");
var tubeSettings = container.GenerateSubcontainer(3);
var sideCountInputField =
inspector.GenerateInputField(this, tubeSettings, "Side Count", nameof(sideCount))
.AddListenerFunction(() => { tubeGenerator.sides = sideCount; });
InspectorBuilder.For(this)
.Section("Tube Settings")
.InputField(nameof(sideCount), "Side Count")
.OnChanged(() => tubeGenerator.sides = sideCount)
.Build();
base.SetUpInspector();
}

View File

@@ -9,30 +9,25 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Track Time Movable");
var trackTimeSubmoduleSettings = container.GenerateSubcontainer(3);
var startTimeInputField =
inspector.GenerateInputField(this, trackTimeSubmoduleSettings, "Start Time", nameof(trackStartTime))
.AddListenerFunction(RefreshChildren);
var endTimeInputField = inspector.GenerateInputField(this, trackTimeSubmoduleSettings, "End Time", nameof(trackEndTime))
.AddListenerFunction(RefreshChildren);
var visibleTimeInputField =
inspector.GenerateInputField(this, trackTimeSubmoduleSettings, "Visible Time Length", nameof(visibleTrackTimeLength));
var animationCurveDropdown =
inspector.GenerateDropdown(this, trackTimeSubmoduleSettings, "Animation Curve", typeof(AnimationCurveType), nameof(animationCurveType))
.AddListenerFunction(RefreshChildren);
// var isGoWithZToggle =
// inspector.GenerateToggle(this, trackTimeSubmoduleSettings, "Go With Z", nameof(isGoWithZ));
var deleteButton = inspector.GenerateButton(this, trackTimeSubmoduleSettings, "Delete", () =>
{
Delete();
track.trackTimeSubmodule = null;
inspectorMain.SetInspector(track);
track.Refresh();
});
InspectorBuilder.For(this)
.Section("Track Time Movable")
.InputField(nameof(trackStartTime), "Start Time")
.OnChanged(RefreshChildren)
.InputField(nameof(trackEndTime), "End Time")
.OnChanged(RefreshChildren)
.InputField(nameof(visibleTrackTimeLength), "Visible Time Length")
.Dropdown<AnimationCurveType>(nameof(animationCurveType), "Animation Curve")
.OnChanged(RefreshChildren)
.Button("Delete", () =>
{
Delete();
track.trackTimeSubmodule = null;
inspectorMain.SetInspector(track);
track.Refresh();
})
.Build();
}
#endregion
@@ -55,22 +50,20 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Track Time Static");
var trackTimeSubmoduleSettings = container.GenerateSubcontainer(3);
var totalTimeInputField =
inspector.GenerateInputField(this, trackTimeSubmoduleSettings, "Total Time", nameof(trackTotalTime));
var animationCurveDropdown =
inspector.GenerateDropdown(this, trackTimeSubmoduleSettings, "Animation Curve", typeof(AnimationCurveType), nameof(animationCurveType));
var deleteButton = inspector.GenerateButton(this, trackTimeSubmoduleSettings, "Delete", () =>
{
Delete();
track.trackTimeSubmodule = null;
inspectorMain.SetInspector(track);
track.Refresh();
});
InspectorBuilder.For(this)
.Section("Track Time Static")
.InputField(nameof(trackTotalTime), "Total Time")
.Dropdown<AnimationCurveType>(nameof(animationCurveType), "Animation Curve")
.Button("Delete", () =>
{
Delete();
track.trackTimeSubmodule = null;
inspectorMain.SetInspector(track);
track.Refresh();
})
.Build();
}
#endregion
}

View File

@@ -21,228 +21,187 @@ namespace Ichni.RhythmGame
#region [] Inspector Setup
public override void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
base.SetUpInspector();
var inspectorMain = EditorManager.instance.uiManager.inspector;
//次级模块
var trackSubmodulesContainer = inspector.GenerateContainer("Track Submodules");
var trackPathSubcontainer = trackSubmodulesContainer.GenerateSubcontainer(3);
var trackPathButton = inspector.GenerateButton(this, trackPathSubcontainer, "Track Path", () =>
{
trackPathSubmodule = new TrackPathSubmodule(this, TrackSpaceType.CatmullRom,
TrackSamplingType.TimeDistributed, false, false);
inspectorMain.SetInspector(this);
});
InspectorBuilder.For(this)
// ── 次级模块 ──
.Section("Track Submodules", sectionOrder: 10)
.Button("Track Path", () =>
{
trackPathSubmodule = new TrackPathSubmodule(this, TrackSpaceType.CatmullRom,
TrackSamplingType.TimeDistributed, false, false);
inspectorMain.SetInspector(this);
})
.EnabledIf(() => trackPathSubmodule == null)
.Button("Track Time Movable", () =>
{
trackTimeSubmodule = new TrackTimeSubmoduleMovable(this, 0, 1, 1, AnimationCurveType.Linear);
inspectorMain.SetInspector(this);
})
.EnabledIf(() => trackTimeSubmodule == null)
.Button("Track Time Static", () =>
{
trackTimeSubmodule = new TrackTimeSubmoduleStatic(this, 1, AnimationCurveType.Linear);
inspectorMain.SetInspector(this);
})
.EnabledIf(() => trackTimeSubmodule == null)
.Button("Track Renderer Auto Orient", () =>
{
trackRendererSubmodule =
new TrackRendererSubmoduleAutoOrient(this, false, 0, true, Vector2.one, Vector2.zero);
inspectorMain.SetInspector(this);
})
.EnabledIf(() => trackRendererSubmodule == null)
.Button("Track Renderer Path Generator", () =>
{
trackRendererSubmodule =
new TrackRendererSubmodulePathGenerator(this, false, 0, true, Vector2.one, Vector2.zero);
inspectorMain.SetInspector(this);
})
.EnabledIf(() => trackRendererSubmodule == null)
.Button("Track Renderer Tube Generator", () =>
{
trackRendererSubmodule =
new TrackRendererSubmoduleTubeGenerator(this, false, 0, true, 4, Vector2.one, Vector2.zero);
inspectorMain.SetInspector(this);
})
.EnabledIf(() => trackRendererSubmodule == null)
.Button("Track Renderer Surface", () =>
{
trackRendererSubmodule =
new TrackRendererSubmoduleSurface(this, false, 0, true, Vector2.one, Vector2.zero);
inspectorMain.SetInspector(this);
})
.EnabledIf(() => trackRendererSubmodule == null)
var trackTimeSubcontainer = trackSubmodulesContainer.GenerateSubcontainer(3);
var trackTimeMovableButton =
inspector.GenerateButton(this, trackTimeSubcontainer, "Track Time Movable", () =>
{
trackTimeSubmodule = new TrackTimeSubmoduleMovable(this, 0, 1, 1, AnimationCurveType.Linear);
inspectorMain.SetInspector(this);
});
var trackTimeStaticButton =
inspector.GenerateButton(this, trackTimeSubcontainer, "Track Time Static", () =>
{
trackTimeSubmodule = new TrackTimeSubmoduleStatic(this, 1, AnimationCurveType.Linear);
inspectorMain.SetInspector(this);
});
// ── 物体生成 ──
.Section("Generate Elements", sectionOrder: 20)
.Button("Path Node", () =>
{
PathNode.GenerateElement("New Path Node", Guid.NewGuid(), new List<string>(), true, this, true);
})
.EnabledIf(() => trackPathSubmodule != null)
.Button("Track Percent Point", () =>
{
var a = TrackPercentPoint.GenerateElement("New Track Percent Point", Guid.NewGuid(), new List<string>(), true, this, new FlexibleFloat());
if (trackTimeSubmodule != null && trackTimeSubmodule is TrackTimeSubmoduleMovable trackTimeSubmoduleMovable)
a.trackPercent.Add(
new AnimatedFloat(trackTimeSubmoduleMovable.trackStartTime, trackTimeSubmoduleMovable.trackEndTime, 0, 1, AnimationCurveType.Linear));
})
.Button("Track Head Point", () =>
{
TrackHeadPoint.GenerateElement("New Track Head Point", Guid.NewGuid(), new List<string>(), true, this, false, Vector3.zero);
})
.EnabledIf(() => trackTimeSubmodule is TrackTimeSubmoduleMovable)
.Button("Tap", () => Tap.GenerateElement("New Tap", Guid.NewGuid(), new List<string>(), true, this, 0f))
.Button("Stay", () => Stay.GenerateElement("New Stay", Guid.NewGuid(), new List<string>(), true, this, 0f))
.Button("Hold", () => Hold.GenerateElement("New Hold", Guid.NewGuid(), new List<string>(), true, this, 0f, 1f))
.Button("Flick", () => Flick.GenerateElement("New Flick", Guid.NewGuid(), new List<string>(), true, this, 0f, new List<Vector2>()))
.Button("Particle Tracker", () =>
{
ParticleTracker.GenerateElement("New Particle Tracker", Guid.NewGuid(), new List<string>(), true, this,
string.Empty, string.Empty, false, 0, 1, false, 10, Vector3.right, 10, 5, true, Vector3.zero);
})
.Button("Object Tracker", () =>
{
ObjectTracker.GenerateElement("New Object Tracker", Guid.NewGuid(), new List<string>(), true, this,
string.Empty, string.Empty, 10, Vector2.zero, Vector2.zero, string.Empty,
false, Vector3.zero, Vector3.zero, string.Empty,
false, Vector3.zero, Vector3.zero, string.Empty);
})
.Button("Track Global Color Change", () =>
{
TrackGlobalColorChange.GenerateElement("New Track Global Color Change", Guid.NewGuid(), new List<string>(), true, this,
new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true));
})
.Build();
var trackRendererSubcontainer = trackSubmodulesContainer.GenerateSubcontainer(3);
var trackRendererAutoOrientButton =
inspector.GenerateButton(this, trackRendererSubcontainer, "Track Renderer Auto Orient", () =>
{
trackRendererSubmodule =
new TrackRendererSubmoduleAutoOrient(this, false, 0, true, Vector2.one, Vector2.zero);
inspectorMain.SetInspector(this);
});
var trackRendererPathGeneratorButton =
inspector.GenerateButton(this, trackRendererSubcontainer, "Track Renderer Path Generator", () =>
{
trackRendererSubmodule =
new TrackRendererSubmodulePathGenerator(this, false, 0, true, Vector2.one, Vector2.zero);
inspectorMain.SetInspector(this);
});
var trackRenderTubeGeneratorButton =
inspector.GenerateButton(this, trackRendererSubcontainer, "Track Renderer Tube Generator", () =>
{
trackRendererSubmodule =
new TrackRendererSubmoduleTubeGenerator(this, false, 0, true, 4, Vector2.one, Vector2.zero);
inspectorMain.SetInspector(this);
});
var trackRendererSurfaceButton =
inspector.GenerateButton(this, trackRendererSubcontainer, "Track Renderer Surface", () =>
{
trackRendererSubmodule =
new TrackRendererSubmoduleSurface(this, false, 0, true, Vector2.one, Vector2.zero);
inspectorMain.SetInspector(this);
});
InspectorBuilder.For(this)
.Section("Generate Elements", sectionOrder: 25)
.Preset(InspectorBuilder.TransformPreset)
// ── Track 工具 ──
.Section("Track Tools", sectionOrder: 30)
.Button("QuickCopy", () =>
{
IHaveInspection qcWindow = inspectorMain.GenerateSecondaryWindow(this, elementName + "'s Quick Copy");
var qcContainer = qcWindow.GenerateContainer();
var qcSubcontainer = qcContainer.GenerateSubcontainer(3);
var xField = qcWindow.GenerateInputField(qcSubcontainer, "X offset", "0");
var yField = qcWindow.GenerateInputField(qcSubcontainer, "Y offset", "0");
var zField = qcWindow.GenerateInputField(qcSubcontainer, "Z offset", "0");
var timeField = qcWindow.GenerateInputField(qcSubcontainer, "Time offset", "0");
var iterationField = qcWindow.GenerateInputField(qcSubcontainer, "Iteration", "0");
var includeAnimationToggle = qcWindow.GenerateToggle(null, qcSubcontainer, "Include Animation", string.Empty);
var movingTrackToggle = qcWindow.GenerateToggle(null, qcSubcontainer, "Moving Track or PathNode", string.Empty);
qcWindow.GenerateButton(this, qcSubcontainer, "Copy", () =>
{
Vector3 positionOffset = new Vector3(xField.GetValue<float>(), yField.GetValue<float>(), zField.GetValue<float>());
float timeOffset = timeField.GetValue<float>();
int iteration = iterationField.GetValue<int>();
bool includeAnimation = includeAnimationToggle.toggle.isOn;
bool movingTrack = movingTrackToggle.toggle.isOn;
this.QuickCopy(positionOffset, timeOffset, includeAnimation, iteration, movingTrack);
});
})
.Button("Whole Track Move", () =>
{
IHaveInspection wholeMoveWindow = inspectorMain.GenerateSecondaryWindow(this, elementName + "'s Whole Track Move");
var wmContainer = wholeMoveWindow.GenerateContainer();
var wmSubcontainer = wmContainer.GenerateSubcontainer(3);
var xField = wholeMoveWindow.GenerateInputField(wmSubcontainer, "X offset", "0");
var yField = wholeMoveWindow.GenerateInputField(wmSubcontainer, "Y offset", "0");
var zField = wholeMoveWindow.GenerateInputField(wmSubcontainer, "Z offset", "0");
wholeMoveWindow.GenerateButton(this, wmSubcontainer, "Move", () =>
{
Vector3 positionOffset = new Vector3(xField.GetValue<float>(), yField.GetValue<float>(), zField.GetValue<float>());
this.WholeTrackMove(positionOffset);
});
})
.Button("Whole Track Swirl", () =>
{
IHaveInspection wholeSwirlWindow = inspectorMain.GenerateSecondaryWindow(this, elementName + "'s Whole Track Swirl");
var wsContainer = wholeSwirlWindow.GenerateContainer();
var wsSubcontainer = wsContainer.GenerateSubcontainer(3);
var angleField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Angle", "0");
var centerXField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Center X", "0");
var centerYField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Center Y", "0");
var centerZField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Center Z", "0");
var axisDirXField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Axis Direction X", "0");
var axisDirYField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Axis Direction Y", "0");
var axisDirZField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Axis Direction Z", "0");
wholeSwirlWindow.GenerateButton(this, wsSubcontainer, "Swirl", () =>
{
float angle = angleField.GetValue<float>();
Vector3 center = new Vector3(centerXField.GetValue<float>(), centerYField.GetValue<float>(), centerZField.GetValue<float>());
Vector3 axisDirection = new Vector3(axisDirXField.GetValue<float>(), axisDirYField.GetValue<float>(), axisDirZField.GetValue<float>());
this.WholeTrackSwirl(angle, center, axisDirection);
});
})
//物体生成
var generateContainer = inspector.GenerateContainer("Generate Elements");
var pathNodeSubcontainer = generateContainer.GenerateSubcontainer(3);
var pathNodeButton = inspector.GenerateButton(this, pathNodeSubcontainer, "Path Node",
() => { PathNode.GenerateElement("New Path Node", Guid.NewGuid(), new List<string>(), true, this, true); });
// ── PathNode 工具 ──
.Section("Path Node Tools", sectionOrder: 40)
.Button("Set All Path Node Sphere", () =>
{
bool firstPathNodeSphere = trackPathSubmodule.pathNodeList[0].isShowingSphere;
this.SetAllPathNodeSphere(!firstPathNodeSphere);
})
.Button("Only Enable Start & End Path Node's sphere", SetOnlyStartEndPathNodeSphereEnabled)
var trackMajorPointSubcontainer = generateContainer.GenerateSubcontainer(3);
var trackPercentPointButton = inspector.GenerateButton(this, trackMajorPointSubcontainer, "Track Percent Point",
() =>
{
var a = TrackPercentPoint.GenerateElement("New Track Percent Point", Guid.NewGuid(), new List<string>(), true, this, new FlexibleFloat());
if (trackTimeSubmodule != null && trackTimeSubmodule is TrackTimeSubmoduleMovable trackTimeSubmoduleMovable)
a.trackPercent.Add(
new AnimatedFloat(trackTimeSubmoduleMovable.trackStartTime, trackTimeSubmoduleMovable.trackEndTime, 0, 1, AnimationCurveType.Linear));
});
var trackHeadPointButton = inspector.GenerateButton(this, trackMajorPointSubcontainer, "Track Head Point",
() => { TrackHeadPoint.GenerateElement("New Track Head Point", Guid.NewGuid(), new List<string>(), true, this, false, Vector3.zero); });
if (trackTimeSubmodule is not TrackTimeSubmoduleMovable) trackHeadPointButton.button.interactable = false;
var noteSubcontainer = generateContainer.GenerateSubcontainer(3);
var tapButton = inspector.GenerateButton(this, noteSubcontainer, "Tap",
() => { Tap.GenerateElement("New Tap", Guid.NewGuid(), new List<string>(), true, this, 0f); });
var stayButton = inspector.GenerateButton(this, noteSubcontainer, "Stay",
() => { Stay.GenerateElement("New Stay", Guid.NewGuid(), new List<string>(), true, this, 0f); });
var holdButton = inspector.GenerateButton(this, noteSubcontainer, "Hold",
() => { Hold.GenerateElement("New Hold", Guid.NewGuid(), new List<string>(), true, this, 0f, 1f); });
var flickButton = inspector.GenerateButton(this, noteSubcontainer, "Flick",
() => { Flick.GenerateElement("New Flick", Guid.NewGuid(), new List<string>(), true, this, 0f, new List<Vector2>()); });
var particleSubcontainer = generateContainer.GenerateSubcontainer(3);
var particleTrackerButton = inspector.GenerateButton(this, particleSubcontainer, "Particle Tracker",
() =>
{
ParticleTracker.GenerateElement("New Particle Tracker", Guid.NewGuid(), new List<string>(), true, this,
string.Empty, string.Empty, false, 0, 1, false, 10, Vector3.right, 10, 5, true, Vector3.zero);
});
var objectTrackerButton = inspector.GenerateButton(this, particleSubcontainer, "Object Tracker",
() =>
{
ObjectTracker.GenerateElement("New Object Tracker", Guid.NewGuid(), new List<string>(), true, this,
string.Empty, string.Empty, 10, Vector2.zero, Vector2.zero, string.Empty,
false, Vector3.zero, Vector3.zero, string.Empty,
false, Vector3.zero, Vector3.zero, string.Empty);
});
StandardInspectionElement.GenerateForTransform(this, generateContainer);
inspector.GenerateButton(this, particleSubcontainer, "Track Global Color Change",
() => { TrackGlobalColorChange.GenerateElement("New Track Global Color Change", Guid.NewGuid(), new List<string>(), true, this, new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true), new FlexibleFloat(true)); });
if (trackPathSubmodule != null)
{
trackPathButton.button.interactable = false;
}
else
{
pathNodeButton.button.interactable = false;
}
if (trackTimeSubmodule != null)
{
trackTimeMovableButton.button.interactable = false;
trackTimeStaticButton.button.interactable = false;
}
if (trackRendererSubmodule != null)
{
trackRendererAutoOrientButton.button.interactable = false;
trackRendererPathGeneratorButton.button.interactable = false;
trackRenderTubeGeneratorButton.button.interactable = false;
trackRendererSurfaceButton.button.interactable = false;
}
var trackToolsContainer = inspector.GenerateContainer("Track Tools");
var trackToolsSubcontainer = trackToolsContainer.GenerateSubcontainer(3);
var quickCopyButton = inspector.GenerateButton(this, trackToolsSubcontainer, "QuickCopy", () =>
{
IHaveInspection qcWindow = inspectorMain.GenerateSecondaryWindow(this, elementName + "'s Quick Copy");
var qcContainer = qcWindow.GenerateContainer();
var qcSubcontainer = qcContainer.GenerateSubcontainer(3);
var xField = qcWindow.GenerateInputField(qcSubcontainer, "X offset", "0");
var yField = qcWindow.GenerateInputField(qcSubcontainer, "Y offset", "0");
var zField = qcWindow.GenerateInputField(qcSubcontainer, "Z offset", "0");
var timeField = qcWindow.GenerateInputField(qcSubcontainer, "Time offset", "0");
var iterationField = qcWindow.GenerateInputField(qcSubcontainer, "Iteration", "0");
var includeAnimationToggle = qcWindow.GenerateToggle(null, qcSubcontainer, "Include Animation", string.Empty);
var MovingTrackToggle = qcWindow.GenerateToggle(null, qcSubcontainer, "Moving Track or PathNode", string.Empty);
qcWindow.GenerateButton(this, qcSubcontainer, "Copy", () =>
{
Vector3 positionOffset = new Vector3(xField.GetValue<float>(), yField.GetValue<float>(), zField.GetValue<float>());
float timeOffset = timeField.GetValue<float>();
int iteration = iterationField.GetValue<int>();
bool includeAnimation = includeAnimationToggle.toggle.isOn;
bool MovingTrack = MovingTrackToggle.toggle.isOn;
this.QuickCopy(positionOffset, timeOffset, includeAnimation, iteration, MovingTrack);
});
});
var wholeTrackMoveButton = inspector.GenerateButton(this, trackToolsSubcontainer, "Whole Track Move", () =>
{
IHaveInspection wholeMoveWindow = inspectorMain.GenerateSecondaryWindow(this, elementName + "'s Whole Track Move");
var wmContainer = wholeMoveWindow.GenerateContainer();
var wmSubcontainer = wmContainer.GenerateSubcontainer(3);
var xField = wholeMoveWindow.GenerateInputField(wmSubcontainer, "X offset", "0");
var yField = wholeMoveWindow.GenerateInputField(wmSubcontainer, "Y offset", "0");
var zField = wholeMoveWindow.GenerateInputField(wmSubcontainer, "Z offset", "0");
wholeMoveWindow.GenerateButton(this, wmSubcontainer, "Move", () =>
{
Vector3 positionOffset = new Vector3(xField.GetValue<float>(), yField.GetValue<float>(), zField.GetValue<float>());
this.WholeTrackMove(positionOffset);
});
});
var wholeTrackSwirlButton = inspector.GenerateButton(this, trackToolsSubcontainer, "Whole Track Swirl", () =>
{
IHaveInspection wholeSwirlWindow = inspectorMain.GenerateSecondaryWindow(this, elementName + "'s Whole Track Swirl");
var wsContainer = wholeSwirlWindow.GenerateContainer();
var wsSubcontainer = wsContainer.GenerateSubcontainer(3);
var angleField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Angle", "0");
var centerXField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Center X", "0");
var centerYField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Center Y", "0");
var centerZField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Center Z", "0");
var axisDirXField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Axis Direction X", "0");
var axisDirYField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Axis Direction Y", "0");
var axisDirZField = wholeSwirlWindow.GenerateInputField(wsSubcontainer, "Axis Direction Z", "0");
wholeSwirlWindow.GenerateButton(this, wsSubcontainer, "Swirl", () =>
{
float angle = angleField.GetValue<float>();
Vector3 center = new Vector3(centerXField.GetValue<float>(), centerYField.GetValue<float>(), centerZField.GetValue<float>());
Vector3 axisDirection = new Vector3(axisDirXField.GetValue<float>(), axisDirYField.GetValue<float>(), axisDirZField.GetValue<float>());
this.WholeTrackSwirl(angle, center, axisDirection);
});
});
var pathNodeToolsContainer = inspector.GenerateContainer("Path Node Tools");
var pathNodeToolsSubcontainer = pathNodeToolsContainer.GenerateSubcontainer(3);
var setAllPathNodeSphereButton =
inspector.GenerateButton(this, pathNodeToolsSubcontainer, "Set All Path Node Sphere", () =>
{
bool firstPathNodeSphere = trackPathSubmodule.pathNodeList[0].isShowingSphere;
this.SetAllPathNodeSphere(!firstPathNodeSphere);
});
var setOnlyStartEndPathNodeSphereEnabledButton =
inspector.GenerateButton(this, pathNodeToolsSubcontainer, "Only Enable Start & End Path Node's sphere",
this.SetOnlyStartEndPathNodeSphereEnabled);
var Sampler = inspector.GenerateContainer("Sampler");
var SamplerSubcontainer = Sampler.GenerateSubcontainer(1);
var SamplerButton = inspector.GenerateButton(this, SamplerSubcontainer, "Sampler", () =>
{
SampleWindow sampleWindow = inspector.GenerateSampler(this, this.elementName);
}
);
var fastNoteTrackerButton = inspector.GenerateButton(this, SamplerSubcontainer, "Fast Note Tracker", () =>
{
FastNoteTracker fastNoteTracker = FastNoteTracker.GenerateElement("Fast Note Tracker", Guid.NewGuid(), new List<string>(), true, this);
}
);
// ── Sampler ──
.Section("Sampler", sectionOrder: 50)
.Button("Sampler", () =>
{
IHaveInspection insp = EditorManager.instance.uiManager.inspector;
insp.GenerateSampler(this, this.elementName);
})
.Span(3)
.Button("Fast Note Tracker", () =>
{
FastNoteTracker.GenerateElement("Fast Note Tracker", Guid.NewGuid(), new List<string>(), true, this);
})
.Span(3)
.Build();
}
#endregion

View File

@@ -26,68 +26,55 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Object Tracker");
var generate = container.GenerateSubcontainer(3);
var themeBundleDropdown =
inspector.GenerateDropdown(this, generate, "Theme Bundle", themeBundleList, nameof(themeBundleName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
if (themeBundleName != String.Empty && ThemeBundleManager.instance.TryGetThemeBundle(themeBundleName, out ThemeBundle themeBundle))
{
objectNameList = themeBundle.assetList_GameObject.ConvertAll(x => x.name);
var objectNameDropdown =
inspector.GenerateDropdown(this, generate, "Object Name", objectNameList, nameof(objectName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
}
else
{
var objectNameDropdown =
inspector.GenerateDropdown(this, generate, "Object Name", new List<string>(), nameof(objectName));
objectNameDropdown.dropdown.interactable = false;
} // 如果没有选择主题包,则物体名称下拉框不可用
var setButton = inspector.GenerateButton(this, generate, "Generate", () =>
{
objectController.Clear();
this.objectPrefab = ThemeBundleManager.instance.GetObject<GameObject>(themeBundleName, objectName);
this.objectController.objects = new[] { this.objectPrefab };
this.objectController.Spawn();
});
bool hasThemeBundle = themeBundleName != String.Empty;
ThemeBundle themeBundle = null;
if (hasThemeBundle)
hasThemeBundle = ThemeBundleManager.instance.TryGetThemeBundle(themeBundleName, out themeBundle);
objectNameList = hasThemeBundle ? themeBundle.assetList_GameObject.ConvertAll(x => x.name) : new List<string>();
if (themeBundleName == String.Empty || objectName == String.Empty)
{
setButton.button.interactable = false;
}
var spawnSettings = container.GenerateSubcontainer(3);
inspector.GenerateInputField(this, spawnSettings, "Spawn Count", nameof(spawnCount))
.AddListenerFunction(() => objectController.spawnCount = spawnCount);
inspector.GenerateInputField(this, spawnSettings, "Play Time", nameof(playTime));
inspector.GenerateInputField(this, spawnSettings, "Stop Time", nameof(stopTime));
var posSettings = container.GenerateSubcontainer(1);
inspector.GenerateVector2InputField(this, posSettings, "Position Offset Min", nameof(positionOffsetMin))
.AddListenerFunction(() => objectController.minOffset = positionOffsetMin);
inspector.GenerateVector2InputField(this, posSettings, "Position Offset Max", nameof(positionOffsetMax))
.AddListenerFunction(() => objectController.maxOffset = positionOffsetMax);
//inspector.GenerateInputField(this, posSettings, "Custom Position Rule Name", nameof(customPositionRuleName));
var rotSettings = container.GenerateSubcontainer(1);
inspector.GenerateToggle(this, rotSettings, "Apply Rotation Offset", nameof(applyRotationOffset))
.AddListenerFunction(() => objectController.applyRotation = applyRotationOffset);
inspector.GenerateVector3InputField(this, rotSettings, "Rotation Offset Min", nameof(rotationOffsetMin))
.AddListenerFunction(() => objectController.minRotation = rotationOffsetMin);
inspector.GenerateVector3InputField(this, rotSettings, "Rotation Offset Max", nameof(rotationOffsetMax))
.AddListenerFunction(() => objectController.maxRotation = rotationOffsetMax);
//inspector.GenerateInputField(this, rotSettings, "Custom Rotation Rule Name", nameof(customRotationRuleName));
var scaleSettings = container.GenerateSubcontainer(1);
inspector.GenerateToggle(this, scaleSettings, "Apply Scale Offset", nameof(applyScaleOffset))
.AddListenerFunction(() => objectController.applyScale = applyScaleOffset);
inspector.GenerateVector3InputField(this, scaleSettings, "Scale Offset Min", nameof(scaleOffsetMin))
.AddListenerFunction(() => objectController.minScaleMultiplier = scaleOffsetMin);
inspector.GenerateVector3InputField(this, scaleSettings, "Scale Offset Max", nameof(scaleOffsetMax))
.AddListenerFunction(() => objectController.maxScaleMultiplier = scaleOffsetMax);
//inspector.GenerateInputField(this, scaleSettings, "Custom Scale Rule Name", nameof(customScaleRuleName));
InspectorBuilder.For(this)
.Section("Object Tracker")
// Theme bundle selection
.Dropdown(nameof(themeBundleName), themeBundleList, "Theme Bundle")
.OnChanged(() => inspectorMain.SetInspector(this))
.Dropdown(nameof(objectName), objectNameList, "Object Name")
.EnabledIf(() => hasThemeBundle)
.OnChanged(() => inspectorMain.SetInspector(this))
.Button("Generate", () =>
{
objectController.Clear();
objectPrefab = ThemeBundleManager.instance.GetObject<GameObject>(themeBundleName, objectName);
objectController.objects = new[] { objectPrefab };
objectController.Spawn();
})
.EnabledIf(() => themeBundleName != String.Empty && objectName != String.Empty)
.Section("Spawn Settings")
.InputField(nameof(spawnCount), "Spawn Count")
.OnChanged(() => objectController.spawnCount = spawnCount)
.InputField(nameof(playTime), "Play Time")
.InputField(nameof(stopTime), "Stop Time")
.Section("Position Offset")
.Vector2Field(nameof(positionOffsetMin), "Position Offset Min")
.OnChanged(() => objectController.minOffset = positionOffsetMin)
.Vector2Field(nameof(positionOffsetMax), "Position Offset Max")
.OnChanged(() => objectController.maxOffset = positionOffsetMax)
.Section("Rotation Offset")
.Toggle(nameof(applyRotationOffset), "Apply Rotation Offset")
.OnChanged(() => objectController.applyRotation = applyRotationOffset)
.Vector3Field(nameof(rotationOffsetMin), "Rotation Offset Min")
.OnChanged(() => objectController.minRotation = rotationOffsetMin)
.Vector3Field(nameof(rotationOffsetMax), "Rotation Offset Max")
.OnChanged(() => objectController.maxRotation = rotationOffsetMax)
.Section("Scale Offset")
.Toggle(nameof(applyScaleOffset), "Apply Scale Offset")
.OnChanged(() => objectController.applyScale = applyScaleOffset)
.Vector3Field(nameof(scaleOffsetMin), "Scale Offset Min")
.OnChanged(() => objectController.minScaleMultiplier = scaleOffsetMin)
.Vector3Field(nameof(scaleOffsetMax), "Scale Offset Max")
.OnChanged(() => objectController.maxScaleMultiplier = scaleOffsetMax)
.Build();
}
#endregion
}

View File

@@ -21,71 +21,50 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Particle Tracker");
// 确保 themeBundleList 初始化
if (themeBundleList == null)
themeBundleList = ThemeBundleManager.instance.loadedThemeBundleList.ConvertAll(x => x.themeBundleName);
DynamicUISubcontainer particleSettings0 = container.GenerateSubcontainer(3);
inspector.GenerateToggle(this, particleSettings0, "Prewarm", nameof(prewarm))
.AddListenerFunction(() => particlesContainer.SetPrewarm(prewarm));
inspector.GenerateInputField(this, particleSettings0, "Play Time", nameof(playTime));
inspector.GenerateInputField(this, particleSettings0, "Stop Time", nameof(stopTime));
bool hasThemeBundle = themeBundleName != string.Empty;
ThemeBundle themeBundle = null;
if (hasThemeBundle)
hasThemeBundle = ThemeBundleManager.instance.TryGetThemeBundle(themeBundleName, out themeBundle);
materialNameList = hasThemeBundle ? themeBundle.assetList_Material.ConvertAll(x => x.name) : new List<string>();
DynamicUISubcontainer particleSettings1_0 = container.GenerateSubcontainer(3);
inspector.GenerateToggle(this, particleSettings1_0, "Is 3D", nameof(is3D))
.AddListenerFunction(SetShape);
inspector.GenerateInputField(this, particleSettings1_0, "Width", nameof(width))
.AddListenerFunction(SetShape);
DynamicUISubcontainer particleSettings1_1 = container.GenerateSubcontainer(1);
inspector.GenerateVector3InputField(this, particleSettings1_1, "Extend Direction", nameof(extendDirection))
.AddListenerFunction(SetShape);
DynamicUISubcontainer particleSettings2 = container.GenerateSubcontainer(3);
inspector.GenerateInputField(this, particleSettings2, "Density", nameof(density))
.AddListenerFunction(()=>particlesContainer.SetDensity(density));
inspector.GenerateInputField(this, particleSettings2, "Life Time", nameof(lifeTime))
.AddListenerFunction(()=>particlesContainer.SetLifeTime(lifeTime));
DynamicUISubcontainer particleSettings3_0 = container.GenerateSubcontainer(3);
inspector.GenerateToggle(this, particleSettings3_0, "Is Auto Orient", nameof(isAutoOrient))
.AddListenerFunction(()=>particlesContainer.SetAlignment(isAutoOrient, particleRotation));
DynamicUISubcontainer particleSettings3_1 = container.GenerateSubcontainer(1);
inspector.GenerateVector3InputField(this, particleSettings3_1, "Particle Rotation", nameof(particleRotation))
.AddListenerFunction(()=>particlesContainer.SetParticleRotation(particleRotation));
DynamicUISubcontainer materialSettings = container.GenerateSubcontainer(3);
var themeBundleDropdown =
inspector.GenerateDropdown(this, materialSettings, "Theme Bundle", themeBundleList, nameof(themeBundleName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
if (themeBundleName != string.Empty && ThemeBundleManager.instance.TryGetThemeBundle(themeBundleName, out ThemeBundle themeBundle))
{
materialNameList = themeBundle.assetList_Material.ConvertAll(x => x.name);
var objectNameDropdown =
inspector.GenerateDropdown(this, materialSettings, "Material Name", materialNameList, nameof(materialName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
}
else
{
materialNameList = new List<string>(); // 防止为null
var objectNameDropdown =
inspector.GenerateDropdown(this, materialSettings, "Material Name", materialNameList, nameof(materialName));
objectNameDropdown.dropdown.interactable = false;
} // 如果没有选择主题包,则材质名称下拉框不可用
var setMaterialButton = inspector.GenerateButton(this, materialSettings, "Set Material", () =>
{
particlesContainer.SetParticleMaterial(themeBundleName, materialName);
});
if (themeBundleName == string.Empty || materialName == string.Empty)
{
setMaterialButton.button.interactable = false;
}
InspectorBuilder.For(this)
.Section("Particle Tracker")
.Toggle(nameof(prewarm), "Prewarm")
.OnChanged(() => particlesContainer.SetPrewarm(prewarm))
.InputField(nameof(playTime), "Play Time")
.InputField(nameof(stopTime), "Stop Time")
.Section("Shape")
.Toggle(nameof(is3D), "Is 3D")
.OnChanged(SetShape)
.InputField(nameof(width), "Width")
.OnChanged(SetShape)
.Vector3Field(nameof(extendDirection), "Extend Direction")
.OnChanged(SetShape)
.Section("Emission")
.InputField(nameof(density), "Density")
.OnChanged(() => particlesContainer.SetDensity(density))
.InputField(nameof(lifeTime), "Life Time")
.OnChanged(() => particlesContainer.SetLifeTime(lifeTime))
.Section("Orientation")
.Toggle(nameof(isAutoOrient), "Is Auto Orient")
.OnChanged(() => particlesContainer.SetAlignment(isAutoOrient, particleRotation))
.Vector3Field(nameof(particleRotation), "Particle Rotation")
.OnChanged(() => particlesContainer.SetParticleRotation(particleRotation))
.Section("Material")
.Dropdown(nameof(themeBundleName), themeBundleList, "Theme Bundle")
.OnChanged(() => inspectorMain.SetInspector(this))
.Dropdown(nameof(materialName), materialNameList, "Material Name")
.EnabledIf(() => hasThemeBundle)
.OnChanged(() => inspectorMain.SetInspector(this))
.Button("Set Material", () =>
particlesContainer.SetParticleMaterial(themeBundleName, materialName))
.EnabledIf(() => themeBundleName != string.Empty && materialName != string.Empty)
.Build();
}
#endregion
}

View File

@@ -20,81 +20,72 @@ namespace Ichni.RhythmGame
public override void SetUpInspector()
{
base.SetUpInspector();
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
StandardInspectionElement.GenerateForTransform(this); //关于有Transform的元素
IHaveInspection inspection = inspectorMain;
var container = inspector.GenerateContainer("Trail");
// Transform 动画预设
InspectorBuilder.For(this)
.Section("Generate Elements")
.Preset(InspectorBuilder.TransformPreset)
.Build();
var trailSettings = container.GenerateSubcontainer(3);
var visibleTimeLengthInputField =
inspector.GenerateInputField(this, trailSettings, "Visible Time Length", nameof(visibleTimeLength))
.AddListenerFunction(() => trailRenderer.time = visibleTimeLength);
var isAutoOrientToggle =
inspector.GenerateToggle(this, trailSettings, "Is Auto Orient", nameof(isAutoOrient))
.AddListenerFunction(() => trailRenderer.alignment = isAutoOrient ? LineAlignment.View : LineAlignment.TransformZ);
var widthMultiplierInputField =
inspector.GenerateInputField(this, trailSettings, "Width Multiplier", nameof(widthMultiplier))
.AddListenerFunction(() => trailRenderer.widthMultiplier = widthMultiplier);
var widthCurveButton = inspector.GenerateButton(this, trailSettings, "Width Curve", () =>
{
var widthCurveWindow = inspector.GenerateCompositeParameterWindow(this, "Width Curve", nameof(widthCurve));
widthCurveWindow.SetAsCustomCurve();
widthCurveWindow.closeButton.onClick.AddListener(() => trailRenderer.widthCurve = widthCurve);
});
// Material dropdown
bool hasMaterialBundle = !string.IsNullOrEmpty(materialThemeBundleName)
&& ThemeBundleManager.instance != null;
ThemeBundle themeBundle = null;
if (hasMaterialBundle)
hasMaterialBundle = ThemeBundleManager.instance.TryGetThemeBundle(materialThemeBundleName, out themeBundle);
List<string> materialNameList = hasMaterialBundle
? themeBundle.assetList_Material.ConvertAll(x => x.name)
: new List<string>();
// ----------- 新增:材质设置 -----------
var materialSettings = container.GenerateSubcontainer(3);
// 主题包下拉框
if (ThemeBundleManager.instance != null)
{
var themeBundleDropdown = inspector
.GenerateDropdown(this, materialSettings, "Theme Bundle", ThemeBundleManager.instance.selectedThemeBundleList, nameof(materialThemeBundleName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
// 材质名下拉框
if (!string.IsNullOrEmpty(materialThemeBundleName) && ThemeBundleManager.instance.TryGetThemeBundle(materialThemeBundleName, out ThemeBundle themeBundle))
{
List<string> materialNameList = themeBundle.assetList_Material.ConvertAll(x => x.name);
var objectNameDropdown = inspector.GenerateDropdown(this, materialSettings, "Material Name", materialNameList, nameof(materialName))
.AddListenerFunction(() => inspectorMain.SetInspector(this));
}
else
{
var objectNameDropdown = inspector.GenerateDropdown(this, materialSettings, "Material Name", new List<string>(), nameof(materialName));
objectNameDropdown.dropdown.interactable = false;
}
// 应用材质按钮
var applyMaterialButton = inspector.GenerateButton(this, materialSettings, "Apply Material", () =>
{
if (!string.IsNullOrEmpty(materialThemeBundleName) && !string.IsNullOrEmpty(materialName))
InspectorBuilder.For(this)
.Section("Trail")
.InputField(nameof(visibleTimeLength), "Visible Time Length")
.OnChanged(() => trailRenderer.time = visibleTimeLength)
.Toggle(nameof(isAutoOrient), "Is Auto Orient")
.OnChanged(() => trailRenderer.alignment = isAutoOrient ? LineAlignment.View : LineAlignment.TransformZ)
.InputField(nameof(widthMultiplier), "Width Multiplier")
.OnChanged(() => trailRenderer.widthMultiplier = widthMultiplier)
.Button("Width Curve", () =>
{
Material mat = ThemeBundleManager.instance.GetObject<Material>(materialThemeBundleName, materialName);
if (mat != null)
var w = inspection.GenerateCompositeParameterWindow(this, "Width Curve", nameof(widthCurve));
w.SetAsCustomCurve();
w.closeButton.onClick.AddListener(() => trailRenderer.widthCurve = widthCurve);
})
.Section("Trail Material")
.Dropdown(nameof(materialThemeBundleName), ThemeBundleManager.instance?.selectedThemeBundleList ?? new List<string>(), "Theme Bundle")
.OnChanged(() => inspectorMain.SetInspector(this))
.Dropdown(nameof(materialName), materialNameList, "Material Name")
.EnabledIf(() => hasMaterialBundle)
.OnChanged(() => inspectorMain.SetInspector(this))
.Button("Apply Material", () =>
{
if (!string.IsNullOrEmpty(materialThemeBundleName) && !string.IsNullOrEmpty(materialName))
{
renderMaterial = mat;
if (trailRenderer != null)
trailRenderer.material = renderMaterial;
Material mat = ThemeBundleManager.instance.GetObject<Material>(materialThemeBundleName, materialName);
if (mat != null)
{
renderMaterial = mat;
if (trailRenderer != null)
trailRenderer.material = renderMaterial;
}
}
}
});
}
// ----------- 材质设置结束 -----------
var colorSettings = container.GenerateSubcontainer(3);
var gradientColorKeysButton = inspector.GenerateButton(this, colorSettings, "Gradient Color Keys", () =>
{
var gradientWindow = inspector.GenerateCompositeParameterWindow(this, "Gradient Color Keys", nameof(gradient));
gradientWindow.SetAsGradientColorKeys();
gradientWindow.closeButton.onClick.AddListener(() => trailRenderer.colorGradient = gradient);
});
var gradientAlphaKeysButton = inspector.GenerateButton(this, colorSettings, "Gradient Alpha Keys", () =>
{
var gradientWindow = inspector.GenerateCompositeParameterWindow(this, "Gradient Alpha Keys", nameof(gradient));
gradientWindow.SetAsGradientAlphaKeys();
gradientWindow.closeButton.onClick.AddListener(() => trailRenderer.colorGradient = gradient);
});
})
.Section("Trail Colors")
.Button("Gradient Color Keys", () =>
{
var g = inspection.GenerateCompositeParameterWindow(this, "Gradient Color Keys", nameof(gradient));
g.SetAsGradientColorKeys();
g.closeButton.onClick.AddListener(() => trailRenderer.colorGradient = gradient);
})
.Button("Gradient Alpha Keys", () =>
{
var g = inspection.GenerateCompositeParameterWindow(this, "Gradient Alpha Keys", nameof(gradient));
g.SetAsGradientAlphaKeys();
g.closeButton.onClick.AddListener(() => trailRenderer.colorGradient = gradient);
})
.Build();
}
#endregion
}

View File

@@ -58,15 +58,16 @@ namespace Ichni.RhythmGame
#region [] Inspector
public void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Beatmap Container");
var sub = container.GenerateSubcontainer(2);
inspector.GenerateHintText(this, sub, projectName);
inspector.GenerateHintText(this, sub, creatorName);
inspector.GenerateHintText(this, sub, editorVersion);
inspector.GenerateHintText(this, sub, createTime);
inspector.GenerateHintText(this, sub, lastSaveTime);
inspector.GenerateHintText(this, sub, projectPath);
InspectorBuilder.For(this)
.Section("Beatmap Container")
.HintText(projectName).Span(2)
.HintText(creatorName).Span(2)
.HintText(editorVersion).Span(2)
.HintText(createTime).Span(2)
.HintText(lastSaveTime).Span(2)
.HintText(projectPath).Span(2)
.Build();
tagManager?.SetUpInspector();
}
#endregion
@@ -180,27 +181,33 @@ namespace Ichni.Editor
#region [] Inspector
internal void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
var container = inspector.GenerateContainer("Tag Manager");
IHaveInspection inspection = inspectorMain;
for (int i = 0; i < tagMatchers.Count; i++)
{
var matcher = tagMatchers[i];
var sub = container.GenerateSubcontainer(2);
inspector.GenerateHintText(this, sub, $"Name: {matcher.name}");
inspector.GenerateHintText(this, sub, $"Type: {matcher.ElementType?.Name ?? "<null>"}");
var e = inspector.GenerateInputField(sub, "Parameter", matcher.parameterName);
e.AddListenerFunction(() =>
// TagManager 需要为每个 matcher 动态生成带 UnboundInputField 的编辑行,
// 使用 RawSection 处理动态循环
InspectorBuilder.For(this)
.RawSection("Tag Manager", int.MaxValue, (insp, container) =>
{
matcher.parameterName = e.inputField.text;
});
inspector.GenerateButton(this, sub, "Remove", () =>
{
RemoveTagMatcher(matcher);
inspectorMain.SetInspector(EditorManager.instance.projectInformation);
});
}
for (int i = 0; i < tagMatchers.Count; i++)
{
var matcher = tagMatchers[i];
var sub = container.GenerateSubcontainer(2);
insp.GenerateHintText(this, sub, $"Name: {matcher.name}");
insp.GenerateHintText(this, sub, $"Type: {matcher.ElementType?.Name ?? "<null>"}");
var e = insp.GenerateInputField(sub, "Parameter", matcher.parameterName);
e.AddListenerFunction(() =>
{
matcher.parameterName = e.inputField.text;
});
insp.GenerateButton(this, sub, "Remove", () =>
{
RemoveTagMatcher(matcher);
inspectorMain.SetInspector(EditorManager.instance.projectInformation);
});
}
})
.Build();
}
#endregion

View File

@@ -80,22 +80,28 @@ namespace Ichni.RhythmGame
#region [] Inspector
public void SetUpInspector()
{
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
var a = inspector.GenerateContainer("Song Info");
var subsetting = a.GenerateSubcontainer(3);
var c = inspector.GenerateInputField(this, subsetting, "Offset", nameof(offset));
var o = inspector.GenerateInputField(this, subsetting, "Delay", nameof(delay));
var p = inspector.GenerateInputField(this, subsetting, "BPM", nameof(bpm));
UnityAction action = (() =>
{
Debug.Log($"Song Information Updated: {songName}, BPM: {bpm}, Delay: {delay}, Offset: {offset}");
EditorManager.instance.uiManager.timeline.timePointerModule.OnceSpawn();
});
p.AddListenerFunction(action);
o.AddListenerFunction(action);
c.AddListenerFunction(action);
var info = a.GenerateSubcontainer(1);
inspector.GenerateHintText(this, info, songName);
InspectorBuilder.For(this)
.Section("Song Info")
.InputField(nameof(offset), "Offset")
.OnChanged(() =>
{
Debug.Log($"Song Information Updated: {songName}, BPM: {bpm}, Delay: {delay}, Offset: {offset}");
EditorManager.instance.uiManager.timeline.timePointerModule.OnceSpawn();
})
.InputField(nameof(delay), "Delay")
.OnChanged(() =>
{
Debug.Log($"Song Information Updated: {songName}, BPM: {bpm}, Delay: {delay}, Offset: {offset}");
EditorManager.instance.uiManager.timeline.timePointerModule.OnceSpawn();
})
.InputField(nameof(bpm), "BPM")
.OnChanged(() =>
{
Debug.Log($"Song Information Updated: {songName}, BPM: {bpm}, Delay: {delay}, Offset: {offset}");
EditorManager.instance.uiManager.timeline.timePointerModule.OnceSpawn();
})
.HintText(songName).Span(3)
.Build();
}
#endregion

View File

@@ -28,7 +28,6 @@ namespace Ichni.RhythmGame
[HideInInspector]
public bool _isShowingSphere;
[DynamicUI("Is Showing Sphere", Group = "Path Node", Span = 1)]
public bool isShowingSphere
{
get => _isShowingSphere;
@@ -39,7 +38,6 @@ namespace Ichni.RhythmGame
}
}
[DynamicUI("Index", Group = "Path Node", ReadOnly = true, Span = 1)]
public int TrackIndex => track != null && track.trackPathSubmodule != null ? track.trackPathSubmodule.pathNodeList.IndexOf(this) : -1;
#endregion