4
.gitignore
vendored
4
.gitignore
vendored
@@ -46,6 +46,7 @@ ExportedObj/
|
||||
*.mdb
|
||||
*.opendb
|
||||
*.VC.db
|
||||
*.DS_Store
|
||||
|
||||
# Unity3D generated meta files
|
||||
*.pidb.meta
|
||||
@@ -61,7 +62,8 @@ sysinfo.txt
|
||||
*.unitypackage
|
||||
*.unitypackage.meta
|
||||
*.app
|
||||
|
||||
/[Aa]ssets/FR2_Cache.asset
|
||||
#这玩意好大
|
||||
# Crashlytics generated file
|
||||
crashlytics-build.properties
|
||||
|
||||
|
||||
7
Assets/NLayer/NLayer.csproj.meta
Normal file
7
Assets/NLayer/NLayer.csproj.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6dbdd314784e80440b48088e6357c1ef
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -2020,6 +2020,7 @@ MonoBehaviour:
|
||||
isEmission: 0
|
||||
emissionObj: {fileID: 0}
|
||||
emissionInput: {fileID: 0}
|
||||
baseColorPicker: {fileID: 0}
|
||||
--- !u!225 &1119795976362648617
|
||||
CanvasGroup:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@@ -2989,7 +2989,7 @@ RectTransform:
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 47}
|
||||
m_SizeDelta: {x: 500, y: 394}
|
||||
m_SizeDelta: {x: 100, y: 394}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!114 &7396740820777350136
|
||||
MonoBehaviour:
|
||||
|
||||
@@ -5,6 +5,7 @@ using Ichni.RhythmGame;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Ichni.Editor
|
||||
@@ -71,14 +72,17 @@ namespace Ichni.Editor
|
||||
inputFieldBaseA.text = sliderA.value.ToString();
|
||||
ApplyParameters();
|
||||
}
|
||||
public void SliderChangeWithoutNofication(Color color)
|
||||
public void SliderChangeWithoutNotification(Color color)
|
||||
{
|
||||
// 仅更新UI,不触发事件
|
||||
sliderR.SetValueWithoutNotify(color.r);
|
||||
sliderG.SetValueWithoutNotify(color.g);
|
||||
sliderB.SetValueWithoutNotify(color.b);
|
||||
sliderA.SetValueWithoutNotify(color.a);
|
||||
|
||||
inputFieldBaseR.SetTextWithoutNotify(color.r.ToString());
|
||||
inputFieldBaseG.SetTextWithoutNotify(color.g.ToString());
|
||||
inputFieldBaseB.SetTextWithoutNotify(color.b.ToString());
|
||||
inputFieldBaseA.SetTextWithoutNotify(color.a.ToString());
|
||||
// 不调用ApplyParameters以避免重复更新
|
||||
colorPreview.color = new Color(sliderR.value, sliderG.value, sliderB.value, sliderA.value);
|
||||
}
|
||||
@@ -97,5 +101,36 @@ namespace Ichni.Editor
|
||||
|
||||
return this;
|
||||
}
|
||||
private void Update()
|
||||
{
|
||||
if (RectTransformUtility.RectangleContainsScreenPoint(colorPreview.rectTransform, Mouse.current.position.ReadValue())
|
||||
|| RectTransformUtility.RectangleContainsScreenPoint(hsvDrawer?.previewImage.rectTransform, Mouse.current.position.ReadValue()))
|
||||
{
|
||||
if (Mouse.current.leftButton.wasPressedThisFrame)//快速复制粘贴颜色
|
||||
{
|
||||
// 复制颜色到剪贴板
|
||||
GUIUtility.systemCopyBuffer = ColorUtility.ToHtmlStringRGBA(new Color(sliderR.value, sliderG.value, sliderB.value, sliderA.value));
|
||||
LogWindow.Log("Color copied to clipboard: " + GUIUtility.systemCopyBuffer);
|
||||
}
|
||||
else if (Mouse.current.rightButton.wasPressedThisFrame)
|
||||
{
|
||||
if (GUIUtility.systemCopyBuffer != null && GUIUtility.systemCopyBuffer != "")
|
||||
{
|
||||
// 从剪贴板粘贴颜色
|
||||
Color pastedColor;
|
||||
if (ColorUtility.TryParseHtmlString("#" + GUIUtility.systemCopyBuffer, out pastedColor))
|
||||
{
|
||||
SliderChangeWithoutNotification(pastedColor);
|
||||
ApplyParameters();
|
||||
LogWindow.Log("Color pasted from clipboard: " + pastedColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Failed to parse color from clipboard: " + GUIUtility.systemCopyBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using Ichni.RhythmGame;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.UI;
|
||||
|
||||
@@ -114,5 +115,47 @@ namespace Ichni.Editor
|
||||
|
||||
return this;
|
||||
}
|
||||
public void SliderChangeWithoutNotification(Color color)
|
||||
{
|
||||
sliderR.SetValueWithoutNotify(color.r);
|
||||
sliderG.SetValueWithoutNotify(color.g);
|
||||
sliderB.SetValueWithoutNotify(color.b);
|
||||
inputFieldEmissionI.SetTextWithoutNotify(color.a.ToString());
|
||||
inputFieldEmissionB.SetTextWithoutNotify(color.b.ToString());
|
||||
inputFieldEmissionG.SetTextWithoutNotify(color.g.ToString());
|
||||
inputFieldEmissionR.SetTextWithoutNotify(color.r.ToString());
|
||||
// 不调用ApplyParameters以避免重复更新
|
||||
}
|
||||
private void Update()
|
||||
{
|
||||
if (RectTransformUtility.RectangleContainsScreenPoint(colorPreview.rectTransform, Mouse.current.position.ReadValue())
|
||||
)
|
||||
{
|
||||
if (Mouse.current.leftButton.wasPressedThisFrame)//快速复制粘贴颜色
|
||||
{
|
||||
// 复制颜色到剪贴板
|
||||
GUIUtility.systemCopyBuffer = ColorUtility.ToHtmlStringRGBA(new Color(sliderR.value, sliderG.value, sliderB.value, inputFieldEmissionI.text != "" ? float.Parse(inputFieldEmissionI.text) : 1f));
|
||||
LogWindow.Log("Color copied to clipboard: " + GUIUtility.systemCopyBuffer);
|
||||
}
|
||||
else if (Mouse.current.rightButton.wasPressedThisFrame)
|
||||
{
|
||||
if (GUIUtility.systemCopyBuffer != null && GUIUtility.systemCopyBuffer != "")
|
||||
{
|
||||
// 从剪贴板粘贴颜色
|
||||
Color pastedColor;
|
||||
if (ColorUtility.TryParseHtmlString("#" + GUIUtility.systemCopyBuffer, out pastedColor))
|
||||
{
|
||||
SliderChangeWithoutNotification(pastedColor);
|
||||
ApplyParameters();
|
||||
LogWindow.Log("Color pasted from clipboard: " + pastedColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("Failed to parse color from clipboard: " + GUIUtility.systemCopyBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,10 +65,10 @@ namespace Ichni.RhythmGame
|
||||
SetEmissionIntensity();
|
||||
SetUV();
|
||||
|
||||
if (track.trackTimeSubmodule is TrackTimeSubmoduleMovable)
|
||||
if (track.trackTimeSubmodule is TrackTimeSubmoduleMovable trackTimeSubmoduleMovable)
|
||||
{
|
||||
meshGenerator.clipFrom = 0;
|
||||
meshGenerator.clipTo = 0;
|
||||
meshGenerator.clipFrom = trackTimeSubmoduleMovable.tailPercent;
|
||||
meshGenerator.clipTo = trackTimeSubmoduleMovable.headPercent;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -193,7 +193,7 @@ namespace Ichni.RhythmGame
|
||||
this.splineRenderer.doubleSided = true;
|
||||
this.splineRenderer.clipFrom = 0;
|
||||
this.splineRenderer.clipTo = 1;
|
||||
this.splineRenderer.updateMethod = SplineUser.UpdateMethod.LateUpdate;
|
||||
this.splineRenderer.updateMethod = SplineUser.UpdateMethod.Update;
|
||||
this.meshRenderer.material = renderMaterial;
|
||||
this.splineRenderer.color = Color.white;
|
||||
this.splineRenderer.uvRotation = 90;
|
||||
@@ -281,7 +281,7 @@ namespace Ichni.RhythmGame
|
||||
this.pathGenerator.doubleSided = true;
|
||||
this.pathGenerator.clipFrom = 0;
|
||||
this.pathGenerator.clipTo = 1;
|
||||
this.pathGenerator.updateMethod = SplineUser.UpdateMethod.LateUpdate;
|
||||
this.pathGenerator.updateMethod = SplineUser.UpdateMethod.Update;
|
||||
this.meshRenderer.material = renderMaterial;
|
||||
this.pathGenerator.color = Color.white;
|
||||
this.pathGenerator.uvRotation = 90;
|
||||
@@ -372,7 +372,7 @@ namespace Ichni.RhythmGame
|
||||
this.tubeGenerator.doubleSided = true;
|
||||
this.tubeGenerator.clipFrom = 0;
|
||||
this.tubeGenerator.clipTo = 1;
|
||||
this.tubeGenerator.updateMethod = SplineUser.UpdateMethod.LateUpdate;
|
||||
this.tubeGenerator.updateMethod = SplineUser.UpdateMethod.Update;
|
||||
this.meshRenderer.material = renderMaterial;
|
||||
this.tubeGenerator.color = Color.white;
|
||||
this.tubeGenerator.uvRotation = 90;
|
||||
|
||||
@@ -57,16 +57,61 @@ public partial class HsvDrawer
|
||||
}
|
||||
}
|
||||
|
||||
private Coroutine valueSliderCoroutine;
|
||||
private float pendingValue = -1f;
|
||||
|
||||
// 新增:高低分辨率参数
|
||||
public int highResTextureSize = 256;
|
||||
public int lowResTextureSize = 64;
|
||||
private bool isLowRes = false;
|
||||
|
||||
void OnValueSliderChanged(float newValue)
|
||||
{
|
||||
value = newValue;
|
||||
CreateColorWheelTexture();
|
||||
pendingValue = newValue;
|
||||
|
||||
// 切换到低分辨率
|
||||
if (!isLowRes)
|
||||
{
|
||||
isLowRes = true;
|
||||
CreateColorWheelTexture(true);
|
||||
ApplyTextureToRawImage();
|
||||
}
|
||||
|
||||
if (valueSliderCoroutine != null)
|
||||
StopCoroutine(valueSliderCoroutine);
|
||||
valueSliderCoroutine = StartCoroutine(DelayedRedrawColorWheel());
|
||||
|
||||
// 刷新当前颜色
|
||||
if (pickerIndicator != null)
|
||||
UpdateCurrentColor(pickerIndicator.localPosition);
|
||||
}
|
||||
|
||||
IEnumerator DelayedRedrawColorWheel()
|
||||
{
|
||||
float waitTime = 0.01f;
|
||||
float timer = 0f;
|
||||
|
||||
while (timer < waitTime)
|
||||
{
|
||||
yield return null;
|
||||
timer += Time.unscaledDeltaTime;
|
||||
}
|
||||
// 恢复高分辨率
|
||||
if (isLowRes)
|
||||
{
|
||||
isLowRes = false;
|
||||
CreateColorWheelTexture(false);
|
||||
ApplyTextureToRawImage();
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateColorWheelTexture(false);
|
||||
ApplyTextureToRawImage();
|
||||
}
|
||||
valueSliderCoroutine = null;
|
||||
}
|
||||
|
||||
void OnAlphaSliderChanged(float newAlpha)
|
||||
{
|
||||
// 只更新透明度
|
||||
@@ -82,6 +127,7 @@ public partial class HsvDrawer
|
||||
{
|
||||
StartCoroutine(DraggingColorPicker());
|
||||
}
|
||||
|
||||
}
|
||||
IEnumerator DraggingColorPicker()
|
||||
{
|
||||
@@ -112,47 +158,44 @@ public partial class HsvDrawer
|
||||
yield return null; // 等待下一帧
|
||||
}
|
||||
}
|
||||
void CreateColorWheelTexture()
|
||||
// 整合分辨率逻辑到此方法
|
||||
void CreateColorWheelTexture(bool useLowRes = false)
|
||||
{
|
||||
// 创建方形纹理
|
||||
int targetSize = useLowRes ? lowResTextureSize : highResTextureSize;
|
||||
textureSize = targetSize;
|
||||
|
||||
if (_texture == null || _texture.width != textureSize || _texture.height != textureSize)
|
||||
_texture = new Texture2D(textureSize, textureSize, TextureFormat.RGBA32, false);
|
||||
|
||||
_texture.wrapMode = TextureWrapMode.Clamp;
|
||||
|
||||
Vector2 center = new Vector2(textureSize / 2f, textureSize / 2f);
|
||||
float maxRadius = textureSize / 2f;
|
||||
Vector2 center = new Vector2(textureSize * 0.5f, textureSize * 0.5f);
|
||||
float maxRadius = textureSize * 0.5f;
|
||||
Color[] pixels = new Color[textureSize * textureSize];
|
||||
|
||||
// 遍历所有像素
|
||||
for (int y = 0; y < textureSize; y++)
|
||||
{
|
||||
for (int x = 0; x < textureSize; x++)
|
||||
{
|
||||
Vector2 pixelPos = new Vector2(x, y);
|
||||
Vector2 offset = pixelPos - center;
|
||||
Vector2 offset = new Vector2(x + 0.5f, y + 0.5f) - center;
|
||||
float distance = offset.magnitude;
|
||||
int idx = y * textureSize + x;
|
||||
|
||||
// 在圆形区域内绘制
|
||||
if (distance <= maxRadius)
|
||||
{
|
||||
// 计算角度(0-360°)
|
||||
float angle = Mathf.Atan2(offset.y, offset.x) * Mathf.Rad2Deg;
|
||||
if (angle < 0) angle += 360;
|
||||
|
||||
// 计算饱和度(基于半径比例)
|
||||
if (angle < 0) angle += 360f;
|
||||
float sat = Mathf.Clamp01(distance / maxRadius) * saturation;
|
||||
|
||||
// HSV转RGB
|
||||
Color color = Color.HSVToRGB(angle / 360f, sat, value);
|
||||
_texture.SetPixel(x, y, color);
|
||||
pixels[idx] = Color.HSVToRGB(angle / 360f, sat, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 圆形外透明
|
||||
_texture.SetPixel(x, y, Color.clear);
|
||||
pixels[idx] = Color.clear;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_texture.Apply(); // 应用像素更改
|
||||
_texture.SetPixels(pixels);
|
||||
_texture.Apply();
|
||||
}
|
||||
|
||||
void ApplyTextureToRawImage()
|
||||
@@ -207,7 +250,7 @@ public partial class HsvDrawer
|
||||
if (baseColorPicker != null)
|
||||
{
|
||||
// 同步到BaseColorPicker
|
||||
baseColorPicker.SliderChangeWithoutNofication(currentColor);
|
||||
baseColorPicker.SliderChangeWithoutNotification(currentColor);
|
||||
}
|
||||
ApplyParameters();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user