所有Simple UI Element,以及Composite Parameter Window初步

This commit is contained in:
SoulliesOfficial
2025-02-13 02:04:41 -05:00
parent 8d03acc3cb
commit 96a4d620f5
65 changed files with 10696 additions and 75 deletions

View File

@@ -67,6 +67,17 @@ namespace Ichni.RhythmGame
matchedBM = new Beatmap.Displacement_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM,
positionX.ConvertToBM(), positionY.ConvertToBM(), positionZ.ConvertToBM());
}
public override void SetUpInspector()
{
base.SetUpInspector();
var container = inspector.GenerateContainer("Displacement");
var positionXButton = inspector.GenerateButton(this, container, "Position X",
() =>
{
inspector.GenerateCompositeParameterWindow(this, "Position X", nameof(positionX), typeof(FlexibleFloat));
});
}
}
namespace Beatmap

View File

@@ -8,7 +8,7 @@ namespace Ichni.RhythmGame
/// <summary>
/// 含有颜色属性的次级模块,包括基础颜色(透明度)、发光颜色和发光强度
/// </summary>
public class ColorSubmodule : SubmoduleBase
public partial class ColorSubmodule : SubmoduleBase
{
public Color originalBaseColor;
public bool emissionEnabled;
@@ -76,8 +76,17 @@ namespace Ichni.RhythmGame
{
matchedBM = new ColorSubmodule_BM(attachedGameElement);
}
public override void SetUpInspector()
{
var container = inspector.GenerateContainer("Color");
var baseColor = inspector.GenerateBaseColorPicker(this, container, "Base Color", nameof(originalBaseColor));
var emissionColor = inspector.GenerateEmissionColorPicker(this, container, "Emission Color", nameof(emissionEnabled),
nameof(originalEmissionColor), nameof(originalEmissionIntensity));
}
}
public interface IHaveColorSubmodule
{
public ColorSubmodule colorSubmodule { get; set; }

View File

@@ -2,6 +2,7 @@ using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Serialization;
[CreateAssetMenu(fileName = "BasePrefabsCollection", menuName = "Ichni/BasePrefabsCollection", order = 0)]
public class BasePrefabsCollection : SerializedScriptableObject
@@ -30,13 +31,16 @@ public class BasePrefabsCollection : SerializedScriptableObject
[Title("Effect相关")] public GameObject bloomShake;
[Title("DynamicUI相关")] public GameObject dynamicUIContainer;
[Title("DynamicUI相关-Simple")] public GameObject dynamicUIContainer;
public GameObject inputField;
public GameObject Vec3inputField;
public GameObject Vector3inputField;
public GameObject text;
public GameObject button;
public GameObject toggle;
public GameObject dropdown;
public GameObject baseColorPicker;
public GameObject emissionColorPicker;
[Title("DynamicUI相关-Composite")]
public GameObject compositeParameterWindow;
public GameObject stringUnit;
}

BIN
Assets/Scripts/DynamicUI/.DS_Store vendored Normal file

Binary file not shown.

View File

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

View File

@@ -0,0 +1,18 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DynamicUIAnimatedBoolUnit : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

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

View File

@@ -0,0 +1,18 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DynamicUIAnimatedFloatUnit : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

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

View File

@@ -0,0 +1,18 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DynamicUIAnimatedIntUnit : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

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

View File

@@ -0,0 +1,15 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
namespace Ichni.Editor
{
public abstract class DynamicUICompositeUnit : MonoBehaviour
{
public CompositeParameterWindow compositeParameterWindow;
public Button removeButton;
public abstract void SetUnit(CompositeParameterWindow list, object itemContent);
}
}

View File

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

View File

