采音接口

This commit is contained in:
2025-06-09 12:42:23 +08:00
parent fc53c2437a
commit 1837d5ead0
7 changed files with 281 additions and 152 deletions

File diff suppressed because one or more lines are too long

View File

@@ -4,12 +4,10 @@ using UnityEngine;
using DynamicExpresso;
using System.Text.RegularExpressions;
using System.Linq;
using Ichni.RhythmGame;
using UnityEngine.InputSystem;
using TMPro;
using System.Reflection;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Sirenix.Utilities;
//又在写大粪 ——神币
@@ -282,150 +280,4 @@ namespace Ichni.Editor
}
public static class EditorConsoleMethods
{
public static Inspector inspector => EditorManager.instance.uiManager.inspector;
public static Hierarchy hierarchy => EditorManager.instance.uiManager.hierarchy;
public static LogWindow logWindow => EditorManager.instance.uiManager.mainPage.logWindow;
public static void tp(Vector3 pos)
{
if (EditorManager.instance.cameraManager.isSceneCameraActive)
{
EditorManager.instance.cameraManager.sceneCamera.sceneCamera.transform.position = pos;
}
}
// 保留无参tp
public static void tp()
{
if (EditorManager.instance.cameraManager.isSceneCameraActive)
{
EditorManager.instance.cameraManager.sceneCamera.sceneCamera.transform.position =
inspector.connectedGameElement.transform.position;
}
}
public static void reName(string message)
{
inspector.connectedGameElement.elementName = message;
inspector.connectedGameElement.Refresh();
}
public static void lgp(int loop, Vector3 start, Vector3 end)
{
if (inspector.connectedGameElement == null || inspector.connectedGameElement.GetType() != typeof(Track))
{
LogWindow.Log("Please select a Track first!");
return;
}
Track track = (Track)inspector.connectedGameElement;
for (int i = 0; i < loop; i++)
{
float t = (float)i / loop;
float x = start.x + (end.x - start.x) * t;
float y = start.y + (end.y - start.y) * t;
float z = start.z + (end.z - start.z) * t;
PathNode j = PathNode.GenerateElement("PathNode" + i.ToString(), Guid.NewGuid(), new List<string>(), true, track, true);
j.transformSubmodule.originalPosition = new Vector3(x, y, z);
}
}
// 支持主轴方向的螺旋线式 PathNode
public static void spiral(int loop, Vector3 center, float r, float h, int pointsPerTurn, string axis = "y")
{
if (inspector.connectedGameElement == null || inspector.connectedGameElement.GetType() != typeof(Track))
{
LogWindow.Log("Please select a Track first!");
return;
}
Track track = (Track)inspector.connectedGameElement;
for (int i = 0; i < loop; i++)
{
float t = (float)i / loop;
float angle = 2 * Mathf.PI * (i % pointsPerTurn) / pointsPerTurn;
Vector3 pos = new Vector3(center.x, center.y, center.z);
switch (axis.ToLower())
{
case "x":
pos.x += h * t;
pos.y += r * Mathf.Cos(angle);
pos.z += r * Mathf.Sin(angle);
break;
case "y":
pos.x += r * Mathf.Cos(angle);
pos.y += h * t;
pos.z += r * Mathf.Sin(angle);
break;
case "z":
pos.x += r * Mathf.Cos(angle);
pos.y += r * Mathf.Sin(angle);
pos.z += h * t;
break;
default:
pos.x += r * Mathf.Cos(angle);
pos.y += h * t;
pos.z += r * Mathf.Sin(angle);
break;
}
PathNode node = PathNode.GenerateElement("SpiralNode" + i.ToString(), Guid.NewGuid(), new List<string>(), true, track, true);
node.transformSubmodule.originalPosition = pos;
}
}
// 任意方向的螺旋线式 PathNode中心点和方向均为Vector3
public static void spiral(int loop, Vector3 center, float r, float h, int pointsPerTurn, Vector3 dir)
{
if (inspector.connectedGameElement == null || inspector.connectedGameElement.GetType() != typeof(Track))
{
LogWindow.Log("Please select a Track first!");
return;
}
Vector3 direction = dir.normalized;
if (direction == Vector3.zero) direction = Vector3.up; // 默认Y轴
Quaternion rot = Quaternion.FromToRotation(Vector3.up, direction);
Track track = (Track)inspector.connectedGameElement;
for (int i = 0; i < loop; i++)
{
float t = (float)i / loop;
float angle = 2 * Mathf.PI * (i % pointsPerTurn) / pointsPerTurn;
Vector3 localPos = new Vector3(
r * Mathf.Cos(angle),
h * t,
r * Mathf.Sin(angle)
);
Vector3 pos = center + rot * localPos;
PathNode node = PathNode.GenerateElement("SpiralNode" + i.ToString(), Guid.NewGuid(), new List<string>(), true, track, true);
node.transformSubmodule.originalPosition = pos;
}
}
public static void delSameInParent()
{
Type type = inspector.connectedGameElement.GetType();
foreach (GameElement element in inspector.connectedGameElement.parentElement.GetAllGameElementsFromThis())
{
try
{
if (element.GetType() == type && element != inspector.connectedGameElement)
{
element.Delete();
}
}
catch (Exception)
{
}
}
}
}
}

