改改改

重大bug修复:track删除pathnode后不能正确更新

Signed-off-by: TRAfoer <lhf190@outlook.com>
This commit is contained in:
2025-07-10 20:40:03 +08:00
parent 43fae3a34a
commit 135f61a857
24 changed files with 34730 additions and 21708 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -61,8 +61,6 @@ MonoBehaviour:
type: 3}
cameraShakeEffect: {fileID: 5030288017655597913, guid: 46175bea33f87445bbec1389a53da172,
type: 3}
cameraTiltEffect: {fileID: 5030288017655597913, guid: 34f35091439de454483d8f703662fe18,
type: 3}
chromaticAberrationEffect: {fileID: 5030288017655597913, guid: 4d005c2b7c6d64702878b4c578f5970c,
type: 3}
vignetteEffect: {fileID: 5030288017655597913, guid: 7c3d54fe8d65c4f70a69073c45555dae,
@@ -95,6 +93,8 @@ MonoBehaviour:
type: 3}
emissionColorPicker: {fileID: 8936320662031972394, guid: d00706ed05d0c4a55943214fad99b6cd,
type: 3}
hsvDrawer: {fileID: 8967832941118495084, guid: a6e56f21472670046ab4dfe41e9c739f,
type: 3}
generalSecondaryWindow: {fileID: 6108546402767822149, guid: f3b40a60628cd4583bd8f92cacf1ba3e,
type: 3}
compositeParameterWindow: {fileID: 8976586735561836907, guid: 6d98a93f5b5c14ef5b7b125e407ce17d,

View File

@@ -11,13 +11,14 @@ Material:
m_Shader: {fileID: 4800000, guid: 44e8d6dab1446644688189717537509a, type: 3}
m_Parent: {fileID: 0}
m_ModifiedSerializedProperties: 0
m_ValidKeywords: []
m_ValidKeywords:
- _EMISSION_ON
m_InvalidKeywords:
- _RECEIVE_SHADOWS_OFF
- _ZWRITE_ON
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 1
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses:
@@ -128,7 +129,7 @@ Material:
- _DistortionStrengthScaled: 0
- _DstBlend: 0
- _DstBlendAlpha: 0
- _Emission: 0
- _Emission: 1
- _EmissionEnabled: 0
- _EnableExternalAlpha: 0
- _EnvironmentReflections: 1
@@ -170,7 +171,7 @@ Material:
- _CameraFadeParams: {r: 0, g: Infinity, b: 0, a: 0}
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _ColorAddSubDiff: {r: 0, g: 0, b: 0, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _EmissionColor: {r: 8.574187, g: 8.574187, b: 8.574187, a: 1}
- _Flip: {r: 1, g: 1, b: 1, a: 1}
- _RendererColor: {r: 1, g: 1, b: 1, a: 1}
- _SoftParticleFadeParams: {r: 0, g: 0, b: 0, a: 0}

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -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;
}
}
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
});
}
}
}

View File

@@ -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);
}
}

View File

@@ -79,6 +79,7 @@ namespace Ichni.RhythmGame
public void OnDestroy()
{
track.trackPathSubmodule.pathNodeList.Remove(this);
track.trackPathSubmodule.SetPathPoints();
track.Refresh();
print("PathNode " + elementName + " destroyed.");
}

View File

@@ -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);

View File

@@ -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()

View File

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

View 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;
}
}

View File

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

View File

@@ -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;
//采音器

View File

@@ -97,5 +97,5 @@ Material:
- _Color: {r: 0, g: 0, b: 0, a: 0}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _Tint: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
- _Tint2: {r: 0.39999998, g: 0.39999998, b: 0.39999998, a: 0.5}
- _Tint2: {r: 0.5, g: 0.5, b: 0.5, a: 0.5}
m_BuildTextureStacks: []

View File