@@ -0,0 +1,30 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Ichni.Editor
{
public class DynamicUIStringUnit : DynamicUICompositeUnit
{
public TMP_InputField stringInputField;
public override void SetUnit(CompositeParameterWindow list, object itemContent)
{
compositeParameterWindow = list;
stringInputField.text = (string)itemContent;
stringInputField.onEndEdit.AddListener(_ => compositeParameterWindow.ApplyParameters());
removeButton.onClick.AddListener(() =>
{
compositeParameterWindow.RemoveUnit(this);
compositeParameterWindow.ApplyParameters();
});
}
public string GetValue()
{
return stringInputField.text;
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,44 @@
using System.Collections;
using System.Collections.Generic;
using Ichni.RhythmGame;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace Ichni.Editor
{
public class DynamicUIBaseColorPicker : DynamicUIElement
{
public TMP_InputField inputFieldBaseR;
public TMP_InputField inputFieldBaseG;
public TMP_InputField inputFieldBaseB;
public TMP_InputField inputFieldBaseA;
public Image colorPreview;
public override void Initialize(IBaseElement baseElement, string title, string parameterName)
{
base.Initialize(baseElement, title, parameterName);
Color baseColor = (Color)connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement); //获取对应变量的值
inputFieldBaseR.text = baseColor.r.ToString();
inputFieldBaseG.text = baseColor.g.ToString();
inputFieldBaseB.text = baseColor.b.ToString();
inputFieldBaseA.text = baseColor.a.ToString();
inputFieldBaseR.onEndEdit.AddListener(_ => ApplyParameters());
inputFieldBaseG.onEndEdit.AddListener(_ => ApplyParameters());
inputFieldBaseB.onEndEdit.AddListener(_ => ApplyParameters());
inputFieldBaseA.onEndEdit.AddListener(_ => ApplyParameters());
colorPreview.color = baseColor;
}
private void ApplyParameters()
{
Color newValue = new Color(float.Parse(inputFieldBaseR.text), float.Parse(inputFieldBaseG.text),
float.Parse(inputFieldBaseB.text), float.Parse(inputFieldBaseA.text));
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, newValue);
colorPreview.color = newValue;
connectedBaseElement.Refresh();
}
}
}

View File

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

View File

@@ -0,0 +1,28 @@
using System.Collections;
using System.Collections.Generic;
using Ichni.RhythmGame;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace Ichni.Editor
{
public class DynamicUIButton : DynamicUIElement
{
public Button button;
public TMP_Text buttonText;
public void SetText(string buttonText, bool hasTitle)
{
this.buttonText.text = buttonText;
if(!hasTitle) title.gameObject.SetActive(false);
}
public void ApplyFunction(UnityAction function)
{
button.onClick.AddListener(function);
button.onClick.AddListener(connectedBaseElement.Refresh);
}
}
}

View File

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

View File

@@ -0,0 +1,62 @@
using System.Collections;
using System.Collections.Generic;
using Ichni.RhythmGame;
using TMPro;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
namespace Ichni.Editor
{
public class DynamicUIEmissionColorPicker : DynamicUIElement
{
private string emissionEnabledName, colorParameterName, emissionIntensityName;
public Toggle toggleEnableEmission;
public TMP_InputField inputFieldEmissionR;
public TMP_InputField inputFieldEmissionG;
public TMP_InputField inputFieldEmissionB;
public TMP_InputField inputFieldEmissionI;
public Image colorPreview;
public new void Initialize(IBaseElement baseElement, string title,
string emissionEnabledName, string colorParameterName, string emissionIntensityName)
{
base.Initialize(baseElement, title, colorParameterName);
this.emissionEnabledName = emissionEnabledName;
this.colorParameterName = colorParameterName;
this.emissionIntensityName = emissionIntensityName;
bool enableEmission = (bool)connectedBaseElement.GetType().GetField(emissionEnabledName).GetValue(connectedBaseElement);
Color emissionColor = (Color)connectedBaseElement.GetType().GetField(colorParameterName).GetValue(connectedBaseElement);
float emissionIntensity = (float)connectedBaseElement.GetType().GetField(emissionIntensityName).GetValue(connectedBaseElement);
toggleEnableEmission.isOn = enableEmission;
inputFieldEmissionR.text = emissionColor.r.ToString();
inputFieldEmissionG.text = emissionColor.g.ToString();
inputFieldEmissionB.text = emissionColor.b.ToString();
inputFieldEmissionI.text = emissionIntensity.ToString();
toggleEnableEmission.onValueChanged.AddListener(_ => ApplyParameters());
inputFieldEmissionR.onEndEdit.AddListener(_ => ApplyParameters());
inputFieldEmissionG.onEndEdit.AddListener(_ => ApplyParameters());
inputFieldEmissionB.onEndEdit.AddListener(_ => ApplyParameters());
inputFieldEmissionI.onEndEdit.AddListener(_ => ApplyParameters());
colorPreview.color = emissionColor;
}
private void ApplyParameters()
{
bool enableEmission = toggleEnableEmission.isOn;
Color emissionColor = new Color(float.Parse(inputFieldEmissionR.text), float.Parse(inputFieldEmissionG.text),
float.Parse(inputFieldEmissionB.text));
float emissionIntensity = float.Parse(inputFieldEmissionI.text);
connectedBaseElement.GetType().GetField(emissionEnabledName).SetValue(connectedBaseElement, enableEmission);
connectedBaseElement.GetType().GetField(colorParameterName).SetValue(connectedBaseElement, emissionColor);
connectedBaseElement.GetType().GetField(emissionIntensityName).SetValue(connectedBaseElement, emissionIntensity);
colorPreview.color = emissionColor;
connectedBaseElement.Refresh();
}
}
}

View File

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

View File

@@ -0,0 +1,26 @@
using System.Collections;
using System.Collections.Generic;
using Ichni.RhythmGame;
using UnityEngine;
using UnityEngine.UI;
namespace Ichni.Editor
{
public class DynamicUIToggle : DynamicUIElement
{
public Toggle toggle;
public override void Initialize(IBaseElement baseElement, string title, string parameterName)
{
base.Initialize(baseElement, title, parameterName);
toggle.isOn = (bool)connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement); //获取对应变量的值
toggle.onValueChanged.AddListener(ApplyParameters);
}
private void ApplyParameters(bool value)
{
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, value);
connectedBaseElement.Refresh();
}
}
}

