using System; using System.Collections.Generic; using System.Linq; using HighlightPlus; using MotionFramework; using UnityEngine; using UnityEngine.UI; using Type = System.Type; namespace DefaultNamespace.ProcessMode { [ScriptDescription("流程模式管理器")] public class AnimationProcessManager : ModuleSingleton, IModule { private Dictionary processes = new Dictionary(); public ProcessMode currentMode; // 当前模式 private int currentStepIndex; // 当前步骤索引 private int currentActionIndex; // 当前动作索引,确保动作顺序 private int currentActionGameIndex; // 当前动作索引,确保动作顺序 private List incorrectClicks; // 错误点击的记录列表 public AnimationProcess CurrentProcess => processes[currentMode.ToString()]; public delegate void CompleteEventHandler(); public delegate void UIEventHandler(); public delegate void SendMessagePrompt(string message); /// /// 全部流程结束调用方法 /// public event CompleteEventHandler OnCompleteEvent; public event UIEventHandler OnUIEvent; public event SendMessagePrompt OnSendMessagePrompt; public void AddProcess(string type) { // if (!processes.ContainsKey(type)) // { // processes[type] = new AnimationProcess(type); // Enum.TryParse(type, true, out currentMode); // } processes[type] = new AnimationProcess(type); Enum.TryParse(type, true, out currentMode); } public void ClearProcess() { processes.Clear(); } public void AddStepToProcess(string type, AnimationStep step) { if (processes.ContainsKey(type)) { processes[type].AddStep(step); } } public void HandleClick(string clickedObject) { string type = currentMode.ToString(); if (processes.ContainsKey(type)) { AnimationProcess process = processes[type]; if (currentStepIndex < process.Steps.Count) { AnimationStep step = process.Steps[currentStepIndex]; ActionWithDescription currentAction = step.Actions[currentActionIndex]; if (currentAction.IsSequential) { // 按顺序点击的逻辑 if (currentAction.CurrentObjectIndex < currentAction.TargetObjects.Count && currentAction.TargetObjects[currentAction.CurrentObjectIndex] == clickedObject) { Debug.Log($"正确点击了:{clickedObject}"); currentAction.CurrentObjectIndex++; // 正确点击,递增对象索引 currentAction.ClickedObjects.Add(clickedObject); // 添加到已点击对象集合 HandleModeFeedback(currentMode, currentAction); // 处理模式特定的反馈 if (currentAction.CurrentObjectIndex >= currentAction.TargetObjects.Count) { CompleteAction(step, currentAction); // 完成当前动作 } } else { string correctObjectName = currentAction.TargetObjects[currentAction.CurrentObjectIndex]; Debug.Log($"错误点击或顺序错误:{clickedObject}。正确的物体是:{correctObjectName}"); } } else { // 不按顺序点击的逻辑 if (currentAction.TargetObjects.Any(obj => obj == clickedObject)) { if (currentAction.ClickedObjects.Any(obj => obj == clickedObject)) { Debug.Log($"错误点击:{clickedObject}。这个物体已经点击过。"); return; // 如果物体已经点击过,不继续处理 } if (!currentAction.ClickedObjects.Contains(clickedObject)) { Debug.Log($"正确点击了:{clickedObject}"); currentAction.ClickedObjects.Add(clickedObject); // 添加到已点击对象集合 HandleModeFeedback(currentMode, currentAction); // 处理模式特定的反馈 if (currentAction.ClickedObjects.Count >= currentAction.TargetObjects.Count) { CompleteAction(step, currentAction); // 完成当前动作 } } } else { Debug.Log($"错误点击:{clickedObject}"); List correctObjectNames = new List(); foreach (var obj in currentAction.TargetObjects) { if (!currentAction.ClickedObjects.Contains(obj)) { correctObjectNames.Add(obj); } } string correctObjects = string.Join(",", correctObjectNames); Debug.Log($"正确的物体是:{correctObjects}"); } } } } } /// /// 处理完成当前动作的逻辑 /// /// 当前步骤 /// 当前动作 private void CompleteAction(AnimationStep step, ActionWithDescription currentAction) { Debug.Log($"完成了动作 {currentActionIndex + 1}"); step.PlayAnimation(currentActionIndex); // 播放当前动作的动画 currentActionIndex++; currentAction.CurrentObjectIndex = 0; // 重置当前动作对象索引 currentAction.ClickedObjects.Clear(); // 重置已点击对象集合 currentAction.FeedbackDisplayed = false; // 重置反馈显示标志 if (currentActionIndex >= step.Actions.Count) { Debug.Log("所有动作完成!"); currentActionIndex = 0; // 重置动作索引或进入下一个大步骤 currentStepIndex++; if (currentStepIndex < processes[currentMode.ToString()].Steps.Count) { var nextStep = processes[currentMode.ToString()].Steps[currentStepIndex]; HandleModeFeedback(currentMode, nextStep.Actions[0]); // 准备下一个步骤 } else { if (MotionEngine.GetModule().GetToolsPackScene() == ToolsPackScene.其他) { OnCompleteEvent?.Invoke(); } Debug.Log("全部完成了!!!!"); } } else { Debug.Log("开始下一个动作!"); HandleModeFeedback(currentMode, step.Actions[currentActionIndex]); // 传递下一个动作对象 } } /// /// 判断是否为最后一个动作 /// /// 当前的动作 /// 是否为最后一个动作 private bool IsLastAction(ActionWithDescription action) { if (currentStepIndex == processes[currentMode.ToString()].Steps.Count - 1 && currentActionIndex == processes[currentMode.ToString()].Steps[currentStepIndex].Actions.Count - 1) { return true; } return false; } /// /// 根据当前模式处理相应的反馈逻辑,包括准备下一个步骤或动作 /// /// 当前的流程模式 /// 当前步骤或动作 public void HandleModeFeedback(ProcessMode mode, object stepOrAction) { switch (mode) { case ProcessMode.Teaching: HighlightNextObject(stepOrAction as ActionWithDescription); // 高亮下一个需要点击的物体 break; case ProcessMode.Training: if (stepOrAction is ActionWithDescription action) { Debug.Log($"培训模式:{action.Description}"); OnSendMessagePrompt?.Invoke("提示:" + action.Description); // ShowTrainingStep(action.Description); // 在右上角显示流程步骤 } else if (stepOrAction is AnimationStep step) { if (step.Actions.Count > 0) { Debug.Log($"培训模式:{step.Actions[0].Description}"); OnSendMessagePrompt?.Invoke("提示:" + step.Actions[0].Description); // ShowTrainingStep(step.Actions[0].Description); // 在右上角显示流程步骤 } } break; case ProcessMode.Practice: if (stepOrAction is ActionWithDescription practiceAction) { if (IsLastAction(practiceAction)) { ShowPracticeStep(practiceAction.Description); // 只显示当前步骤 } } else if (stepOrAction is AnimationStep practiceStep) { if (practiceStep.Actions.Count > 0) { if (IsLastAction(practiceStep.Actions[0])) { ShowPracticeStep(practiceStep.Actions[0].Description); // 只显示当前步骤 } } } break; case ProcessMode.Assessment: // 考核模式无提示 break; } } /// /// 高亮显示下一个需要点击的物体 /// /// 当前的动作 private void HighlightNextObject(ActionWithDescription action) { if (action != null) { bool hasDuplicates = action.TargetObjects.GroupBy(x => x).Any(g => g.Count() > 1); for (int i = action.CurrentObjectIndex; i < action.TargetObjects.Count; i++) { string nextObject = action.TargetObjects[i]; if (hasDuplicates) { // 处理重复物体的高亮逻辑 int count = action.TargetObjects.Take(i).Count(o => o == nextObject); // 统计当前物体之前出现的次数 if (!action.ClickedObjects.Contains($"{nextObject}_{count}")) { HighlightObject(nextObject); break; } } else { // 无重复物体的高亮逻辑 if (!action.ClickedObjects.Contains(nextObject)) { HighlightObject(nextObject); break; } } } } } /// /// 高亮指定的物体 /// /// 物体名称 private void HighlightObject(string objectName) { try { var obj = GameObject.Find(objectName); if (obj != null) { var highlightEffect = obj.GetComponent(); if (highlightEffect != null) { highlightEffect.highlighted = true; } Debug.Log($"高亮显示:{objectName}"); } } catch (Exception e) { Debug.LogError($"Error highlighting object {objectName}: {e.Message}"); } } /// /// 设置当前模式 /// /// 模式 public void SetCurrentMode(ProcessMode mode) { currentMode = mode; currentStepIndex = 0; currentActionIndex = 0; } private void ShowPracticeStep(object nextStepOrAction) { if (nextStepOrAction is ActionWithDescription practiceAction) { OnSendMessagePrompt(practiceAction.Description); Debug.Log($"练习模式:{practiceAction.Description}"); } } public void OnCreate(object createParam) { processes = new Dictionary(); incorrectClicks = new List(); } public void OnUpdate() { } public void OnDestroy() { } public void OnGUI() { } } }