using System; using UnityEngine; using UnityEditor; using DefaultNamespace.ProcessMode; using System.Collections.Generic; using UnityEngine.UIElements; using System.Linq; using DefaultNamespace; using Framework.ProcessMode; using MotionFramework; public class ProcessScoreWindow : EditorWindow { private Vector2 scrollPosition; private ProcessManager processManager; private bool[] stepFoldouts; private GUIStyle headerStyle; private GUIStyle subHeaderStyle; private GUIStyle scoreStyle; private GUIStyle warningStyle; private GUIStyle jumpButtonStyle; [MenuItem("工具/流程查看器")] public static void ShowWindow() { var window = GetWindow("流程得分查看器"); window.minSize = new Vector2(400, 300); } private void OnEnable() { // 初始化样式 //InitializeStyles(); } private void InitializeStyles() { try { headerStyle = new GUIStyle(EditorStyles.boldLabel) { fontSize = 14, margin = new RectOffset(4, 4, 8, 8) }; subHeaderStyle = new GUIStyle(EditorStyles.boldLabel) { fontSize = 12, margin = new RectOffset(4, 4, 4, 4) }; scoreStyle = new GUIStyle(EditorStyles.label) { fontSize = 11, normal = { textColor = Color.green } }; warningStyle = new GUIStyle(EditorStyles.label) { fontSize = 11, normal = { textColor = Color.red } }; jumpButtonStyle = new GUIStyle(GUI.skin.button) { fontSize = 10, normal = { textColor = Color.white }, fontStyle = FontStyle.Bold }; } catch (Exception e) { } } private void OnGUI() { if (GUILayout.Button("打开在线文档")) { Application.OpenURL("https://docs.qq.com/sheet/DYVJYQ3VBUXZYZWx3?tab=BB08J2"); } // 每帧尝试获取 ProcessManager processManager = MotionFramework.MotionEngine.GetModule(); InitializeStyles(); if (processManager == null) { EditorGUILayout.HelpBox("未找到 ProcessManager 实例", MessageType.Warning); return; } // 检查当前模式是否存在 if (string.IsNullOrEmpty(processManager._currentMode.ToString())) { EditorGUILayout.HelpBox("当前没有设置流程模式", MessageType.Info); return; } try { var currentCollection = processManager.CurrentProcessCollection; if (currentCollection == null) { EditorGUILayout.HelpBox("当前没有活动的流程集合", MessageType.Info); return; } // 如果 stepFoldouts 为空或长度不匹配,重新初始化 if (stepFoldouts == null || stepFoldouts.Length != currentCollection.Steps.Count) { stepFoldouts = new bool[currentCollection.Steps.Count]; } scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); var steps = currentCollection.Steps; // 显示总体信息 EditorGUILayout.LabelField("流程总览", headerStyle); EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.LabelField($"当前模式: {processManager._currentMode}"); EditorGUILayout.LabelField($"总步骤数: {steps.Count}"); EditorGUILayout.LabelField($"已完成步骤: {steps.Count(s => s.IsCompleted)}/{steps.Count}"); EditorGUILayout.EndVertical(); EditorGUILayout.Space(10); // 显示每个步骤的详细信息 for (int i = 0; i < steps.Count; i++) { var step = steps[i]; EditorGUILayout.BeginVertical(EditorStyles.helpBox); // 步骤标题栏 EditorGUILayout.BeginHorizontal(); stepFoldouts[i] = EditorGUILayout.Foldout(stepFoldouts[i], $"步骤 {i + 1}: {step.StepDescription}", true); // 显示步骤状态 string status = step.IsCompleted ? "✓ 已完成" : "✗ 未完成"; GUIStyle statusStyle = step.IsCompleted ? scoreStyle : warningStyle; EditorGUILayout.LabelField(status, statusStyle, GUILayout.Width(60)); // 显示步骤得分 EditorGUILayout.LabelField($"得分: {step.Score:F1}", scoreStyle, GUILayout.Width(80)); EditorGUILayout.EndHorizontal(); if (stepFoldouts[i]) { EditorGUI.indentLevel++; // 显示步骤下的所有动作 for (int j = 0; j < step.Actions.Count; j++) { var action = step.Actions[j]; EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.LabelField($"动作 {j + 1}: {action.Title}", subHeaderStyle); EditorGUILayout.LabelField($"描述: {action.Description}"); EditorGUILayout.LabelField($"满分: {action.Score}"); // 显示动作完成状态 string actionStatus = action.IsCompleted ? "✓ 已完成" : "✗ 未完成"; GUIStyle actionStatusStyle = action.IsCompleted ? scoreStyle : warningStyle; EditorGUILayout.LabelField($"状态: {actionStatus}", actionStatusStyle); // 显示目标物体 EditorGUILayout.LabelField("目标物体:", subHeaderStyle); switch (action.ActionType) { case ProcessActionType.默认: // 点击物体 foreach (var target in action.TargetObjects) { EditorGUILayout.LabelField($"- {target.ObjectName} (点击物体)"); } break; case ProcessActionType.判断题: // 判断题 if (action.JudgmentQuestions != null) { foreach (var question in action.JudgmentQuestions) { EditorGUILayout.LabelField($"- 判断题: {question.Question}"); EditorGUILayout.LabelField($" 正确答案: {(question.CorrectAnswer)}"); EditorGUILayout.LabelField($" 分值: {question.Score}"); } } break; case ProcessActionType.多选题: // 多选题 if (action.MultipleChoiceQuestions != null) { foreach (var question in action.MultipleChoiceQuestions) { EditorGUILayout.LabelField($"- 多选题: {question.Question}"); EditorGUILayout.LabelField($" 选项: {string.Join(", ", question.Options)}"); EditorGUILayout.LabelField($" 正确答案: {string.Join(", ", question.CorrectAnswers)}"); EditorGUILayout.LabelField($" 分值: {question.Score}"); } } break; default: EditorGUILayout.LabelField("未知类型的目标物体"); break; } // 显示错误点击信息 var actionErrors = processManager._incorrectClicksPerStep .Where(kvp => kvp.Key.stepIndex == i && kvp.Key.actionIndex == j) .SelectMany(kvp => kvp.Value) .ToList(); if (actionErrors.Count > 0) { EditorGUILayout.LabelField($"错误点击次数: {actionErrors.Count}"); EditorGUILayout.LabelField($"错误点击的物体: {string.Join(", ", actionErrors)}"); } else { EditorGUILayout.LabelField("无错误点击"); } // 添加跳转按钮 EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUI.backgroundColor = new Color(1f, 0.6f, 0f, 1f); // 橙色背景 if (GUILayout.Button("跳转到此处", jumpButtonStyle, GUILayout.Width(80), GUILayout.Height(25))) { JumpToAction(i, j); } GUI.backgroundColor = Color.white; // 恢复默认颜色 EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); EditorGUILayout.Space(5); } EditorGUI.indentLevel--; } EditorGUILayout.EndVertical(); EditorGUILayout.Space(5); } EditorGUILayout.EndScrollView(); // 添加刷新按钮 EditorGUILayout.Space(10); if (GUILayout.Button("刷新数据")) { Repaint(); } if (GUILayout.Button("提交试卷 "+MotionEngine.GetModule().GetUsedTimeInSeconds()+"秒")) { FileComponent.UploadExamFiles(); } // if (GUILayout.Button("下载文件 ")) // { // FileComponent.DownloadSingleFile(ExamQuestionTypes.kV10变压器到货验收入库, "答题卡"); } } catch (KeyNotFoundException) { EditorGUILayout.HelpBox($"当前模式 '{processManager._currentMode}' 不存在", MessageType.Error); } catch (System.Exception ex) { EditorGUILayout.HelpBox($"发生错误: {ex.Message}", MessageType.Error); } } /// /// 跳转到指定的动作,并完成前面的所有步骤和动作 /// 使用框架内置的JumpToProcessAsync方法确保完整的状态管理 /// /// 目标步骤索引 /// 目标动作索引 private async void JumpToAction(int targetStepIndex, int targetActionIndex) { if (processManager == null || processManager.CurrentProcessCollection == null) { EditorUtility.DisplayDialog("错误", "无法获取流程管理器或当前流程集合", "确定"); return; } // 显示确认对话框 bool confirmed = EditorUtility.DisplayDialog( "确认跳转", $"确定要跳转到步骤 {targetStepIndex + 1},动作 {targetActionIndex + 1} 吗?\n\n这将自动完成前面的所有步骤和动作。", "确定跳转", "取消" ); if (!confirmed) return; try { // 使用框架内置的跳转方法,确保完整的状态管理和事件执行 Debug.Log($"【编辑器工具】开始跳转到步骤 {targetStepIndex + 1},动作 {targetActionIndex + 1}"); await processManager.JumpToProcessAsync(targetStepIndex, targetActionIndex); EditorUtility.DisplayDialog("跳转成功", $"已成功跳转到步骤 {targetStepIndex + 1},动作 {targetActionIndex + 1}\n\n" + "框架将自动完成前面的步骤和动作,并执行相关事件。", "确定"); Repaint(); // 刷新界面 } catch (System.Exception ex) { EditorUtility.DisplayDialog("跳转失败", $"跳转过程中发生错误: {ex.Message}", "确定"); } } }