using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using Ichni; using Ichni.Editor; using Ichni.NodeScript; using Ichni.RhythmGame; using TMPro; using UnityEngine; using UnityEngine.InputSystem; public class consoleOnMono : MonoBehaviour { void Update() { if (Keyboard.current.f7Key.wasPressedThisFrame) { StartCoroutine(read()); } if (Keyboard.current.f3Key.wasPressedThisFrame) { if (NodeManager.Instance == null) { Instantiate(EditorManager.instance.basePrefabs.NodeEditor, EditorManager.instance.uiManager.WindowsCanvas.gameObject.transform); if (EditorManager.instance.operationManager.currentSelectedElements.Count > 0) NodeManager.Instance.Init(EditorManager.instance.operationManager.currentSelectedElements[0]); } else Destroy(NodeManager.Instance.gameObject); } } public IEnumerator read() { string path = Application.streamingAssetsPath + "/1.txt"; string[] lines = File.ReadAllLines(path); Dictionary folders = new Dictionary(); Dictionary tracks = new Dictionary(); ElementFolder FindFolder(string id) { if (folders.ContainsKey(id)) { return folders[id]; } else { throw new Exception($"Folder with ID {id} not found."); } } TMP_Text text = LogWindow.LogText("start..", Color.yellow); int c = 0; var rootFolder = ElementFolder.GenerateElement("root", Guid.NewGuid(), new List(), true, null); foreach (string line in lines) { yield return null; // 每行处理后等待一帧,防止卡顿 text.text = $"Processing line {c + 1}/{lines.Length}"; c++; string[] parts = line.Split(' '); switch (parts[0]) { // 在 read() 协程的 foreach 循环 switch (parts[0]) 中添加: case "FD": // 创建 Folder { string folderId = parts[1]; string folderName = parts[2]; // 调用 Ichni 引擎的生成方法 (参考项目中已有的生成逻辑) ElementFolder newFolder = ElementFolder.GenerateElement(folderName, Guid.NewGuid(), new List(), true, rootFolder); folders.Add(folderId, newFolder); } break; case "TR": // 仅创建轨道 { string tId = parts[1]; ElementFolder parentFolder = FindFolder(parts[2]); Track newTrack = Track.GenerateElement(parts[3], Guid.NewGuid(), new List(), true, parentFolder); newTrack.trackTimeSubmodule = new TrackTimeSubmoduleMovable( newTrack, float.Parse(parts[4]), float.Parse(parts[5]), float.Parse(parts[6]), (AnimationCurveType)int.Parse(parts[7]) ); newTrack.trackRendererSubmodule = new TrackRendererSubmoduleAutoOrient(newTrack, false, 0, false, new Vector2(0, 0), new Vector2(1, 1)); bool isClosed = parts[9] == "1"; if (newTrack.trackPathSubmodule != null) { newTrack.trackPathSubmodule.isClosed = isClosed; } tracks.Add(tId, newTrack); // 先加入字典,方便后续 PN 指令查找 } break; case "PN": // 逐个添加路径节点 { string targetTrackId = parts[1]; Track targetTrack = tracks[targetTrackId]; Vector3 pos = new Vector3(float.Parse(parts[2]), float.Parse(parts[3]), float.Parse(parts[4])); Color nodeColor = new Color(float.Parse(parts[5]), float.Parse(parts[6]), float.Parse(parts[7]), 1.0f); // 生成节点并挂载到轨道 var node = PathNode.GenerateElement(pos.ToString(), Guid.NewGuid(), new List(), true, targetTrack, true); node.transformSubmodule.originalPosition = pos; node.transformSubmodule.originalScale = new Vector3(0.1f, 0.1f, 0.1f); node.colorSubmodule.originalBaseColor = nodeColor; // 标记轨道需要刷新(可选:为了性能可以等所有 PN 完后再统一 Refresh) } break; case "SW": // 应用旋转 (旧版相机取反) { float startTime = float.Parse(parts[2]); float endTime = float.Parse(parts[3]); int curveIndex = int.Parse(parts[4]); // 获取曲线索引 // int curveType = int.Parse(parts[4]); // 如果有曲线系统可以应用 // 提取取反后的旋转数值 Vector3 startRot = new Vector3(float.Parse(parts[5]), float.Parse(parts[6]), float.Parse(parts[7])); Vector3 endRot = new Vector3(float.Parse(parts[8]), float.Parse(parts[9]), float.Parse(parts[10])); ElementFolder targetFolder = FindFolder(parts[1]); if (targetFolder == null) continue; if (targetFolder.childElementList.FirstOrDefault(i => i is Swirl) == null) { Swirl.GenerateElement("swirl", Guid.NewGuid(), new List(), true, targetFolder, new FlexibleFloat( new List { new(startTime, endTime, startRot.x, endRot.x, (AnimationCurveType)curveIndex) }) , new FlexibleFloat( new List { new(startTime, endTime, startRot.x, endRot.x, (AnimationCurveType)curveIndex) }) , new FlexibleFloat( new List { new(startTime, endTime, startRot.x, endRot.x, (AnimationCurveType)curveIndex) }) ); } else { Swirl swirl = targetFolder.childElementList.First(i => i is Swirl) as Swirl; swirl.eulerAngleX.Add(new AnimatedFloat( startTime, endTime, startRot.x, endRot.x, (AnimationCurveType)curveIndex )); swirl.eulerAngleY.Add(new AnimatedFloat( startTime, endTime, startRot.y, endRot.y, (AnimationCurveType)curveIndex )); swirl.eulerAngleZ.Add(new AnimatedFloat( startTime, endTime, startRot.z, endRot.z, (AnimationCurveType)curveIndex )); } } break; } } text.text = "Completed!"; foreach (var i in rootFolder.GetAllGameElementsFromThis()) { i.Refresh(); } } }