@@ -224,7 +224,7 @@ namespace Ichni.Editor
|
||||
processedArgs.Add(a);
|
||||
}
|
||||
// 数字
|
||||
else if (Regex.IsMatch(a, @"^-?\d+(\.\d+)?$"))
|
||||
else if (Regex.IsMatch(a, @"^-?\d+(\.\d+)?([eE][+-]?\d+)?$"))
|
||||
{
|
||||
processedArgs.Add(a);
|
||||
}
|
||||
|
||||
@@ -593,7 +593,30 @@ namespace Ichni.Editor
|
||||
GUIUtility.systemCopyBuffer = result;
|
||||
LogWindow.Log("Colped Done!", Color.green);
|
||||
}
|
||||
|
||||
public static void AdjustPathnodeZ(float OriginZpoint, float scale)
|
||||
{
|
||||
if (inspector.connectedGameElement == null || inspector.connectedGameElement.GetType() != typeof(Track))
|
||||
{
|
||||
LogWindow.Log("Please select a Track first!");
|
||||
return;
|
||||
}
|
||||
Track track = (Track)inspector.connectedGameElement;
|
||||
var pathnodes = track.trackPathSubmodule.pathNodeList;
|
||||
foreach (var pathnode in pathnodes)
|
||||
{
|
||||
if (pathnode.childElementList.OfType<Displacement>().Count() > 0)
|
||||
{
|
||||
LogWindow.Log($"PathNode {pathnode.elementName} has Displacement, which may cause issues", Color.yellow);
|
||||
}
|
||||
float worldZ = pathnode.transform.position.z;
|
||||
float deltaZ = worldZ - OriginZpoint;
|
||||
float newZ = OriginZpoint + deltaZ * scale;
|
||||
pathnode.transform.position = new Vector3(pathnode.transform.position.x, pathnode.transform.position.y, newZ);
|
||||
pathnode.transformSubmodule.originalPosition = pathnode.transform.localPosition;
|
||||
pathnode.transformSubmodule.Refresh();
|
||||
pathnode.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using DG.Tweening;
|
||||
using Ichni;
|
||||
|
||||
using Ichni.RhythmGame;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
@@ -62,51 +65,113 @@ public class EventPoint : MonoBehaviour
|
||||
UpdateValue();
|
||||
ReDraw(value);
|
||||
}
|
||||
public void ReDraw(float value)
|
||||
public IEnumerator GenerateTextureCoroutine(int width, int height, float value)
|
||||
{
|
||||
|
||||
Texture2D Texture = new Texture2D((int)CurveCanvas.rectTransform.sizeDelta.x / 5, (int)CurveCanvas.rectTransform.sizeDelta.y / 5);
|
||||
for (int i = 0; i < Texture.width; i++)
|
||||
Task<Color[]> task = Task.Run(() => GenerateTextureColors(width, height, value));
|
||||
while (!task.IsCompleted)
|
||||
{
|
||||
for (int j = 0; j < Texture.height; j++)
|
||||
{
|
||||
Texture.SetPixel(i, j, new Color(0, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
Texture.Apply();
|
||||
|
||||
|
||||
int LastEventPointY = 0;
|
||||
for (int i = 0; i < Texture.width; i++)
|
||||
{
|
||||
float t = (float)i / Texture.width;
|
||||
int f = (int)(
|
||||
(Texture.height / 2) + (animatedFloat.startValue * value + ((animatedFloat.endValue - animatedFloat.startValue)
|
||||
* AnimationCurveEvaluator.Evaluate(animatedFloat.animationCurveType, t) * value))
|
||||
);
|
||||
|
||||
|
||||
//不是哥们
|
||||
for (int j = LastEventPointY; j < f; j++)
|
||||
{
|
||||
if (j < Texture.height) Texture.SetPixel(i, j, Color.green);
|
||||
else Texture.SetPixel(i, j, Color.red);
|
||||
}
|
||||
for (int j = LastEventPointY; j > f; j--)
|
||||
{
|
||||
if (j > 0) Texture.SetPixel(i, j, Color.green);
|
||||
else Texture.SetPixel(i, j, Color.red);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (f < Texture.height && f > 0) Texture.SetPixel(i, f, Color.green);//丑陋
|
||||
else Texture.SetPixel(i, f, Color.red);
|
||||
LastEventPointY = f;
|
||||
yield return null; // 等待下一帧
|
||||
}
|
||||
Color[] textureColors = task.Result;
|
||||
Texture2D Texture = new Texture2D(width, height);
|
||||
Texture.SetPixels(textureColors);
|
||||
Texture.Apply();
|
||||
CurveCanvas.texture = Texture;
|
||||
// CurveCanvas.color = new Color(1, 1, 1, 0);
|
||||
// CurveCanvas.DOColor(new Color(1, 1, 1, 1), 0.2f).SetEase(Ease.InOutSine);
|
||||
|
||||
}
|
||||
public Color[] GenerateTextureColors(int width, int height, float value)
|
||||
{
|
||||
Color[] pixels = new Color[width * height];
|
||||
|
||||
// 初始化所有像素为透明
|
||||
for (int i = 0; i < pixels.Length; i++)
|
||||
{
|
||||
pixels[i] = new Color(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
int LastEventPointY = 0;
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
float t = (float)i / width;
|
||||
int f = (int)(
|
||||
(height / 2) + (animatedFloat.startValue * value + ((animatedFloat.endValue - animatedFloat.startValue)
|
||||
* AnimationCurveEvaluator.Evaluate(animatedFloat.animationCurveType, t) * value))
|
||||
);
|
||||
|
||||
// 绘制垂直线段 - 保留超出边界的红色标记
|
||||
if (LastEventPointY < f)
|
||||
{
|
||||
for (int j = LastEventPointY; j < f; j++)
|
||||
{
|
||||
// 检查是否超出边界
|
||||
bool isOutOfBounds = j < 0 || j >= height;
|
||||
|
||||
// 计算实际坐标(循环调整)
|
||||
int actualY = j;
|
||||
while (actualY < 0) actualY += height;
|
||||
while (actualY >= height) actualY -= height;
|
||||
|
||||
int index = actualY * width + i;
|
||||
if (index >= 0 && index < pixels.Length)
|
||||
{
|
||||
// 根据是否超出边界设置颜色
|
||||
pixels[index] = isOutOfBounds ? Color.red : Color.green;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = LastEventPointY; j > f; j--)
|
||||
{
|
||||
// 检查是否超出边界
|
||||
bool isOutOfBounds = j < 0 || j >= height;
|
||||
|
||||
// 计算实际坐标(循环调整)
|
||||
int actualY = j;
|
||||
while (actualY < 0) actualY += height;
|
||||
while (actualY >= height) actualY -= height;
|
||||
|
||||
int index = actualY * width + i;
|
||||
if (index >= 0 && index < pixels.Length)
|
||||
{
|
||||
// 根据是否超出边界设置颜色
|
||||
pixels[index] = isOutOfBounds ? Color.red : Color.green;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制当前点 - 保留超出边界的红色标记
|
||||
bool isFOutOfBounds = f < 0 || f >= height;
|
||||
int actualF = f;
|
||||
while (actualF < 0) actualF += height;
|
||||
while (actualF >= height) actualF -= height;
|
||||
|
||||
int currentIndex = actualF * width + i;
|
||||
if (currentIndex >= 0 && currentIndex < pixels.Length)
|
||||
{
|
||||
// 根据是否超出边界设置颜色
|
||||
pixels[currentIndex] = isFOutOfBounds ? Color.red : Color.green;
|
||||
}
|
||||
|
||||
LastEventPointY = f;
|
||||
}
|
||||
|
||||
return pixels;
|
||||
}
|
||||
|
||||
public void ReDraw(float value)
|
||||
{
|
||||
int width = (int)CurveCanvas.rectTransform.sizeDelta.x / 5;
|
||||
int height = (int)CurveCanvas.rectTransform.sizeDelta.y / 5;
|
||||
|
||||
// 获取颜色数组(可在多线程环境中调用)
|
||||
|
||||
// 在主线程中创建和设置纹理(Unity对象操作必须在主线程)
|
||||
StartCoroutine(GenerateTextureCoroutine(width, height, value));
|
||||
|
||||
// 其余的非纹理相关代码保持不变
|
||||
if (NextEventPoint != null)
|
||||
{
|
||||
OvDrawimage.transform.localPosition = new Vector3(RightSide.transform.localPosition.x,
|
||||
@@ -128,8 +193,7 @@ public class EventPoint : MonoBehaviour
|
||||
}
|
||||
else
|
||||
{
|
||||
OvDrawimage.rectTransform.sizeDelta = new Vector2(0, OvDrawimage.rectTransform.sizeDelta.y
|
||||
);
|
||||
OvDrawimage.rectTransform.sizeDelta = new Vector2(0, OvDrawimage.rectTransform.sizeDelta.y);
|
||||
}
|
||||
|
||||
selectButton.transform.localPosition = EvDrawimage.transform.localPosition;
|
||||
@@ -141,7 +205,6 @@ public class EventPoint : MonoBehaviour
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void SelectButtonClick()//unity内:当按钮按下时
|
||||
{
|
||||
if (Locked) return;
|
||||
|
||||
@@ -23,6 +23,12 @@ namespace Ichni.Editor
|
||||
private List<SelectionConnector> lastHitConnectors = new List<SelectionConnector>();
|
||||
private int currentSelectIndex = 0;
|
||||
|
||||
private Vector2 lastMousePosition;
|
||||
private bool cachedIsPointerOverUI;
|
||||
private GameObject cachedHoveredUI;
|
||||
private int uiCheckFrameInterval = 3; // 每3帧检查一次
|
||||
private int frameCount;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
instance = this;
|
||||
@@ -34,7 +40,22 @@ namespace Ichni.Editor
|
||||
|
||||
private void Update()
|
||||
{
|
||||
isPointerOverUI = IsPointerOverUI(out hoveredUI);
|
||||
frameCount++;
|
||||
|
||||
// 只有当鼠标移动或每隔几帧时才更新UI检测
|
||||
Vector2 currentMousePosition = Mouse.current.position.ReadValue();
|
||||
if (currentMousePosition != lastMousePosition || frameCount % uiCheckFrameInterval == 0)
|
||||
{
|
||||
isPointerOverUI = IsPointerOverUI(out hoveredUI);
|
||||
lastMousePosition = currentMousePosition;
|
||||
cachedIsPointerOverUI = isPointerOverUI;
|
||||
cachedHoveredUI = hoveredUI;
|
||||
}
|
||||
else
|
||||
{
|
||||
isPointerOverUI = cachedIsPointerOverUI;
|
||||
hoveredUI = cachedHoveredUI;
|
||||
}
|
||||
|
||||
SceneCameraOperation();
|
||||
MusicPlayerOperation();
|
||||
@@ -296,6 +317,12 @@ namespace Ichni.Editor
|
||||
public bool IsPointerOverUI(out GameObject hoveredUI)
|
||||
{
|
||||
hoveredUI = null;
|
||||
|
||||
// 快速检查 - 使用Unity内置方法
|
||||
if (!EventSystem.current.IsPointerOverGameObject())
|
||||
return false;
|
||||
|
||||
// 详细检查 - 只有当快速检查通过时才执行
|
||||
if (eventSystem == null || graphicRaycasters.Count == 0)
|
||||
return false;
|
||||
|
||||
@@ -306,20 +333,19 @@ namespace Ichni.Editor
|
||||
|
||||
List<RaycastResult> allResults = new List<RaycastResult>();
|
||||
|
||||
// 遍历所有 Canvas 上的 GraphicRaycaster
|
||||
foreach (var raycaster in graphicRaycasters)
|
||||
// 只对最上层的Canvas进行检测
|
||||
foreach (var raycaster in graphicRaycasters.Where(r => r.gameObject.activeInHierarchy))
|
||||
{
|
||||
List<RaycastResult> results = new List<RaycastResult>();
|
||||
raycaster.Raycast(pointerEventData, results);
|
||||
allResults.AddRange(results);
|
||||
}
|
||||
|
||||
if (allResults.Count > 0)
|
||||
{
|
||||
// 按照 sortingOrder 获取最前面的 UI 物体
|
||||
allResults.Sort((a, b) => b.sortingOrder.CompareTo(a.sortingOrder));
|
||||
hoveredUI = allResults[0].gameObject;
|
||||
return true;
|
||||
if (results.Count > 0)
|
||||
{
|
||||
// 找到最前面的结果后立即返回
|
||||
results.Sort((a, b) => b.sortingOrder.CompareTo(a.sortingOrder));
|
||||
hoveredUI = results[0].gameObject;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user