using System.Collections; using System.Collections.Generic; using UnityEngine; using DevelopEngine; using System; using UnityEngine.Events; /// /// 流程管理 管理流程中所有的步骤 为步骤规划前置和后置关系 提供流程启动入口 提供流程反转功能 /// public class ProcessManager : Singleton { ProcessEnum currentProcess; List stepRelations = new List();//流程规划各步骤关系 后续使用Node编辑插件代替 //Dictionary stepDic;//记录所有步骤前后关系的字典 key前置节点 value后置节点 Dictionary stepNodesDic = new Dictionary();//所有的可操作流程节点对应的虚拟物体 List finishedStep = new List();//当前已经完成的流程节点 bool planningOver;//流程规划完成 string currentLastStep;//当前流程最终步骤名称 string teardownLastStep;//拆卸流程结束步骤 string assembleLastStep;//安装流程结束步骤 UnityAction processOverEvent; /// /// 流程中步骤结束事件 /// public event UnityAction StepOverEvent; /// /// 添加待管理的步骤 /// /// public void AddStep(StepNodeBase stepNode) { if (!stepNodesDic.ContainsKey(stepNode.NodeName)) { stepNodesDic.Add(stepNode.NodeName, stepNode); } else { Debug.LogError($"存在名称重复的流程节点{stepNode.NodeName},无法加入管理队列!"); } } /// /// 开始流程 /// public void StartProcess(UnityAction processOver = null) { this.processOverEvent = processOver; finishedStep = new List(); if (planningOver) { Debug.Log($"启动{currentProcess.ToString()}流程,当前流程最终步骤为{currentLastStep}"); foreach (var item in stepNodesDic)//先设置流程 后启动流程 避免某些节点激活时自动完成影响后续节点 { item.Value.SetProcess(currentProcess); } foreach (var item in stepNodesDic) { item.Value.ProcessStart(); } } else { Debug.LogError("未完成流程规划 无法开始"); } } /// /// 清空流程 /// public void ClearProcess() { stepNodesDic.Clear(); stepRelations.Clear(); planningOver = false; currentLastStep = null; StepOverEvent = null; } /// /// 初始化拆卸流程关系 安装流程直接反转 /// /// 所有节点的前后关系 /// 最终节点 public void InitStepRelationDic(List stepRelations, string teardownLastStep, string assembleLastStep) { this.stepRelations = stepRelations; this.teardownLastStep = teardownLastStep; this.assembleLastStep = assembleLastStep; CheckStep(); } /// /// 设置流程类型 /// /// 拆卸 OR 装配 public void SetProcess(ProcessEnum processName) { currentProcess = processName; switch (processName) { case ProcessEnum.teardown: currentLastStep = teardownLastStep; PlanningTeardownStep(); break; case ProcessEnum.assemble: currentLastStep = assembleLastStep; PlanningAssembleStep(); break; default: break; } } //规划流程 protected void PlanningTeardownStep() { for (int i = 0; i < stepRelations.Count; i++) { PlanningNodes(stepRelations[i].preconditionNodeName, stepRelations[i].postpositionNodeName); } planningOver = true; } //规划规划安装流程 protected void PlanningAssembleStep() { if (/*currentProcess == ProcessEnum.teardown &&*/ planningOver)//已经规划完拆卸流程 { //翻转流程 ReversalProcess(); //currentLastStep = "三角木"; } else { Debug.Log("安装流程需手动规划"); } } /// /// 规划两个节点关系 /// /// 前置节点名称 /// 后置节点名称 protected void PlanningNodes(string preconditionNodeName, string postpositionNodeName) { if (!stepNodesDic.ContainsKey(preconditionNodeName)) { Debug.LogError($"场景中不存在节点:{preconditionNodeName}对应的操作物体,无法规划节点关系"); return; } if (!stepNodesDic.ContainsKey(postpositionNodeName)) { Debug.LogError($"场景中不存在节点:{preconditionNodeName}对应的操作物体,无法规划节点关系"); return; } stepNodesDic[preconditionNodeName].postpositionNodes.Add(stepNodesDic[postpositionNodeName]); stepNodesDic[postpositionNodeName].preconditionNodes.Add(stepNodesDic[preconditionNodeName]); } //记录完成节点 public void RecordFinisedStep(string finisedStep) { finishedStep.Add(finisedStep); StepOverEvent?.Invoke(finisedStep); if (finisedStep == currentLastStep)// { processOverEvent?.Invoke(currentProcess); processOverEvent = null;//流程结束事件注册后只执行一次 注意不要在上一个环节结束事件回调函数中 直接直接开始新的步骤,会导致新的步骤结束事件被清空 } } //流程翻转 protected void ReversalProcess() { Debug.Log("反转流程"); foreach (var item in stepNodesDic)//遍历所有的步骤节点 退出节点激活状态 调换前置、后置步骤关系 { List tempSteps = item.Value.postpositionNodes;// item.Value.ProcessStop(); item.Value.postpositionNodes = item.Value.preconditionNodes; item.Value.preconditionNodes = tempSteps; } } /// /// 添加特定步骤的完成监听事件 /// public void RegisterStepFinishedEvent(string stepName, UnityAction stepFinised) { if (stepNodesDic.ContainsKey(stepName)) { stepNodesDic[stepName].NodeFinished += stepFinised; } else { Debug.LogError($"当前流程不存在{stepName}步骤,无法注册结束事件"); } } /// /// 添加特定步骤的完成监听事件 /// public void RemoveStepFinishedEvent(string stepName, UnityAction stepFinised) { if (stepNodesDic.ContainsKey(stepName)) { stepNodesDic[stepName].NodeFinished -= stepFinised; } else { Debug.LogError($"当前流程不存在{stepName}步骤,无法注销结束事件"); } } /// /// 遍历配置步骤检查是否缺少对应的实现步骤 /// public void CheckStep() { List nullStepNames = new List(); for (int i = 0; i < stepRelations.Count; i++) { if (!stepNodesDic.ContainsKey(stepRelations[i].postpositionNodeName)) { nullStepNames.Add(stepRelations[i].postpositionNodeName); } if (!stepNodesDic.ContainsKey(stepRelations[i].preconditionNodeName)) { nullStepNames.Add(stepRelations[i].preconditionNodeName); } } for (int i = 0; i < nullStepNames.Count; i++) { Debug.LogWarning($"未实现的规划步骤:{nullStepNames[i]}"); } } /// /// 获取当前未完成的步骤给与提示 /// /// public List GetUnFinishedtep() { List allName = new List(); foreach (var item in stepNodesDic) { if (item.Value.stepState == NodeFinishState.unFinished) { allName.Add(item.Key); } } return allName; } } //流程名称 public enum ProcessEnum { /// /// 拆卸流程 /// teardown = 1, /// /// 组装流程 /// assemble = 2, } //步骤关系类 public class StepRelation { /// /// /// /// 前置节点 /// 后置节点 public StepRelation(string preName, string postName) { preconditionNodeName = preName; postpositionNodeName = postName; } /// /// 前置节点 /// public string preconditionNodeName; /// /// 后置节点 /// public string postpositionNodeName; }