改改改
重大bug修复:track删除pathnode后不能正确更新 Signed-off-by: TRAfoer <lhf190@outlook.com>
This commit is contained in:
@@ -326,5 +326,77 @@ namespace Ichni.Editor
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void swapDisplacement()
|
||||
{
|
||||
Displacement displacement = inspector.connectedGameElement as Displacement;
|
||||
if (displacement == null)
|
||||
{
|
||||
LogWindow.Log("Please select a Displacement first!", Color.red);
|
||||
return;
|
||||
}
|
||||
foreach (var anim in displacement.positionX.animations)
|
||||
{
|
||||
anim.endValue = -anim.endValue;
|
||||
anim.startValue = -anim.startValue;
|
||||
}
|
||||
foreach (var anim in displacement.positionY.animations)
|
||||
{
|
||||
anim.endValue = -anim.endValue;
|
||||
anim.startValue = -anim.startValue;
|
||||
}
|
||||
foreach (var anim in displacement.positionZ.animations)
|
||||
{
|
||||
anim.endValue = -anim.endValue;
|
||||
anim.startValue = -anim.startValue;
|
||||
}
|
||||
}
|
||||
public static void swapSwirl()
|
||||
{
|
||||
Swirl swirl = inspector.connectedGameElement as Swirl;
|
||||
if (swirl == null)
|
||||
{
|
||||
LogWindow.Log("Please select a Swirl first!", Color.red);
|
||||
return;
|
||||
}
|
||||
foreach (var anim in swirl.eulerAngleX.animations)
|
||||
{
|
||||
anim.endValue = -anim.endValue;
|
||||
anim.startValue = -anim.startValue;
|
||||
}
|
||||
foreach (var anim in swirl.eulerAngleY.animations)
|
||||
{
|
||||
anim.endValue = -anim.endValue;
|
||||
anim.startValue = -anim.startValue;
|
||||
}
|
||||
foreach (var anim in swirl.eulerAngleZ.animations)
|
||||
{
|
||||
anim.endValue = -anim.endValue;
|
||||
anim.startValue = -anim.startValue;
|
||||
}
|
||||
}
|
||||
public static void swapScale()
|
||||
{
|
||||
Scale scale = inspector.connectedGameElement as Scale;
|
||||
if (scale == null)
|
||||
{
|
||||
LogWindow.Log("Please select a Scale first!", Color.red);
|
||||
return;
|
||||
}
|
||||
foreach (var anim in scale.scaleX.animations)
|
||||
{
|
||||
anim.endValue = -anim.endValue;
|
||||
anim.startValue = -anim.startValue;
|
||||
}
|
||||
foreach (var anim in scale.scaleY.animations)
|
||||
{
|
||||
anim.endValue = -anim.endValue;
|
||||
anim.startValue = -anim.startValue;
|
||||
}
|
||||
foreach (var anim in scale.scaleZ.animations)
|
||||
{
|
||||
anim.endValue = -anim.endValue;
|
||||
anim.startValue = -anim.startValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,11 +12,11 @@ namespace Ichni.Editor
|
||||
public abstract class DynamicUIElement : MonoBehaviour
|
||||
{
|
||||
Inspector Inspector => EditorManager.instance.uiManager.inspector;
|
||||
|
||||
|
||||
public TMP_Text title;
|
||||
public CanvasGroup canvasGroup;
|
||||
public IBaseElement connectedBaseElement;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 参数名,通过反射获取饿修改对应变量的值
|
||||
/// </summary>
|
||||
@@ -24,6 +24,7 @@ namespace Ichni.Editor
|
||||
|
||||
public virtual void Initialize(IBaseElement baseElement, string title, string parameterName)
|
||||
{
|
||||
if (canvasGroup == null) canvasGroup = gameObject.AddComponent<CanvasGroup>();
|
||||
this.connectedBaseElement = baseElement;
|
||||
this.parameterName = parameterName;
|
||||
if (title != string.Empty)
|
||||
@@ -50,7 +51,7 @@ namespace Ichni.Editor
|
||||
|
||||
public abstract DynamicUIElement AddListenerFunction(UnityAction action);
|
||||
}
|
||||
|
||||
|
||||
public interface IHaveAutoUpdate
|
||||
{
|
||||
public bool isAutoUpdate { get; set; }
|
||||
@@ -59,12 +60,12 @@ namespace Ichni.Editor
|
||||
|
||||
public void UpdateContent()
|
||||
{
|
||||
if(isAutoUpdate && isReceiving)
|
||||
if (isAutoUpdate && isReceiving)
|
||||
{
|
||||
ApplyContent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void ApplyContent();
|
||||
}
|
||||
}
|
||||
@@ -212,5 +212,16 @@ namespace Ichni.Editor
|
||||
subcontainer.dynamicUIElements.Add(stringListDropdown);
|
||||
return stringListDropdown;
|
||||
}
|
||||
|
||||
// 新增:HSV色盘生成方法
|
||||
public HsvDrawer GenerateHsvDrawer(IBaseElement baseElement, DynamicUISubcontainer subcontainer, string title, string parameterName)
|
||||
{
|
||||
HsvDrawer hsvDrawer = Object
|
||||
.Instantiate(EditorManager.instance.basePrefabs.hsvDrawer, subcontainer.rect)
|
||||
.GetComponent<HsvDrawer>();
|
||||
hsvDrawer.Initialize(baseElement, title, parameterName);
|
||||
subcontainer.dynamicUIElements.Add(hsvDrawer);
|
||||
return hsvDrawer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ namespace Ichni.Editor
|
||||
public Button clipSaveButton;
|
||||
public Button clipLoadButton;
|
||||
public Button beatmapToolsButton;
|
||||
|
||||
|
||||
[Title("Windows")]
|
||||
public GeneralSecondaryWindow clipManagementWindow;
|
||||
|
||||
@@ -40,17 +40,17 @@ namespace Ichni.Editor
|
||||
beatmapToolsButton.onClick.AddListener(GenerateBeatmapToolsWindow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public partial class ToolBar
|
||||
{
|
||||
private void GenerateEscapeConfirmWindow()
|
||||
{
|
||||
GeneralSecondaryWindow escapeConfirmWindow =
|
||||
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
||||
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
||||
EditorManager.instance.uiManager.mainPage.mainCanvas.GetComponent<RectTransform>()).GetComponent<GeneralSecondaryWindow>();
|
||||
|
||||
|
||||
escapeConfirmWindow.Initialize("Confirm Escape");
|
||||
|
||||
|
||||
var container = escapeConfirmWindow.GenerateContainer();
|
||||
var clipSettings = container.GenerateSubcontainer(3);
|
||||
var applyClipButton = escapeConfirmWindow.GenerateButton(clipSettings, "Yes", () =>
|
||||
@@ -62,15 +62,15 @@ namespace Ichni.Editor
|
||||
escapeConfirmWindow.closeButton.onClick.Invoke();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void GenerateReloadConfirmWindow()
|
||||
{
|
||||
GeneralSecondaryWindow escapeConfirmWindow =
|
||||
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
||||
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
||||
EditorManager.instance.uiManager.mainPage.mainCanvas.GetComponent<RectTransform>()).GetComponent<GeneralSecondaryWindow>();
|
||||
|
||||
|
||||
escapeConfirmWindow.Initialize("Confirm Reload");
|
||||
|
||||
|
||||
var container = escapeConfirmWindow.GenerateContainer();
|
||||
var clipSettings = container.GenerateSubcontainer(3);
|
||||
var applyClipButton = escapeConfirmWindow.GenerateButton(clipSettings, "Yes", () =>
|
||||
@@ -82,7 +82,7 @@ namespace Ichni.Editor
|
||||
escapeConfirmWindow.closeButton.onClick.Invoke();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void GenerateSaveClipWindow()
|
||||
{
|
||||
GameElement currentElement = EditorManager.instance.operationManager.currentSelectedElements[0];
|
||||
@@ -100,11 +100,11 @@ namespace Ichni.Editor
|
||||
}
|
||||
|
||||
GeneralSecondaryWindow saveClipWindow =
|
||||
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
||||
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
||||
EditorManager.instance.uiManager.mainPage.mainCanvas.GetComponent<RectTransform>()).GetComponent<GeneralSecondaryWindow>();
|
||||
clipManagementWindow = saveClipWindow;
|
||||
saveClipWindow.Initialize("Save Clip: " + currentElement.elementName, () => clipManagementWindow = null);
|
||||
|
||||
|
||||
var container = saveClipWindow.GenerateContainer();
|
||||
var clipSettings = container.GenerateSubcontainer(3);
|
||||
var clipNameInputField = saveClipWindow.GenerateInputField(clipSettings, "Clip Name", currentElement.elementName);
|
||||
@@ -117,13 +117,13 @@ namespace Ichni.Editor
|
||||
private void GenerateLoadClipWindow()
|
||||
{
|
||||
GameElement currentElement = EditorManager.instance.operationManager.currentSelectedElements[0];
|
||||
|
||||
|
||||
if (currentElement == null)
|
||||
{
|
||||
LogWindow.Log("No Game Element selected.", Color.red);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
GameElement loadTarget = currentElement == EditorManager.instance ? null : currentElement.parentElement;
|
||||
|
||||
if (clipManagementWindow != null)
|
||||
@@ -131,7 +131,7 @@ namespace Ichni.Editor
|
||||
LogWindow.Log("Clip Management Window already exists.", Color.red);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
GeneralSecondaryWindow loadClipWindow =
|
||||
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
||||
EditorManager.instance.uiManager.mainPage.mainCanvas.GetComponent<RectTransform>()).GetComponent<GeneralSecondaryWindow>();
|
||||
@@ -146,12 +146,12 @@ namespace Ichni.Editor
|
||||
EditorManager.instance.projectManager.beatmapClipManager.LoadClip(clipNameInputField.GetValue<string>());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void GenerateMergeWindow()
|
||||
{
|
||||
GeneralSecondaryWindow mergeWindow = Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
||||
EditorManager.instance.uiManager.mainPage.mainCanvas.GetComponent<RectTransform>()).GetComponent<GeneralSecondaryWindow>();
|
||||
|
||||
|
||||
mergeWindow.Initialize("Merge Beatmap");
|
||||
|
||||
var container = mergeWindow.GenerateContainer();
|
||||
@@ -169,11 +169,11 @@ namespace Ichni.Editor
|
||||
private void GenerateBeatmapToolsWindow()
|
||||
{
|
||||
GeneralSecondaryWindow beatmapToolsWindow =
|
||||
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
||||
Instantiate(EditorManager.instance.basePrefabs.generalSecondaryWindow,
|
||||
EditorManager.instance.uiManager.mainPage.mainCanvas.GetComponent<RectTransform>()).GetComponent<GeneralSecondaryWindow>();
|
||||
|
||||
|
||||
beatmapToolsWindow.Initialize("Beatmap Tools", () => clipManagementWindow = null);
|
||||
|
||||
|
||||
var container = beatmapToolsWindow.GenerateContainer("Note Tools");
|
||||
var beatmapToolsSettings = container.GenerateSubcontainer(3);
|
||||
var applyTimeOnNameButton = beatmapToolsWindow.GenerateButton(beatmapToolsSettings, "Apply Time On Note Name", () =>
|
||||
@@ -183,31 +183,32 @@ namespace Ichni.Editor
|
||||
List<Stay> allStays = allNotes.FindAll(x => x is Stay).ConvertAll(x => x as Stay);
|
||||
List<Hold> allHolds = allNotes.FindAll(x => x is Hold).ConvertAll(x => x as Hold);
|
||||
List<Flick> allFlicks = allNotes.FindAll(x => x is Flick).ConvertAll(x => x as Flick);
|
||||
|
||||
|
||||
foreach (var tap in allTaps.Where(tap => tap.elementName == "New Tap" || Regex.IsMatch(tap.elementName, @"Tap \(\d+\)")))
|
||||
{
|
||||
tap.elementName = "Tap (" + tap.exactJudgeTime + ")";
|
||||
tap.Refresh();
|
||||
}
|
||||
|
||||
|
||||
foreach (var stay in allStays.Where(stay => stay.elementName == "New Stay" || Regex.IsMatch(stay.elementName, @"Stay \(\d+\)")))
|
||||
{
|
||||
stay.elementName = "Stay (" + stay.exactJudgeTime + ")";
|
||||
stay.Refresh();
|
||||
}
|
||||
|
||||
|
||||
foreach (var hold in allHolds.Where(hold => hold.elementName == "New Hold" || Regex.IsMatch(hold.elementName, @"Hold \(\d+-\d+\)")))
|
||||
{
|
||||
hold.elementName = "Hold (" + hold.exactJudgeTime + "-" + hold.holdEndTime + ")";
|
||||
hold.Refresh();
|
||||
}
|
||||
|
||||
|
||||
foreach (var flick in allFlicks.Where(flick => flick.elementName == "New Flick" || Regex.IsMatch(flick.elementName, @"Flick \(\d+\)")))
|
||||
{
|
||||
flick.elementName = "Flick (" + flick.exactJudgeTime + ")";
|
||||
flick.Refresh();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ namespace Ichni.RhythmGame
|
||||
|
||||
this.baseColorDirtyMark = false;
|
||||
this.emissionColorDirtyMark = false;
|
||||
|
||||
|
||||
if (!HaveSameSubmodule)
|
||||
{
|
||||
(attachedGameElement as IHaveColorSubmodule).colorSubmodule = this;
|
||||
@@ -88,7 +88,7 @@ namespace Ichni.RhythmGame
|
||||
|
||||
this.baseColorDirtyMark = false;
|
||||
this.emissionColorDirtyMark = false;
|
||||
|
||||
|
||||
if (!HaveSameSubmodule)
|
||||
{
|
||||
(attachedGameElement as IHaveColorSubmodule).colorSubmodule = this;
|
||||
@@ -106,15 +106,21 @@ namespace Ichni.RhythmGame
|
||||
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
|
||||
var container = inspector.GenerateContainer("Color");
|
||||
var subcontainer = container.GenerateSubcontainer(1, 300f);
|
||||
|
||||
|
||||
if ((attachedGameElement as IHaveColorSubmodule).haveBaseColor)
|
||||
{
|
||||
var baseColor = inspector.GenerateBaseColorPicker(this, subcontainer, "Base Color", nameof(originalBaseColor));
|
||||
baseColor.AddListenerFunction(Refresh);
|
||||
// var baseColor = inspector.GenerateBaseColorPicker(this, subcontainer, "Base Color", nameof(originalBaseColor));
|
||||
// baseColor.AddListenerFunction(Refresh);
|
||||
// 新增:HSV轮盘
|
||||
var hsvDrawer = inspector.GenerateHsvDrawer(this, subcontainer, "HSV", nameof(originalBaseColor));
|
||||
hsvDrawer.AddListenerFunction(Refresh);
|
||||
|
||||
if (attachedGameElement.childElementList.Exists(x => x is BaseColorChange))
|
||||
{
|
||||
baseColor.title.text += " (Occupied by Animation)";
|
||||
baseColor.canvasGroup.interactable = false;
|
||||
// baseColor.title.text += " (Occupied by Animation)";
|
||||
// baseColor.canvasGroup.interactable = false;
|
||||
hsvDrawer.title.text += " (Occupied by Animation)";
|
||||
hsvDrawer.canvasGroup.interactable = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +129,7 @@ namespace Ichni.RhythmGame
|
||||
var emissionColor = inspector.GenerateEmissionColorPicker(this, subcontainer, "Emission Color",
|
||||
nameof(emissionEnabled), nameof(originalEmissionColor), nameof(originalEmissionIntensity));
|
||||
emissionColor.AddListenerFunction(Refresh);
|
||||
|
||||
|
||||
if (attachedGameElement.childElementList.Exists(x => x is EmissionColorChange))
|
||||
{
|
||||
emissionColor.title.text += " (Occupied by Animation)";
|
||||
@@ -147,7 +153,7 @@ namespace Ichni.RhythmGame
|
||||
public ColorSubmodule colorSubmodule { get; set; }
|
||||
public virtual bool haveBaseColor => true;
|
||||
public virtual bool haveEmissionColor => false;
|
||||
|
||||
|
||||
public void SetColorObserver()
|
||||
{
|
||||
GameElement attachedGameElement = colorSubmodule.attachedGameElement;
|
||||
@@ -158,7 +164,7 @@ namespace Ichni.RhythmGame
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
bool willRefresh = false;
|
||||
|
||||
if (colorSubmodule.baseColorDirtyMark)
|
||||
@@ -167,14 +173,14 @@ namespace Ichni.RhythmGame
|
||||
colorSubmodule.baseColorDirtyMark = false;
|
||||
willRefresh = true;
|
||||
}
|
||||
|
||||
|
||||
if (colorSubmodule.emissionColorDirtyMark)
|
||||
{
|
||||
//在动画物体中改变currentColor
|
||||
colorSubmodule.emissionColorDirtyMark = false;
|
||||
willRefresh = true;
|
||||
}
|
||||
|
||||
|
||||
if (willRefresh)
|
||||
{
|
||||
attachedGameElement.Refresh();
|
||||
@@ -209,13 +215,13 @@ namespace Ichni.RhythmGame
|
||||
public override void ExecuteBM()
|
||||
{
|
||||
attachedElement = GameElement_BM.GetElement(attachedElementGuid);
|
||||
(attachedElement as IHaveColorSubmodule).colorSubmodule = new ColorSubmodule(attachedElement,
|
||||
(attachedElement as IHaveColorSubmodule).colorSubmodule = new ColorSubmodule(attachedElement,
|
||||
originalBaseColor, emissionEnabled, originalEmissionColor, originalEmissionIntensity);
|
||||
}
|
||||
|
||||
public override void DuplicateBM(GameElement attached)
|
||||
{
|
||||
(attached as IHaveColorSubmodule).colorSubmodule = new ColorSubmodule(attached,
|
||||
(attached as IHaveColorSubmodule).colorSubmodule = new ColorSubmodule(attached,
|
||||
originalBaseColor, emissionEnabled, originalEmissionColor, originalEmissionIntensity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ namespace Ichni.RhythmGame
|
||||
public void OnDestroy()
|
||||
{
|
||||
track.trackPathSubmodule.pathNodeList.Remove(this);
|
||||
track.trackPathSubmodule.SetPathPoints();
|
||||
track.Refresh();
|
||||
print("PathNode " + elementName + " destroyed.");
|
||||
}
|
||||
|
||||
@@ -98,14 +98,11 @@ namespace Ichni.RhythmGame
|
||||
SetUpSplineComputer(trackSpaceType, trackSamplingType);
|
||||
|
||||
|
||||
foreach (var pathNode in pathNodeList)
|
||||
{
|
||||
SetPathNode(pathNode);
|
||||
}
|
||||
|
||||
ClosePath();
|
||||
path.Rebuild(true);
|
||||
}
|
||||
|
||||
public void SortPathnodeInChildren()//emm待用吧
|
||||
{
|
||||
Debug.Log("TrackSort");
|
||||
@@ -127,6 +124,14 @@ namespace Ichni.RhythmGame
|
||||
|
||||
public partial class TrackPathSubmodule
|
||||
{
|
||||
public void SetPathPoints()
|
||||
{
|
||||
path.SetPoints(new SplinePoint[0]);
|
||||
foreach (var pathNode in pathNodeList)
|
||||
{
|
||||
SetPathNode(pathNode);
|
||||
}
|
||||
}
|
||||
public override void SaveBM()
|
||||
{
|
||||
matchedBM = new TrackPathSubmodule_BM(attachedGameElement, this);
|
||||
|
||||
@@ -44,11 +44,13 @@ namespace Ichni.RhythmGame
|
||||
this.materialThemeBundleName = materialThemeBundleName;
|
||||
this.materialName = materialName;
|
||||
Material mat = ThemeBundleManager.instance.GetObject<Material>(materialThemeBundleName, materialName);
|
||||
if (mat != null)
|
||||
if (mat == null)
|
||||
{
|
||||
renderMaterial = mat;
|
||||
meshRenderer.material = renderMaterial;
|
||||
mat = EditorManager.instance.basePrefabs.defaultTrackMaterial;
|
||||
|
||||
}
|
||||
renderMaterial = mat;
|
||||
meshRenderer.material = renderMaterial;
|
||||
}
|
||||
|
||||
public override void Refresh()
|
||||
@@ -136,7 +138,7 @@ namespace Ichni.RhythmGame
|
||||
{
|
||||
if (enableEmission)
|
||||
{
|
||||
meshRenderer.material.EnableKeyword("_EMISSION_ON");
|
||||
meshRenderer.material.EnableKeyword("_EMISSION_ON");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -193,7 +195,7 @@ namespace Ichni.RhythmGame
|
||||
public string materialName;
|
||||
public bool enableEmission;
|
||||
public float emissionIntensity;
|
||||
public bool zWrite;
|
||||
public bool zWrite; // 新增
|
||||
|
||||
public TrackRendererSubmoduleAutoOrient_BM()
|
||||
{
|
||||
@@ -207,7 +209,7 @@ namespace Ichni.RhythmGame
|
||||
materialName = trackRendererSubmodule.materialName;
|
||||
enableEmission = trackRendererSubmodule.enableEmission;
|
||||
emissionIntensity = trackRendererSubmodule.emissionIntensity;
|
||||
|
||||
zWrite = trackRendererSubmodule.zWrite; // 新增
|
||||
}
|
||||
|
||||
public override void ExecuteBM()
|
||||
@@ -273,7 +275,7 @@ namespace Ichni.RhythmGame
|
||||
public string materialName;
|
||||
public bool enableEmission;
|
||||
public float emissionIntensity;
|
||||
public bool zWrite;
|
||||
public bool zWrite; // 新增
|
||||
|
||||
public TrackRendererSubmodulePathGenerator_BM()
|
||||
{
|
||||
@@ -287,6 +289,7 @@ namespace Ichni.RhythmGame
|
||||
materialName = trackRendererSubmodule.materialName;
|
||||
enableEmission = trackRendererSubmodule.enableEmission;
|
||||
emissionIntensity = trackRendererSubmodule.emissionIntensity;
|
||||
zWrite = trackRendererSubmodule.zWrite; // 新增
|
||||
}
|
||||
|
||||
public override void ExecuteBM()
|
||||
@@ -372,7 +375,7 @@ namespace Ichni.RhythmGame
|
||||
public string materialName;
|
||||
public bool enableEmission;
|
||||
public float emissionIntensity;
|
||||
public bool zWrite;
|
||||
public bool zWrite; // 新增
|
||||
public int sideCount;
|
||||
|
||||
public TrackRendererSubmoduleTubeGenerator_BM()
|
||||
@@ -387,6 +390,7 @@ namespace Ichni.RhythmGame
|
||||
materialName = trackRendererSubmodule.materialName;
|
||||
enableEmission = trackRendererSubmodule.enableEmission;
|
||||
emissionIntensity = trackRendererSubmodule.emissionIntensity;
|
||||
zWrite = trackRendererSubmodule.zWrite; // 新增
|
||||
sideCount = trackRendererSubmodule.sideCount;
|
||||
}
|
||||
|
||||
@@ -453,7 +457,7 @@ namespace Ichni.RhythmGame
|
||||
public string materialName;
|
||||
public bool enableEmission;
|
||||
public float emissionIntensity;
|
||||
public bool zWrite;
|
||||
public bool zWrite; // 新增
|
||||
|
||||
public TrackRendererSubmoduleSurface_BM()
|
||||
{
|
||||
@@ -467,6 +471,7 @@ namespace Ichni.RhythmGame
|
||||
materialName = trackRendererSubmodule.materialName;
|
||||
enableEmission = trackRendererSubmodule.enableEmission;
|
||||
emissionIntensity = trackRendererSubmodule.emissionIntensity;
|
||||
zWrite = trackRendererSubmodule.zWrite; // 新增
|
||||
}
|
||||
|
||||
public override void ExecuteBM()
|
||||
|
||||
8
Assets/Scripts/Graphical Tools/HSV Tool.meta
Normal file
8
Assets/Scripts/Graphical Tools/HSV Tool.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7418d8f37ad03114a8009e73d016d9d5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
276
Assets/Scripts/Graphical Tools/HSV Tool/HsvDrawer.cs
Normal file
276
Assets/Scripts/Graphical Tools/HSV Tool/HsvDrawer.cs
Normal file
@@ -0,0 +1,276 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Ichni;
|
||||
using Ichni.Editor;
|
||||
using Ichni.RhythmGame;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public partial class HsvDrawer
|
||||
{
|
||||
[Header("Color Wheel Settings")]
|
||||
public int textureSize = 256; // 纹理尺寸
|
||||
public float saturation = 1f; // 最大饱和度
|
||||
public float value = 1f; // 明度
|
||||
|
||||
[Header("Color Picker Settings")]
|
||||
public RectTransform pickerIndicator; // 取色器指示器
|
||||
public Color currentColor = Color.white; // 当前选中的颜色
|
||||
public Slider valueSlider; // 亮度拖动条
|
||||
public Slider alphaSlider; // 透明度拖动条
|
||||
public RawImage previewImage; // 颜色预览窗
|
||||
|
||||
private Texture2D _texture;
|
||||
public RawImage _rawImage;
|
||||
private RectTransform _rectTransform;
|
||||
|
||||
|
||||
public bool isEmission = false;
|
||||
public GameObject emissionObj;
|
||||
public InputField emissionInput;
|
||||
void Start()
|
||||
{
|
||||
_rectTransform = _rawImage.GetComponent<RectTransform>(); // 初始化
|
||||
CreateColorWheelTexture();
|
||||
ApplyTextureToRawImage();
|
||||
|
||||
if (valueSlider != null)
|
||||
{
|
||||
valueSlider.minValue = 0f;
|
||||
valueSlider.maxValue = 1f;
|
||||
valueSlider.value = value;
|
||||
valueSlider.onValueChanged.AddListener(OnValueSliderChanged);
|
||||
}
|
||||
if (alphaSlider != null)
|
||||
{
|
||||
alphaSlider.minValue = 0f;
|
||||
alphaSlider.maxValue = 1f;
|
||||
alphaSlider.value = 1f;
|
||||
alphaSlider.onValueChanged.AddListener(OnAlphaSliderChanged);
|
||||
}
|
||||
if (previewImage != null)
|
||||
{
|
||||
previewImage.color = currentColor;
|
||||
}
|
||||
}
|
||||
|
||||
void OnValueSliderChanged(float newValue)
|
||||
{
|
||||
value = newValue;
|
||||
CreateColorWheelTexture();
|
||||
ApplyTextureToRawImage();
|
||||
// 刷新当前颜色
|
||||
if (pickerIndicator != null)
|
||||
UpdateCurrentColor(pickerIndicator.localPosition);
|
||||
}
|
||||
|
||||
void OnAlphaSliderChanged(float newAlpha)
|
||||
{
|
||||
// 只更新透明度
|
||||
currentColor.a = newAlpha;
|
||||
if (previewImage != null)
|
||||
previewImage.color = currentColor;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
// 鼠标点击色轮区域即可拖动
|
||||
if (Mouse.current.leftButton.wasPressedThisFrame && RectTransformUtility.RectangleContainsScreenPoint(_rectTransform, Mouse.current.position.ReadValue()))
|
||||
{
|
||||
StartCoroutine(DraggingColorPicker());
|
||||
}
|
||||
}
|
||||
IEnumerator DraggingColorPicker()
|
||||
{
|
||||
|
||||
while (Mouse.current.leftButton.isPressed)
|
||||
{
|
||||
Vector2 localPosition;
|
||||
RectTransformUtility.ScreenPointToLocalPointInRectangle(_rectTransform, Mouse.current.position.ReadValue(), null, out localPosition);
|
||||
|
||||
// 计算中心和最大半径
|
||||
Vector2 center = _rectTransform.rect.center;
|
||||
float maxRadius = _rectTransform.rect.width / 2f;
|
||||
Vector2 offset = localPosition - center;
|
||||
float distance = offset.magnitude;
|
||||
|
||||
// 如果超出圆形区域,则贴边
|
||||
if (distance > maxRadius)
|
||||
{
|
||||
offset = offset.normalized * maxRadius;
|
||||
localPosition = center + offset;
|
||||
}
|
||||
|
||||
if (pickerIndicator != null)
|
||||
pickerIndicator.localPosition = localPosition;
|
||||
|
||||
UpdateCurrentColor(localPosition);
|
||||
|
||||
yield return null; // 等待下一帧
|
||||
}
|
||||
}
|
||||
void CreateColorWheelTexture()
|
||||
{
|
||||
// 创建方形纹理
|
||||
_texture = new Texture2D(textureSize, textureSize, TextureFormat.RGBA32, false);
|
||||
_texture.wrapMode = TextureWrapMode.Clamp;
|
||||
|
||||
Vector2 center = new Vector2(textureSize / 2f, textureSize / 2f);
|
||||
float maxRadius = textureSize / 2f;
|
||||
|
||||
// 遍历所有像素
|
||||
for (int y = 0; y < textureSize; y++)
|
||||
{
|
||||
for (int x = 0; x < textureSize; x++)
|
||||
{
|
||||
Vector2 pixelPos = new Vector2(x, y);
|
||||
Vector2 offset = pixelPos - center;
|
||||
float distance = offset.magnitude;
|
||||
|
||||
// 在圆形区域内绘制
|
||||
if (distance <= maxRadius)
|
||||
{
|
||||
// 计算角度(0-360°)
|
||||
float angle = Mathf.Atan2(offset.y, offset.x) * Mathf.Rad2Deg;
|
||||
if (angle < 0) angle += 360;
|
||||
|
||||
// 计算饱和度(基于半径比例)
|
||||
float sat = Mathf.Clamp01(distance / maxRadius) * saturation;
|
||||
|
||||
// HSV转RGB
|
||||
Color color = Color.HSVToRGB(angle / 360f, sat, value);
|
||||
_texture.SetPixel(x, y, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 圆形外透明
|
||||
_texture.SetPixel(x, y, Color.clear);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_texture.Apply(); // 应用像素更改
|
||||
}
|
||||
|
||||
void ApplyTextureToRawImage()
|
||||
{
|
||||
if (_rawImage == null)
|
||||
_rawImage = GetComponent<RawImage>();
|
||||
|
||||
_rawImage.texture = _texture;
|
||||
_rawImage.color = Color.white; // 确保显示原始颜色
|
||||
}
|
||||
void UpdateCurrentColor(Vector2 localPosition)
|
||||
{
|
||||
Vector2 center = _rectTransform.rect.center;
|
||||
Vector2 offset = localPosition - center;
|
||||
float maxRadius = _rectTransform.rect.width / 2f;
|
||||
|
||||
// 计算半径比例(饱和度)
|
||||
float distance = offset.magnitude;
|
||||
float sat = Mathf.Clamp01(distance / maxRadius) * saturation;
|
||||
|
||||
// 计算角度(色调)
|
||||
float angle = Mathf.Atan2(offset.y, offset.x) * Mathf.Rad2Deg;
|
||||
if (angle < 0) angle += 360;
|
||||
|
||||
// 计算颜色
|
||||
float alpha = alphaSlider != null ? alphaSlider.value : 1f;
|
||||
currentColor = Color.HSVToRGB(angle / 360f, sat, value);
|
||||
currentColor.a = alpha;
|
||||
|
||||
// 更新取色器颜色(使其与背景有对比度)
|
||||
if (pickerIndicator != null)
|
||||
{
|
||||
var img = pickerIndicator.GetComponent<Image>();
|
||||
if (img != null)
|
||||
img.color = (value > 0.5f) ? Color.black : Color.white;
|
||||
}
|
||||
// 若有亮度滑块,保持同步
|
||||
if (valueSlider != null && valueSlider.value != value)
|
||||
{
|
||||
valueSlider.SetValueWithoutNotify(value);
|
||||
}
|
||||
// 若有透明度滑块,保持同步
|
||||
if (alphaSlider != null && alphaSlider.value != alpha)
|
||||
{
|
||||
alphaSlider.SetValueWithoutNotify(alpha);
|
||||
}
|
||||
// 更新预览窗
|
||||
if (previewImage != null)
|
||||
{
|
||||
previewImage.color = currentColor;
|
||||
}
|
||||
ApplyParameters();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public partial class HsvDrawer : DynamicUIElement
|
||||
{
|
||||
private void ApplyParameters()
|
||||
{
|
||||
Color newValue = currentColor;
|
||||
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, newValue);
|
||||
connectedBaseElement.Refresh();
|
||||
}
|
||||
|
||||
// 新增:同步connectedBaseElement的color到色盘
|
||||
public void SyncFromBaseElement()
|
||||
{
|
||||
if (connectedBaseElement == null || string.IsNullOrEmpty(parameterName)) return;
|
||||
Color color = (Color)connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement);
|
||||
currentColor = color;
|
||||
|
||||
// 解析HSV
|
||||
Color.RGBToHSV(color, out float h, out float s, out float v);
|
||||
value = v;
|
||||
if (valueSlider != null)
|
||||
valueSlider.SetValueWithoutNotify(v);
|
||||
if (alphaSlider != null)
|
||||
alphaSlider.SetValueWithoutNotify(color.a);
|
||||
|
||||
// 计算picker位置
|
||||
if (_rectTransform == null)
|
||||
_rectTransform = _rawImage.GetComponent<RectTransform>();
|
||||
Vector2 center = _rectTransform.rect.center;
|
||||
float maxRadius = _rectTransform.rect.width / 2f;
|
||||
float angle = h * 360f * Mathf.Deg2Rad;
|
||||
float radius = s * maxRadius;
|
||||
Vector2 offset = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * radius;
|
||||
Vector2 pickerPos = center + offset;
|
||||
if (pickerIndicator != null)
|
||||
pickerIndicator.localPosition = pickerPos;
|
||||
|
||||
// 更新色盘和预览
|
||||
CreateColorWheelTexture();
|
||||
ApplyTextureToRawImage();
|
||||
if (previewImage != null)
|
||||
previewImage.color = currentColor;
|
||||
}
|
||||
public override void Initialize(IBaseElement baseElement, string title, string parameterName)
|
||||
{
|
||||
base.Initialize(baseElement, title, parameterName);
|
||||
SyncFromBaseElement();
|
||||
}
|
||||
public override DynamicUIElement AddListenerFunction(UnityAction action)
|
||||
{
|
||||
|
||||
valueSlider.onValueChanged.AddListener(_ => action());
|
||||
|
||||
alphaSlider.onValueChanged.AddListener(_ => action());
|
||||
valueSlider.onValueChanged.AddListener(_ => UpdateCurrentColor(pickerIndicator.localPosition));
|
||||
|
||||
alphaSlider.onValueChanged.AddListener(_ => UpdateCurrentColor(pickerIndicator.localPosition));
|
||||
// 拖动色盘时也触发
|
||||
// 这里通过在 UpdateCurrentColor 里调用 action
|
||||
// 但由于没有事件,这里可以考虑用委托或事件,但为兼容性直接调用
|
||||
// 可以在 UpdateCurrentColor 末尾加一行(如果需要多次触发):
|
||||
// action?.Invoke();
|
||||
// 但一般只需响应滑块即可
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
11
Assets/Scripts/Graphical Tools/HSV Tool/HsvDrawer.cs.meta
Normal file
11
Assets/Scripts/Graphical Tools/HSV Tool/HsvDrawer.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81a06df931b999c4e9a0ac510cb0f3ea
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -13,7 +13,7 @@ namespace Ichni.RhythmGame
|
||||
[Title("基础预制体")] public GameObject emptyObject;
|
||||
public GameObject elementFolder;
|
||||
public GameObject gameCamera;
|
||||
|
||||
|
||||
|
||||
[Title("Track相关")] public GameObject track;
|
||||
public GameObject trackDisplay;
|
||||
@@ -29,7 +29,7 @@ namespace Ichni.RhythmGame
|
||||
public GameObject stayNote;
|
||||
public GameObject holdNote;
|
||||
public GameObject flickNote;
|
||||
|
||||
|
||||
[Title("Note 判定UI")] public GameObject fullscreenNearTimeHint;
|
||||
public GameObject areaHint;
|
||||
public GameObject triggerHint;
|
||||
@@ -57,7 +57,8 @@ namespace Ichni.RhythmGame
|
||||
public GameObject stringListDropdown;
|
||||
public GameObject baseColorPicker;
|
||||
public GameObject emissionColorPicker;
|
||||
|
||||
public GameObject hsvDrawer;
|
||||
|
||||
[Title("DynamicUI相关-Composite")] public GameObject generalSecondaryWindow;
|
||||
public GameObject compositeParameterWindow;
|
||||
public GameObject inputFieldUnit;
|
||||
@@ -69,7 +70,7 @@ namespace Ichni.RhythmGame
|
||||
public GameObject gradientColorKeyUnit;
|
||||
public GameObject gradientAlphaKeyUnit;
|
||||
public GameObject stringIntPairUnit;
|
||||
|
||||
|
||||
[Title("图形化动画编辑器")] public GameObject graphicalFlexibleFloatWindow;
|
||||
|
||||
//采音器
|
||||
|
||||
Reference in New Issue
Block a user