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; public DynamicUIBaseColorPicker baseColorPicker; void Start() { _rectTransform = _rawImage.GetComponent(); // 初始化 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.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.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(); 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; } if (baseColorPicker != null) { // 同步到BaseColorPicker baseColorPicker.SliderChangeWithoutNofication(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(); 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; } }