- LocalizationManager: 新增翻译表(SetFormatted/SetDuration/LocalizeOperateMsg) - LoginPanel: InputField placeholder本地化、字体颜色保持 - HistoryPanel: 用时数据本地化、placeholder本地化 - RecordDetailPanel: 操作详情消息本地化(LanguageChanged重建) - AppraiseWindowBase: 评价等级本地化、操作消息重建 - EditorAppraiser: 所有评估消息改用InjectOperateMsgLocalized - StudentOperateRecorder: 新增InjectOperateMsgLocalized方法 - LocalizationLanguageTestBar: 单例模式、ScreenSpaceOverlay筛选 - 字体切换时保留颜色和verticalOverflow
303 lines
9.3 KiB
C#
303 lines
9.3 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using DevelopEngine;
|
|
using System;
|
|
using UnityEngine.Events;
|
|
/// <summary>
|
|
/// 流程管理 管理流程中所有的步骤 为步骤规划前置和后置关系 提供流程启动入口 提供流程反转功能
|
|
/// </summary>
|
|
public class ProcessManager : Singleton<ProcessManager>
|
|
{
|
|
ProcessEnum currentProcess;
|
|
List<StepRelation> stepRelations = new List<StepRelation>();//流程规划各步骤关系 后续使用Node编辑插件代替
|
|
|
|
//Dictionary<string, string> stepDic;//记录所有步骤前后关系的字典 key前置节点 value后置节点
|
|
Dictionary<string, StepNodeBase> stepNodesDic = new Dictionary<string, StepNodeBase>();//所有的可操作流程节点对应的虚拟物体
|
|
List<string> finishedStep = new List<string>();//当前已经完成的流程节点
|
|
bool planningOver;//流程规划完成
|
|
string currentLastStep;//当前流程最终步骤名称
|
|
string teardownLastStep;//拆卸流程结束步骤
|
|
string assembleLastStep;//安装流程结束步骤
|
|
UnityAction<ProcessEnum> processOverEvent;
|
|
|
|
/// <summary>
|
|
/// 流程中步骤结束事件
|
|
/// </summary>
|
|
public event UnityAction<string> StepOverEvent;
|
|
|
|
/// <summary>
|
|
/// 添加待管理的步骤
|
|
/// </summary>
|
|
/// <param name="stepNode"></param>
|
|
public void AddStep(StepNodeBase stepNode)
|
|
{
|
|
if (!stepNodesDic.ContainsKey(stepNode.NodeName))
|
|
{
|
|
stepNodesDic.Add(stepNode.NodeName, stepNode);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"存在名称重复的流程节点{stepNode.NodeName},无法加入管理队列!");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 开始流程
|
|
/// </summary>
|
|
public void StartProcess(UnityAction<ProcessEnum> processOver = null)
|
|
{
|
|
this.processOverEvent = processOver;
|
|
finishedStep = new List<string>();
|
|
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("未完成流程规划 无法开始");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 清空流程
|
|
/// </summary>
|
|
public void ClearProcess()
|
|
{
|
|
stepNodesDic.Clear();
|
|
stepRelations.Clear();
|
|
planningOver = false;
|
|
currentLastStep = null;
|
|
StepOverEvent = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 初始化拆卸流程关系 安装流程直接反转
|
|
/// </summary>
|
|
/// <param name="stepRelations">所有节点的前后关系 </param>
|
|
/// <param name="lastStep">最终节点</param>
|
|
public void InitStepRelationDic(List<StepRelation> stepRelations, string teardownLastStep, string assembleLastStep)
|
|
{
|
|
this.stepRelations = stepRelations;
|
|
this.teardownLastStep = teardownLastStep;
|
|
this.assembleLastStep = assembleLastStep;
|
|
CheckStep();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 设置流程类型
|
|
/// </summary>
|
|
/// <param name="processName"> 拆卸 OR 装配</param>
|
|
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("安装流程需手动规划");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 规划两个节点关系
|
|
/// </summary>
|
|
/// <param name="preconditionNodeName">前置节点名称</param>
|
|
/// <param name="postpositionNodeName">后置节点名称</param>
|
|
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<StepNodeBase> tempSteps = item.Value.postpositionNodes;//
|
|
item.Value.ProcessStop();
|
|
item.Value.postpositionNodes = item.Value.preconditionNodes;
|
|
item.Value.preconditionNodes = tempSteps;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加特定步骤的完成监听事件
|
|
/// </summary>
|
|
public void RegisterStepFinishedEvent(string stepName, UnityAction stepFinised)
|
|
{
|
|
if (stepNodesDic.ContainsKey(stepName))
|
|
{
|
|
stepNodesDic[stepName].NodeFinished += stepFinised;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"当前流程不存在{stepName}步骤,无法注册结束事件");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加特定步骤的完成监听事件
|
|
/// </summary>
|
|
public void RemoveStepFinishedEvent(string stepName, UnityAction stepFinised)
|
|
{
|
|
if (stepNodesDic.ContainsKey(stepName))
|
|
{
|
|
stepNodesDic[stepName].NodeFinished -= stepFinised;
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError($"当前流程不存在{stepName}步骤,无法注销结束事件");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 遍历配置步骤检查是否缺少对应的实现步骤
|
|
/// </summary>
|
|
public void CheckStep()
|
|
{
|
|
List<string> nullStepNames = new List<string>();
|
|
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]}");
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 获取当前未完成的步骤给与提示
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public List<string> GetUnFinishedtep()
|
|
{
|
|
List<string> allName = new List<string>();
|
|
foreach (var item in stepNodesDic)
|
|
{
|
|
if (item.Value.stepState == NodeFinishState.unFinished)
|
|
{
|
|
allName.Add(item.Key);
|
|
}
|
|
}
|
|
return allName;
|
|
}
|
|
|
|
}
|
|
|
|
//流程名称
|
|
public enum ProcessEnum
|
|
{
|
|
/// <summary>
|
|
/// 拆卸流程
|
|
/// </summary>
|
|
teardown = 1,
|
|
|
|
/// <summary>
|
|
/// 组装流程
|
|
/// </summary>
|
|
assemble = 2,
|
|
}
|
|
|
|
//步骤关系类
|
|
public class StepRelation
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="preName">前置节点</param>
|
|
/// <param name="postName">后置节点</param>
|
|
public StepRelation(string preName, string postName)
|
|
{
|
|
preconditionNodeName = preName;
|
|
postpositionNodeName = postName;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 前置节点
|
|
/// </summary>
|
|
public string preconditionNodeName;
|
|
|
|
/// <summary>
|
|
/// 后置节点
|
|
/// </summary>
|
|
public string postpositionNodeName;
|
|
}
|
|
|
|
|