View File

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

View File

@@ -28,7 +28,7 @@ namespace Ichni.Editor
inputFieldZ.onEndEdit.AddListener(_ => ApplyParameters());
}
public void ApplyParameters()
private void ApplyParameters()
{
Vector3 newValue = new Vector3(float.Parse(inputFieldX.text), float.Parse(inputFieldY.text), float.Parse(inputFieldZ.text));
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, newValue);

View File

@@ -0,0 +1,75 @@
using System.Collections;
using System.Collections.Generic;
using Ichni.RhythmGame;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace Ichni.Editor
{
public partial class CompositeParameterWindow : MovableWindow
{
public Button addNewUnitButton;
public GameObject unitPrefab;
public IBaseElement connectedBaseElement;
public List<DynamicUICompositeUnit> unitList;
public string parameterName;
public UnityAction ApplyParameters;
public void Initialize(IBaseElement baseElement, string title, string parameterName)
{
this.connectedBaseElement = baseElement;
this.parameterName = parameterName;
this.title.text = title;
unitList = new List<DynamicUICompositeUnit>();
closeButton.onClick.AddListener(() =>
{
ApplyParameters();
Destroy(gameObject);
});
}
public void RemoveUnit(DynamicUICompositeUnit unit)
{
unitList.Remove(unit);
Destroy(unit.gameObject);
}
}
public partial class CompositeParameterWindow
{
public void SetAsStringList()
{
unitPrefab = EditorManager.instance.basePrefabs.stringUnit;
addNewUnitButton.onClick.AddListener(() =>
{
DynamicUIStringUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIStringUnit>();
unitList.Add(unit);
unit.SetUnit(this, "");
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
List<string> list = connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement) as List<string>;
foreach (var item in list)
{
DynamicUIStringUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIStringUnit>();
unitList.Add(unit);
unit.SetUnit(this, item);
}
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
ApplyParameters = () =>
{
List<string> list = new List<string>();
foreach (var unit in unitList)
{
list.Add((unit as DynamicUIStringUnit).GetValue());
Debug.Log((unit as DynamicUIStringUnit).GetValue());
}
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, list);
};
}
}
}

View File

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

View File