View File

@@ -0,0 +1,261 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.Linq;
using System.Text.RegularExpressions;
using Ichni.RhythmGame;
using UnityEngine;
namespace Ichni.Editor
{
public static class EditorConsoleMethods
{
public static Inspector inspector => EditorManager.instance.uiManager.inspector;
public static Hierarchy hierarchy => EditorManager.instance.uiManager.hierarchy;
public static LogWindow logWindow => EditorManager.instance.uiManager.mainPage.logWindow;
public static void tp(Vector3 pos)
{
if (EditorManager.instance.cameraManager.isSceneCameraActive)
{
EditorManager.instance.cameraManager.sceneCamera.sceneCamera.transform.position = pos;
}
}
// 保留无参tp
public static void tp()
{
if (EditorManager.instance.cameraManager.isSceneCameraActive)
{
EditorManager.instance.cameraManager.sceneCamera.sceneCamera.transform.position =
inspector.connectedGameElement.transform.position;
}
}
public static void ReName(string message)
{
inspector.connectedGameElement.elementName = message;
inspector.connectedGameElement.Refresh();
}
public static void Lgp(int loop, Vector3 start, Vector3 end)
{
if (inspector.connectedGameElement == null || inspector.connectedGameElement.GetType() != typeof(Track))
{
LogWindow.Log("Please select a Track first!");
return;
}
Track track = (Track)inspector.connectedGameElement;
for (int i = 0; i < loop; i++)
{
float t = (float)i / loop;
float x = start.x + (end.x - start.x) * t;
float y = start.y + (end.y - start.y) * t;
float z = start.z + (end.z - start.z) * t;
PathNode j = PathNode.GenerateElement("PathNode" + i.ToString(), Guid.NewGuid(), new List<string>(), true, track, true);
j.transformSubmodule.originalPosition = new Vector3(x, y, z);
}
}
// 支持主轴方向的螺旋线式 PathNode
public static void Spiral(int loop, Vector3 center, float r, float h, int pointsPerTurn, string axis = "y")
{
if (inspector.connectedGameElement == null || inspector.connectedGameElement.GetType() != typeof(Track))
{
LogWindow.Log("Please select a Track first!");
return;
}
Track track = (Track)inspector.connectedGameElement;
for (int i = 0; i < loop; i++)
{
float t = (float)i / loop;
float angle = 2 * Mathf.PI * (i % pointsPerTurn) / pointsPerTurn;
Vector3 pos = new Vector3(center.x, center.y, center.z);
switch (axis.ToLower())
{
case "x":
pos.x += h * t;
pos.y += r * Mathf.Cos(angle);
pos.z += r * Mathf.Sin(angle);
break;
case "y":
pos.x += r * Mathf.Cos(angle);
pos.y += h * t;
pos.z += r * Mathf.Sin(angle);
break;
case "z":
pos.x += r * Mathf.Cos(angle);
pos.y += r * Mathf.Sin(angle);
pos.z += h * t;
break;
default:
pos.x += r * Mathf.Cos(angle);
pos.y += h * t;
pos.z += r * Mathf.Sin(angle);
break;
}
PathNode node = PathNode.GenerateElement("SpiralNode" + i.ToString(), Guid.NewGuid(), new List<string>(), true, track, true);
node.transformSubmodule.originalPosition = pos;
}
}
// 任意方向的螺旋线式 PathNode中心点和方向均为Vector3
public static void Spiral(int loop, Vector3 center, float r, float h, int pointsPerTurn, Vector3 dir)
{
if (inspector.connectedGameElement == null || inspector.connectedGameElement.GetType() != typeof(Track))
{
LogWindow.Log("Please select a Track first!");
return;
}
Vector3 direction = dir.normalized;
if (direction == Vector3.zero) direction = Vector3.up; // 默认Y轴
Quaternion rot = Quaternion.FromToRotation(Vector3.up, direction);
Track track = (Track)inspector.connectedGameElement;
for (int i = 0; i < loop; i++)
{
float t = (float)i / loop;
float angle = 2 * Mathf.PI * (i % pointsPerTurn) / pointsPerTurn;
Vector3 localPos = new Vector3(
r * Mathf.Cos(angle),
h * t,
r * Mathf.Sin(angle)
);
Vector3 pos = center + rot * localPos;
PathNode node = PathNode.GenerateElement("SpiralNode" + i.ToString(), Guid.NewGuid(), new List<string>(), true, track, true);
node.transformSubmodule.originalPosition = pos;
}
}
public static void DelSameInParent()
{
Type type = inspector.connectedGameElement.GetType();
for (int i = inspector.connectedGameElement.parentElement.childElementList.Count - 1; i >= 0; i--)
{
GameElement element = inspector.connectedGameElement.parentElement.childElementList[i];
if (element.GetType() == type && element != inspector.connectedGameElement)
{
EditorManager.instance.operationManager.CopyPasteDeleteModule.DeleteElement(element);
}
}
EditorManager.instance.operationManager.CopyPasteDeleteModule.DeleteElement(inspector.connectedGameElement);
}
public static void SamplerImport(string inputData)
{
if (!EditorManager.instance.useNotePrefab)
{
LogWindow.Log("Pleasee nable \"Note Prefab\" in EditorManager", Color.red);
return;
}
// 改进的正则表达式支持5个字段和负数
Regex dataPattern = new Regex(
@"\(\s*([^,]+?)\s*,\s*([^,]+?)\s*,\s*([-+]?\d*\.?\d+)\s*,\s*([-+]?\d*\.?\d+)\s*(?:,\s*([-+]?\d*\.?\d+)\s*)?\)",
RegexOptions.Compiled
);
Debug.Log("===== =====");
MatchCollection matches = dataPattern.Matches(inputData);
Debug.Log($": {matches.Count}");
int recordCount = 1;
Track findTrack(string Findtext)
{
List<Track> tracks = EditorManager.instance.beatmapContainer.gameElementList.OfType<Track>().Where(i => i.elementName == Findtext).ToList();
if (tracks.Count == 0)
{
Debug.LogError($"未找到名为 {Findtext} 的轨道");
return null;
}
else if (tracks.Count > 1)
{
LogWindow.Log($"Repeat Track Of {Findtext}, please Cautious", Color.yellow);
}
return tracks[0];
}
foreach (Match match in matches)
{
if (match.Success)
{
string action = match.Groups[1].Value.Trim();
string id = match.Groups[2].Value.Trim();
// 解析公共字段
float timestamp = float.Parse(match.Groups[3].Value);
float value = float.Parse(match.Groups[4].Value);
// 处理Hold操作的特殊字段
float holdDuration = 0f;
bool isHold = false;
if (action == "Hold" && match.Groups[5].Success)
{
isHold = true;
holdDuration = float.Parse(match.Groups[5].Value);
}
// 构建输出信息
string logEntry = $"[记录#{recordCount++}] " +
$"Note: {action.PadRight(5)} | " +
$"ID: {id} | " +
$"时间: {timestamp.ToString("0.000").PadLeft(7)} | " +
$"X值: {value.ToString("0.000").PadLeft(7)}";
if (isHold)
{
logEntry += $" | 持续时间: {holdDuration.ToString("0.000")}";
}
Debug.Log(logEntry);
if (findTrack(id) is null)
{
Debug.LogError($"未找到名为 {id} 的轨道");
continue;
}
// 根据动作类型处理
switch (action)
{
case "Tap":
Tap a = Tap.GenerateElement("New Tap", Guid.NewGuid(), new List<string>(), false, findTrack(id), timestamp);
((TransformSubmodule)a.noteVisual.submoduleList.Where(i => i is TransformSubmodule)?.First()).originalPosition = new Vector3(value, 0, 0);
a.Refresh();
break;
case "Stay":
Stay b = Stay.GenerateElement("New Stay", Guid.NewGuid(), new List<string>(), false, findTrack(id), timestamp);
((TransformSubmodule)b.noteVisual.submoduleList.Where(i => i is TransformSubmodule)?.First()).originalPosition = new Vector3(value, 0, 0);
b.Refresh();
break;
case "Hold":
Hold c = Hold.GenerateElement("New Hold", Guid.NewGuid(), new List<string>(), false, findTrack(id), timestamp, timestamp + holdDuration);
((TransformSubmodule)c.noteVisual.submoduleList.Where(i => i is TransformSubmodule)?.First()).originalPosition = new Vector3(value, 0, 0);
c.Refresh();
break;
case "Flick":
Flick d = Flick.GenerateElement("New Flick", Guid.NewGuid(), new List<string>(), false, findTrack(id), timestamp, new List<Vector2>());
((TransformSubmodule)d.noteVisual.submoduleList.Where(i => i is TransformSubmodule)?.First()).originalPosition = new Vector3(value, 0, 0);
d.Refresh();
break;
default:
Debug.LogError($"未知类型: {action}");
break;
}
}
}
Debug.Log("===== =====");
}
}
}

View File

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

View File

@@ -218,7 +218,6 @@ public class SampleWindow : MovableWindow//该window高度为300横的要在1
far -= 1f / Xdevide;
float time = far * timePerBeat;
if (!isExpand)//movable
{
switch (NoteCode)

View File

@@ -250,7 +250,10 @@ namespace Ichni.Editor
if (Physics.Raycast(ray, out RaycastHit hit, float.MaxValue, LayerMask.GetMask("Selectable")))
{
SelectionConnector connector = hit.collider.GetComponent<SelectionConnector>();//TODO: 对于Hold这种复杂的元素需要使用连接脚本进行获取
(connector.connectedGameElement as IHaveSelectSubmodule)?.selectSubmodule.SelectGameElement();
(connector.
connectedGameElement as IHaveSelectSubmodule)
?.selectSubmodule
.SelectGameElement();
}
}
}

View File

@@ -113,6 +113,7 @@ namespace Ichni.Editor
}
gameElement.Delete();
EditorManager.instance.uiManager.inspector.ClearInspector();
}
/// <summary>