@@ -2114,11 +2114,11 @@
}
},{
"__type" : "Ichni.RhythmGame.Beatmap.TrackRendererSubmoduleAutoOrient_BM,Assembly-CSharp",
"materialThemeBundleName" : "departure_to_multiverse",
"materialName" : "EnergyTrail0",
"enableEmission" : true,
"materialThemeBundleName" : "Please Select...",
"materialName" : "Please Select...",
"enableEmission" : false,
"emissionIntensity" : 4,
"zWrite" : false,
"zWrite" : true,
"attachedElementGuid" : {
"value" : "7fd4dbfe-ed4a-4c45-8b54-9ce497808b5c"
}
@@ -2166,9 +2166,9 @@
},{
"__type" : "Ichni.RhythmGame.Beatmap.ColorSubmodule_BM,Assembly-CSharp",
"originalBaseColor" : {
"r" : 1,
"r" : 0.0961389542,
"g" : 0,
"b" : 0,
"b" : 1,
"a" : 1
},
"emissionEnabled" : false,
@@ -7409,10 +7409,10 @@
},{
"__type" : "Ichni.RhythmGame.Beatmap.ColorSubmodule_BM,Assembly-CSharp",
"originalBaseColor" : {
"r" : 1,
"g" : 1,
"r" : 0,
"g" : 0.5528357,
"b" : 1,
"a" : 1
"a" : 0.128183112
},
"emissionEnabled" : true,
"originalEmissionColor" : {

View File

@@ -19,8 +19,8 @@
"__type" : "Ichni.RhythmGame.Beatmap.TransformSubmodule_BM,Assembly-CSharp",
"originalPosition" : {
"x" : 0,
"y" : 0,
"z" : 0
"y" : -10,
"z" : 10
},
"originalEulerAngles" : {
"x" : 0,
@@ -115,8 +115,8 @@
},{
"__type" : "Ichni.RhythmGame.Beatmap.TransformSubmodule_BM,Assembly-CSharp",
"originalPosition" : {
"x" : -8,
"y" : 0,
"x" : 0,
"y" : 10,
"z" : 0
},
"originalEulerAngles" : {
@@ -144,7 +144,7 @@
"__type" : "Ichni.RhythmGame.Beatmap.ColorSubmodule_BM,Assembly-CSharp",
"originalBaseColor" : {
"r" : 1,
"g" : 0,
"g" : 1,
"b" : 1,
"a" : 1
},
@@ -203,8 +203,8 @@
},{
"__type" : "Ichni.RhythmGame.Beatmap.ColorSubmodule_BM,Assembly-CSharp",
"originalBaseColor" : {
"r" : 0,
"g" : 0,
"r" : 1,
"g" : 1,
"b" : 1,
"a" : 1
},
@@ -236,7 +236,7 @@
"__type" : "Ichni.RhythmGame.Beatmap.TransformSubmodule_BM,Assembly-CSharp",
"originalPosition" : {
"x" : 0,
"y" : 0,
"y" : 10,
"z" : 30
},
"originalEulerAngles" : {
@@ -263,7 +263,7 @@
},{
"__type" : "Ichni.RhythmGame.Beatmap.ColorSubmodule_BM,Assembly-CSharp",
"originalBaseColor" : {
"r" : 0,
"r" : 1,
"g" : 1,
"b" : 1,
"a" : 1
@@ -571,7 +571,34 @@
"effectTime" : 0.2
}
],"GeneralJudge":[
{
"__type" : "Ichni.RhythmGame.Beatmap.CameraZoomEffect_BM,Assembly-CSharp",
"duration" : 1,
"relativeZoom" : -20,
"zoomCurve" : {
"keys" : [
{
"time" : 0,
"value" : 0,
"inTangent" : 0,
"outTangent" : 0
},{
"time" : 0.5,
"value" : 1,
"inTangent" : 0,
"outTangent" : 0
},{
"time" : 1,
"value" : 0,
"inTangent" : 0,
"outTangent" : 0
}
],
"preWrapMode" : 8,
"postWrapMode" : 8
},
"effectTime" : 0
}
],"StartHold":[
],"Holding":[
@@ -658,7 +685,7 @@
]
},
"trackPercent" : {
"value" : 1,
"value" : 0.7573288,
"currentAnimationIndex" : 0,
"animations" : [
{
@@ -859,8 +886,8 @@
"__type" : "Ichni.RhythmGame.Beatmap.ColorSubmodule_BM,Assembly-CSharp",
"originalBaseColor" : {
"r" : 1,
"g" : 1,
"b" : 1,
"g" : 0.870243967,
"b" : 0,
"a" : 1
},
"emissionEnabled" : false,
@@ -892,7 +919,7 @@
"originalPosition" : {
"x" : 0,
"y" : 10,
"z" : 1
"z" : 50
},
"originalEulerAngles" : {
"x" : 0,
@@ -918,9 +945,9 @@
},{
"__type" : "Ichni.RhythmGame.Beatmap.ColorSubmodule_BM,Assembly-CSharp",
"originalBaseColor" : {
"r" : 1,
"r" : 0,
"g" : 1,
"b" : 1,
"b" : 0.004379511,
"a" : 1
},
"emissionEnabled" : false,
@@ -1057,7 +1084,7 @@
},{
"__type" : "Ichni.RhythmGame.Beatmap.GameCamera_BM,Assembly-CSharp",
"cameraViewType" : 0,
"perspectiveAngle" : 60,
"perspectiveAngle" : 41.3599319,
"orthographicSize" : 10,
"elementName" : "New Game Camera",
"tags" : [
@@ -1154,14 +1181,21 @@
}
},{
"__type" : "Ichni.RhythmGame.Beatmap.ParticleTracker_BM,Assembly-CSharp",
"playTime" : 0,
"stopTime" : 10,
"width" : 10,
"density" : 100,
"prewarm" : true,
"isAutoOrient" : true,
"playTime" : 1,
"stopTime" : 10,
"is3D" : false,
"width" : 10,
"extendDirection" : {
"x" : 1,
"y" : 0,
"z" : 0
},
"density" : 5,
"lifeTime" : 5,
"isAutoOrient" : false,
"particleRotation" : {
"x" : 0,
"x" : 90,
"y" : 0,
"z" : 0
},
@@ -1172,11 +1206,196 @@
],
"elementGuid" : {
"value" : "7dbb4c90-d401-42b0-85d6-6aed1d3d1ef5"
"value" : "d62acd1e-888f-4e2a-b766-c0dead3c203f"
},
"attachedElementGuid" : {
"value" : "266d9898-21fd-4a93-86b9-6166399a5e8f"
}
},{
"__type" : "Ichni.RhythmGame.Beatmap.ColorSubmodule_BM,Assembly-CSharp",
"originalBaseColor" : {
"r" : 1,
"g" : 1,
"b" : 1,
"a" : 1
},
"emissionEnabled" : true,
"originalEmissionColor" : {
"r" : 0,
"g" : 1,
"b" : 1,
"a" : 1
},
"originalEmissionIntensity" : 1.5,
"attachedElementGuid" : {
"value" : "d62acd1e-888f-4e2a-b766-c0dead3c203f"
}
},{
"__type" : "Ichni.RhythmGame.Beatmap.CameraFieldOfView_BM,Assembly-CSharp",
"fieldOfView" : {
"animatedFloatList" : [
{
"startValue" : 30,
"endValue" : 60,
"startTime" : 0,
"endTime" : 10,
"animationCurveType" : 0
}
]
},
"elementName" : "New Field of View",
"tags" : [
],
"elementGuid" : {
"value" : "a65fb169-1256-4ef9-a36f-4a4a752359fe"
},
"attachedElementGuid" : {
"value" : "1aa98d0a-6830-4680-8899-c02c6833b8f9"
}
},{
"__type" : "Ichni.RhythmGame.Beatmap.TimeDurationSubmodule_BM,Assembly-CSharp",
"isOverridingDuration" : false,
"startTime" : -32767,
"endTime" : 32767,
"attachedElementGuid" : {
"value" : "a65fb169-1256-4ef9-a36f-4a4a752359fe"
}
},{
"__type" : "Ichni.RhythmGame.Beatmap.SkyboxSubsetter_BM,Assembly-CSharp",
"skyBoxThemeBundleList" : [
"departure_to_multiverse","departure_to_multiverse","departure_to_multiverse","departure_to_multiverse"
],
"skyboxNameList" : [
"DTM_Skybox_BlueprintBlue","DTM_Skybox_BlueprintDark","DTM_Skybox_BlueprintWhite","DTM_Skybox_BlueprintBlue"
],
"blendTimeList" : [
2,5
],
"blendSpeedList" : [
1,0.5
],
"elementName" : "New Skybox Subsetter",
"tags" : [
],
"elementGuid" : {
"value" : "b526ff54-e6f3-48bf-901a-5c1cae6bb5de"
},
"attachedElementGuid" : {
"value" : "b2d480f8-ee18-456f-a2e0-b6f29a52ca86"
}
},{
"__type" : "Ichni.RhythmGame.Beatmap.ParticleTracker_BM,Assembly-CSharp",
"prewarm" : false,
"playTime" : 0,
"stopTime" : 111,
"is3D" : true,
"width" : 1,
"extendDirection" : {
"x" : 0,
"y" : 0,
"z" : 0
},
"density" : 100,
"lifeTime" : 1,
"isAutoOrient" : true,
"particleRotation" : {
"x" : -90,
"y" : 0,
"z" : 0
},
"materialThemeBundleName" : "basic",
"materialName" : "DTM_Skybox_BlueprintBlue",
"elementName" : "New Particle Tracker",
"tags" : [
],
"elementGuid" : {
"value" : "9c234d01-3dbf-45d0-bac6-4c926e27c5b0"
},
"attachedElementGuid" : {
"value" : "771b0b4b-dfd7-49d8-9919-a3930fd2ec4c"
}
},{
"__type" : "Ichni.RhythmGame.Beatmap.ColorSubmodule_BM,Assembly-CSharp",
"originalBaseColor" : {
"r" : 1,
"g" : 1,
"b" : 1,
"a" : 1
},
"emissionEnabled" : true,
"originalEmissionColor" : {
"r" : 1,
"g" : 1,
"b" : 1,
"a" : 1
},
"originalEmissionIntensity" : 0,
"attachedElementGuid" : {
"value" : "9c234d01-3dbf-45d0-bac6-4c926e27c5b0"
}
},{
"__type" : "Ichni.RhythmGame.Beatmap.PathNode_BM,Assembly-CSharp",
"isShowingSphere" : false,
"elementName" : "New Path Node",
"tags" : [
],
"elementGuid" : {
"value" : "21875719-e0da-4a97-9d09-52630171a5e6"
},
"attachedElementGuid" : {
"value" : "771b0b4b-dfd7-49d8-9919-a3930fd2ec4c"
}
},{
"__type" : "Ichni.RhythmGame.Beatmap.TransformSubmodule_BM,Assembly-CSharp",
"originalPosition" : {
"x" : 0,
"y" : 10,
"z" : 100
},
"originalEulerAngles" : {
"x" : 0,
"y" : 0,
"z" : 0
},
"originalScale" : {
"x" : 1,
"y" : 1,
"z" : 1
},
"attachedElementGuid" : {
"value" : "21875719-e0da-4a97-9d09-52630171a5e6"
}
},{
"__type" : "Ichni.RhythmGame.Beatmap.TimeDurationSubmodule_BM,Assembly-CSharp",
"isOverridingDuration" : false,
"startTime" : -32767,
"endTime" : 32767,
"attachedElementGuid" : {
"value" : "21875719-e0da-4a97-9d09-52630171a5e6"
}
},{
"__type" : "Ichni.RhythmGame.Beatmap.ColorSubmodule_BM,Assembly-CSharp",
"originalBaseColor" : {
"r" : 0,
"g" : 1,
"b" : 0.004379511,
"a" : 1
},
"emissionEnabled" : false,
"originalEmissionColor" : {
"r" : 0,
"g" : 0,
"b" : 0,
"a" : 1
},
"originalEmissionIntensity" : 0,
"attachedElementGuid" : {
"value" : "21875719-e0da-4a97-9d09-52630171a5e6"
}
}
],
"attachedElementGuid" : {

File diff suppressed because it is too large Load Diff

View File

@@ -4847,33 +4847,14 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
serializationData:
SerializedFormat: 2
SerializedBytes:
SerializedFormat: 0
SerializedBytes: 29010b00000065006c0065006d0065006e00740047007500690064000000000000000000000000000000000001010d0000007300750062006d006f00640075006c0065004c006900730074002f00000000015e000000530079007300740065006d002e0043006f006c006c0065006300740069006f006e0073002e00470065006e0065007200690063002e004c00690073007400600031005b005b004900630068006e0069002e00520068007900740068006d00470061006d0065002e005300750062006d006f00640075006c00650042006100730065002c00200041007300730065006d0062006c0079002d004300530068006100720070005d005d002c0020006d00730063006f0072006c00690062000000000006000000000000000007052d010b00000065006e00610062006c00650054007900700065007300
ReferencedUnityObjects: []
SerializedBytesString:
Prefab: {fileID: 0}
PrefabModificationsReferencedUnityObjects: []
PrefabModifications: []
SerializationNodes:
- Name: elementGuid
Entry: 2
Data: 00000000000000000000000000000000
- Name: submoduleList
Entry: 7
Data: 0|System.Collections.Generic.List`1[[Ichni.RhythmGame.SubmoduleBase,
Assembly-CSharp]], mscorlib
- Name:
Entry: 12
Data: 0
- Name:
Entry: 13
Data:
- Name:
Entry: 8
Data:
- Name: enableTypes
Entry: 6
Data:
SerializationNodes: []
elementName:
tags: []
parentElement: {fileID: 0}
@@ -14739,7 +14720,7 @@ TrailRenderer:
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 2bb7915e218d4874f98e5f5201e984de, type: 2}
- {fileID: 2100000, guid: 8af6dd7f0725540388b84a4697118bb9, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
@@ -14770,7 +14751,7 @@ TrailRenderer:
m_Curve:
- serializedVersion: 3
time: 0
value: 1
value: 0.10227203
inSlope: 0
outSlope: 0
tangentMode: 0