@@ -2,14 +2,17 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices.WindowsRuntime;
using DG.Tweening;
using Ichni.RhythmGame;
using UnityEngine;
using UnityEngine.Events;
namespace Ichni.Editor
{
public partial class Inspector : StaticWindow
{
public GameElement connectedGameElement;
public Canvas inspectorCanvas;
public RectTransform inspectorRect;
public List<DynamicUIContainer> containers;
@@ -23,12 +26,21 @@ namespace Ichni.Editor
containers.Clear();
connectedGameElement = gameElement;
connectedGameElement.SetUpInspector();
}
}
public partial class Inspector
{
public CompositeParameterWindow GenerateCompositeParameterWindow(IBaseElement baseElement, string title, string parameterName, Type parameterType)
{
CompositeParameterWindow compositeParameterWindow =
Instantiate(EditorManager.instance.basePrefabs.compositeParameterWindow,
EditorManager.instance.uiManager.inspector.inspectorCanvas.GetComponent<RectTransform>())
.GetComponent<CompositeParameterWindow>();
compositeParameterWindow.Initialize(baseElement, title, parameterName);
return compositeParameterWindow;
}
public DynamicUIContainer GenerateContainer(string title)
{
DynamicUIContainer container =
@@ -49,6 +61,18 @@ namespace Ichni.Editor
return container;
}
public DynamicUIButton GenerateButton(IBaseElement baseElement, DynamicUIContainer container, string buttonText,
UnityAction function, string title = "null")
{
DynamicUIButton button = Instantiate(EditorManager.instance.basePrefabs.button, container.rect)
.GetComponent<DynamicUIButton>();
button.SetText(buttonText, title != "null");
button.Initialize(baseElement, title, "null");
button.ApplyFunction(function);
container.dynamicUIElements.Add(button);
return button;
}
public DynamicUIInputField GenerateInputField(IBaseElement baseElement, DynamicUIContainer container,
string title, string parameterName)
{
@@ -63,12 +87,32 @@ namespace Ichni.Editor
string title, string parameterName)
{
DynamicUIVector3InputField vector3InputField =
Instantiate(EditorManager.instance.basePrefabs.Vec3inputField, container.rect)
Instantiate(EditorManager.instance.basePrefabs.Vector3inputField, container.rect)
.GetComponent<DynamicUIVector3InputField>();
vector3InputField.Initialize(baseElement, title, parameterName);
container.dynamicUIElements.Add(vector3InputField);
return vector3InputField;
}
public DynamicUIBaseColorPicker GenerateBaseColorPicker(IBaseElement baseElement, DynamicUIContainer container,
string title, string parameterName)
{
DynamicUIBaseColorPicker colorPicker = Instantiate(EditorManager.instance.basePrefabs.baseColorPicker, container.rect)
.GetComponent<DynamicUIBaseColorPicker>();
colorPicker.Initialize(baseElement, title, parameterName);
container.dynamicUIElements.Add(colorPicker);
return colorPicker;
}
public DynamicUIEmissionColorPicker GenerateEmissionColorPicker(IBaseElement baseElement, DynamicUIContainer container,
string title, string emissionEnabledName, string emissionColorName, string emissionIntensityName)
{
DynamicUIEmissionColorPicker colorPicker = Instantiate(EditorManager.instance.basePrefabs.emissionColorPicker, container.rect)
.GetComponent<DynamicUIEmissionColorPicker>();
colorPicker.Initialize(baseElement, title, emissionEnabledName, emissionColorName, emissionIntensityName);
container.dynamicUIElements.Add(colorPicker);
return colorPicker;
}
public DynamicUIText GenerateText(IBaseElement baseElement, DynamicUIContainer container, string title,
string parameterName, bool isAlwaysUpdate = false)

View File

@@ -1,18 +1,17 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Serialization;
using UnityEngine.UI;
public class MovableWindow : MonoBehaviour
namespace Ichni.Editor
{
// Start is called before the first frame update
void Start()
public abstract class MovableWindow : MonoBehaviour
{
public RectTransform windowRect;
public Button closeButton;
public TMP_Text title;
public DynamicUIContainer container;
}
// Update is called once per frame
void Update()
{
}
}
}

View File

@@ -4,18 +4,8 @@ using UnityEngine;
namespace Ichni.Editor
{
public class StaticWindow : MonoBehaviour
public abstract class StaticWindow : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
}

View File

@@ -141,11 +141,16 @@ namespace Ichni.RhythmGame
{
public Inspector inspector => EditorManager.instance.uiManager.inspector;
public void SetUpInspector() //被点击时设置第一层Inspector
public virtual void SetUpInspector() //被点击时设置第一层Inspector
{
var container = inspector.GenerateContainer("Element Info");
var nameInputField = inspector.GenerateInputField(this, container, GetType().Name + "'s Name", nameof(elementName));
var guidText = inspector.GenerateText(this, container, "Element GUID", nameof(elementGuid), true);
var tagsListButton = inspector.GenerateButton(this, container, "Tags List", () =>
{
inspector.GenerateCompositeParameterWindow(this, "Tags List", nameof(tags), typeof(List<string>))
.SetAsStringList();
});
foreach (var submodule in submoduleList)
{
submodule.SetUpInspector();

View File

@@ -10,8 +10,7 @@ using UnityEngine;
namespace Ichni.RhythmGame
{
public partial class PathNode : GameElement, IHaveTransformSubmodule, IHaveTimeDurationSubmodule,
IHaveColorSubmodule
public partial class PathNode : GameElement, IHaveTransformSubmodule, IHaveTimeDurationSubmodule, IHaveColorSubmodule
{
public Track track;

View File

@@ -67,10 +67,19 @@ namespace Ichni.RhythmGame
public partial class TrackPathSubmodule
{
override public void SaveBM()
public override void SaveBM()
{
matchedBM = new TrackPathSubmodule_BM(attachedGameElement, this);
}
public override void SetUpInspector()
{
var container = inspector.GenerateContainer("Track Path");
var trackSpaceDropdown =
inspector.GenerateDropdown(this, container, "Space Type", typeof(Track.TrackSpaceType), nameof(trackSpaceType));
var trackSamplingDropdown =
inspector.GenerateDropdown(this, container, "Sampling Type", typeof(Track.TrackSamplingType), nameof(trackSamplingType));
}
}
namespace Beatmap

View File

@@ -53,6 +53,11 @@ namespace Ichni.RhythmGame
{
matchedBM = new Beatmap.TrackRendererSubmoduleAutoOrient_BM(attachedGameElement, this);
}
public override void SetUpInspector()
{
}
}
namespace Beatmap