private void BeginCurrentStep() { _executing = false; _currentContent = _stepContents[_currentStep]; _currentTarget = _currentContent.Target.GetComponent <StepTarget>(); //UGUI按钮点击型步骤,注册监听 if (_currentContent.Trigger == StepTrigger.ButtonClick) { _isButtonClick = false; _currentButton = _currentContent.Target.GetComponent <Button>(); if (_currentButton) { _currentButton.onClick.AddListener(ButtonClickCallback); } else { GlobalTools.LogError(string.Format("【步骤:{0}】的目标丢失Button组件!", _currentStep + 1)); } } //状态改变触发类型的步骤,自动重置状态 else if (_currentContent.Trigger == StepTrigger.StateChange) { _currentTarget.State = StepTargetState.Normal; } //创建步骤助手 if (_currentContent.Helper != "<None>") { Type type = GlobalTools.GetTypeInRunTimeAssemblies(_currentContent.Helper); if (type != null) { _currentHelper = Activator.CreateInstance(type) as StepHelper; _currentHelper.Parameters = _currentContent.Parameters; for (int i = 0; i < _currentHelper.Parameters.Count; i++) { if (_currentHelper.Parameters[i].Type == StepParameter.ParameterType.GameObject) { if (_targets.ContainsKey(_currentHelper.Parameters[i].GameObjectGUID)) { _currentHelper.Parameters[i].GameObjectValue = _targets[_currentHelper.Parameters[i].GameObjectGUID].gameObject; } } } _currentHelper.Content = _currentContent; _currentHelper.Target = _currentTarget; _currentHelper.Task = StepHelperTask.Execute; _currentHelper.OnInit(); } else { GlobalTools.LogError(string.Format("【步骤:{0}】的助手 {1} 丢失!", _currentStep + 1, _currentContent.Helper)); } } if (_stepContentEnables.ContainsKey(_currentContent.GUID)) { BeginStepEvent?.Invoke(_currentContent, _stepContentEnables[_currentContent.GUID]); if (!_stepContentEnables[_currentContent.GUID]) { StartCoroutine(SkipCurrentStepCoroutine()); } } else { BeginStepEvent?.Invoke(_currentContent, false); } }
private IEnumerator SkipStepCoroutine(int index) { _executing = true; _skipIndex = index; while (_currentStep < _skipIndex) { _currentContent = _stepContents[_currentStep]; _currentTarget = _currentContent.Target.GetComponent <StepTarget>(); _currentContent.Skip(this); SkipStepEvent?.Invoke(_currentContent, _stepContentEnables.ContainsKey(_currentContent.GUID) ? _stepContentEnables[_currentContent.GUID] : false); //UGUI按钮点击型步骤,自动执行按钮事件 if (_currentContent.Trigger == StepTrigger.ButtonClick) { if (_currentButton) { _currentButton.onClick.Invoke(); } else { _currentButton = _currentContent.Target.GetComponent <Button>(); if (_currentButton) { _currentButton.onClick.Invoke(); } else { GlobalTools.LogError(string.Format("【步骤:{0}】的目标丢失Button组件!", _currentStep + 1)); } } _currentButton = null; } //创建步骤助手 if (_currentHelper == null && _currentContent.Helper != "<None>") { Type type = GlobalTools.GetTypeInRunTimeAssemblies(_currentContent.Helper); if (type != null) { _currentHelper = Activator.CreateInstance(type) as StepHelper; _currentHelper.Parameters = _currentContent.Parameters; for (int i = 0; i < _currentHelper.Parameters.Count; i++) { if (_currentHelper.Parameters[i].Type == StepParameter.ParameterType.GameObject) { if (_targets.ContainsKey(_currentHelper.Parameters[i].GameObjectGUID)) { _currentHelper.Parameters[i].GameObjectValue = _targets[_currentHelper.Parameters[i].GameObjectGUID].gameObject; } } } _currentHelper.Content = _currentContent; _currentHelper.Target = _currentTarget; _currentHelper.Task = StepHelperTask.Skip; _currentHelper.OnInit(); } else { GlobalTools.LogError(string.Format("【步骤:{0}】的助手 {1} 丢失!", _currentStep + 1, _currentContent.Helper)); } } //助手执行跳过,等待生命周期结束后销毁助手 if (_currentHelper != null) { _currentHelper.Task = StepHelperTask.Skip; _currentHelper.OnSkip(); if (_currentHelper.SkipLifeTime > 0) { yield return(YieldInstructioner.GetWaitForSeconds(_currentHelper.SkipLifeTime / SkipMultiple)); } _currentHelper.OnTermination(); _currentHelper = null; } yield return(YieldInstructioner.GetWaitForSeconds(_currentContent.ElapseTime / SkipMultiple)); _currentStep += 1; } SkipStepDoneEvent?.Invoke(); yield return(WaitCoroutine(BeginCurrentStep, 0)); }
/// <summary> /// 重新编译步骤内容 /// </summary> /// <param name="prohibitStepID">禁用的步骤ID列表(当为null时启用所有步骤,禁用的步骤会自动跳过)</param> public void RecompileStepContent(HashSet <string> prohibitStepID = null) { if (ContentAsset) { //搜寻框架下所有目标 _targets.Clear(); List <StepTarget> targets = new List <StepTarget>(); Main.Current.transform.GetComponentsInChildren(true, targets); for (int i = 0; i < targets.Count; i++) { if (!_targets.ContainsKey(targets[i].GUID)) { _targets.Add(targets[i].GUID, targets[i]); } else { GlobalTools.LogWarning(string.Format("发现相同GUID的目标!GUID:{0}\r\n目标物体:{1} 和 {2}", targets[i].GUID, _targets[targets[i].GUID].transform.FullName(), targets[i].transform.FullName())); } } //搜寻场景所有目标 GameObject[] rootObjs = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects(); foreach (GameObject rootObj in rootObjs) { targets.Clear(); rootObj.transform.GetComponentsInChildren(true, targets); for (int i = 0; i < targets.Count; i++) { if (!_targets.ContainsKey(targets[i].GUID)) { _targets.Add(targets[i].GUID, targets[i]); } else { GlobalTools.LogWarning(string.Format("发现相同GUID的目标!GUID:{0}\r\n目标物体:{1} 和 {2}", targets[i].GUID, _targets[targets[i].GUID].transform.FullName(), targets[i].transform.FullName())); } } } //判断步骤ID是否重复 _stepContentIDs.Clear(); for (int i = 0; i < ContentAsset.Content.Count; i++) { StepContent content = ContentAsset.Content[i]; if (_stepContentIDs.ContainsKey(content.GUID)) { GlobalTools.LogError(string.Format("发现相同GUID的步骤!GUID:{0}\r\n步骤:{1} 和 {2}", content.GUID, _stepContentIDs[content.GUID].Name, content.Name)); return; } else { _stepContentIDs.Add(content.GUID, content); } } _stepContents.Clear(); _stepContentEnables.Clear(); _stepContentIndexs.Clear(); //启用所有步骤 if (prohibitStepID == null) { for (int i = 0; i < ContentAsset.Content.Count; i++) { StepContent content = ContentAsset.Content[i]; if (_targets.ContainsKey(content.TargetGUID)) { content.Target = _targets[content.TargetGUID].gameObject; } else { GlobalTools.LogError(string.Format("【步骤:{0}】【{1}】目标没有找到,目标路径:{2}", i, content.Name, content.TargetPath)); } for (int j = 0; j < content.Operations.Count; j++) { StepOperation operation = content.Operations[j]; if (_targets.ContainsKey(operation.TargetGUID)) { operation.Target = _targets[operation.TargetGUID].gameObject; } else { GlobalTools.LogError(string.Format("【步骤:{0}】【操作:{1}】目标没有找到,目标路径:{2}", i, operation.Name, operation.TargetPath)); } } _stepContents.Add(content); if (!_stepContentEnables.ContainsKey(content.GUID)) { _stepContentEnables.Add(content.GUID, true); _stepContentIndexs.Add(content.GUID, _stepContents.Count - 1); } } } //禁用 prohibitStepID 指定的步骤 else { for (int i = 0; i < ContentAsset.Content.Count; i++) { StepContent content = ContentAsset.Content[i]; if (_targets.ContainsKey(content.TargetGUID)) { content.Target = _targets[content.TargetGUID].gameObject; } else { GlobalTools.LogError(string.Format("【步骤:{0}】【{1}】目标没有找到,目标路径:{2}", i, content.Name, content.TargetPath)); } for (int j = 0; j < content.Operations.Count; j++) { StepOperation operation = content.Operations[j]; if (_targets.ContainsKey(operation.TargetGUID)) { operation.Target = _targets[operation.TargetGUID].gameObject; } else { GlobalTools.LogError(string.Format("【步骤:{0}】【操作:{1}】目标没有找到,目标路径:{2}", i, operation.Name, operation.TargetPath)); } } _stepContents.Add(content); if (!_stepContentEnables.ContainsKey(content.GUID)) { _stepContentEnables.Add(content.GUID, !prohibitStepID.Contains(ContentAsset.Content[i].GUID)); _stepContentIndexs.Add(content.GUID, _stepContents.Count - 1); } } } _currentStep = 0; _currentContent = null; _currentTarget = null; _running = false; _pause = false; _executing = false; ClearCustomOrder(); } else { GlobalTools.LogError("步骤控制器丢失了步骤资源 Step Content Asset!"); } }
/// <summary> /// 恢复到指定步骤 /// </summary> /// <param name="stepID">步骤ID</param> /// <returns>恢复成功/失败</returns> public bool RestoreStep(string stepID) { if (_running && !_executing) { if (_pause) { return(false); } if (!_stepContentIndexs.ContainsKey(stepID)) { return(false); } int index = _stepContentIndexs[stepID]; if (index < 0 || index >= _currentStep) { return(false); } while (_currentStep >= index) { _currentContent = _stepContents[_currentStep]; _currentTarget = _currentContent.Target.GetComponent <StepTarget>(); RestoreStepEvent?.Invoke(_currentContent, _stepContentEnables.ContainsKey(_currentContent.GUID) ? _stepContentEnables[_currentContent.GUID] : false); //创建步骤助手 if (_currentHelper == null && _currentContent.Helper != "<None>") { Type type = GlobalTools.GetTypeInRunTimeAssemblies(_currentContent.Helper); if (type != null) { _currentHelper = Activator.CreateInstance(type) as StepHelper; _currentHelper.Parameters = _currentContent.Parameters; for (int i = 0; i < _currentHelper.Parameters.Count; i++) { if (_currentHelper.Parameters[i].Type == StepParameter.ParameterType.GameObject) { if (_targets.ContainsKey(_currentHelper.Parameters[i].GameObjectGUID)) { _currentHelper.Parameters[i].GameObjectValue = _targets[_currentHelper.Parameters[i].GameObjectGUID].gameObject; } } } _currentHelper.Content = _currentContent; _currentHelper.Target = _currentTarget; _currentHelper.Task = StepHelperTask.Restore; _currentHelper.OnInit(); } else { GlobalTools.LogError(string.Format("【步骤:{0}】的助手 {1} 丢失!", _currentStep + 1, _currentContent.Helper)); } } //助手执行恢复 if (_currentHelper != null) { _currentHelper.Task = StepHelperTask.Restore; _currentHelper.OnRestore(); _currentHelper.OnTermination(); _currentHelper = null; } _currentStep -= 1; } _currentStep = index; BeginCurrentStep(); return(true); } else { return(false); } }
/// <summary> /// 重新编译步骤内容,在更改步骤资源 ContentAsset 后,必须重新编译一次才可以开始步骤流程 /// </summary> /// <param name="disableStepIDs">禁用的步骤ID集合(当为null时启用所有步骤,禁用的步骤会自动跳过)</param> public void RecompileStepContent(HashSet <string> disableStepIDs = null) { if (ContentAsset) { #region 搜寻步骤目标 //搜寻场景中所有步骤目标 _targets.Clear(); List <GameObject> rootObjs = new List <GameObject>(); List <StepTarget> targetCaches = new List <StepTarget>(); GlobalTools.GetRootGameObjectsInAllScene(rootObjs); foreach (GameObject rootObj in rootObjs) { targetCaches.Clear(); rootObj.transform.GetComponentsInChildren(true, targetCaches); for (int i = 0; i < targetCaches.Count; i++) { if (!_targets.ContainsKey(targetCaches[i].GUID)) { _targets.Add(targetCaches[i].GUID, targetCaches[i]); } else { Log.Warning(string.Format("步骤控制者:发现相同GUID的目标!GUID:{0}\r\n目标物体:{1} 和 {2}", targetCaches[i].GUID, _targets[targetCaches[i].GUID].transform.FullName(), targetCaches[i].transform.FullName())); } } } #endregion #region 判断步骤ID是否重复 _stepContentIDs.Clear(); for (int i = 0; i < ContentAsset.Content.Count; i++) { StepContent content = ContentAsset.Content[i]; if (_stepContentIDs.ContainsKey(content.GUID)) { Log.Error(string.Format("步骤控制者:发现相同GUID的步骤!GUID:{0}\r\n步骤:{1} 和 {2}", content.GUID, _stepContentIDs[content.GUID].Name, content.Name)); } else { _stepContentIDs.Add(content.GUID, content); } } #endregion #region 生成所有步骤信息 _stepContents.Clear(); _stepContentEnables.Clear(); _stepContentIndexs.Clear(); //启用所有步骤 if (disableStepIDs == null || disableStepIDs.Count == 0) { for (int i = 0; i < ContentAsset.Content.Count; i++) { StepContent content = ContentAsset.Content[i]; if (_targets.ContainsKey(content.TargetGUID)) { content.Target = _targets[content.TargetGUID].gameObject; } else { Log.Error(string.Format("步骤控制者:【步骤:{0}】【{1}】目标没有找到,目标路径:{2}", i, content.Name, content.TargetPath)); } for (int j = 0; j < content.Operations.Count; j++) { StepOperation operation = content.Operations[j]; if (_targets.ContainsKey(operation.TargetGUID)) { operation.Target = _targets[operation.TargetGUID].gameObject; } else { Log.Error(string.Format("步骤控制者:【步骤:{0}】【操作:{1}】目标没有找到,目标路径:{2}", i, operation.Name, operation.TargetPath)); } } _stepContents.Add(content); if (!_stepContentEnables.ContainsKey(content.GUID)) { _stepContentEnables.Add(content.GUID, true); _stepContentIndexs.Add(content.GUID, _stepContents.Count - 1); } } } //禁用 disableStepIDs 指定的步骤 else { for (int i = 0; i < ContentAsset.Content.Count; i++) { StepContent content = ContentAsset.Content[i]; if (_targets.ContainsKey(content.TargetGUID)) { content.Target = _targets[content.TargetGUID].gameObject; } else { Log.Error(string.Format("步骤控制者:【步骤:{0}】【{1}】目标没有找到,目标路径:{2}", i, content.Name, content.TargetPath)); } for (int j = 0; j < content.Operations.Count; j++) { StepOperation operation = content.Operations[j]; if (_targets.ContainsKey(operation.TargetGUID)) { operation.Target = _targets[operation.TargetGUID].gameObject; } else { Log.Error(string.Format("步骤控制者:【步骤:{0}】【操作:{1}】目标没有找到,目标路径:{2}", i, operation.Name, operation.TargetPath)); } } _stepContents.Add(content); if (!_stepContentEnables.ContainsKey(content.GUID)) { _stepContentEnables.Add(content.GUID, !disableStepIDs.Contains(content.GUID)); _stepContentIndexs.Add(content.GUID, _stepContents.Count - 1); } } } _currentStepIndex = 0; _currentContent = null; _currentTarget = null; _currentHelper = null; _running = false; _pause = false; _executing = false; ClearCustomOrder(); #endregion } else { throw new HTFrameworkException(HTFrameworkModule.StepEditor, "步骤控制者:重新编译步骤失败,步骤控制者丢失了步骤资源 StepContentAsset!"); } }
/// <summary> /// 跳过到指定步骤(立即模式) /// </summary> /// <param name="index">步骤索引</param> private void SkipStepImmediateCoroutine(int index) { _executing = true; _skipTargetIndex = index; while (_currentStepIndex < _skipTargetIndex) { _currentContent = _stepContents[_currentStepIndex]; _currentTarget = _currentContent.Target.GetComponent <StepTarget>(); SkipStepImmediateEvent?.Invoke(_currentContent, _stepContentEnables.ContainsKey(_currentContent.GUID) ? _stepContentEnables[_currentContent.GUID] : false); //UGUI按钮点击型步骤,自动执行按钮事件 if (_currentContent.Trigger == StepTrigger.ButtonClick) { if (_currentButton) { _currentButton.onClick.Invoke(); _currentButton.onClick.RemoveListener(ButtonClickCallback); } else { _currentButton = _currentContent.Target.GetComponent <Button>(); if (_currentButton) { _currentButton.onClick.Invoke(); } else { Log.Error(string.Format("步骤控制器:【步骤:{0}】【{1}】的目标丢失Button组件!", _currentStepIndex + 1, _currentContent.Name)); } } _currentButton = null; } //创建步骤助手 if (_currentHelper == null && _currentContent.Helper != "<None>") { Type type = ReflectionToolkit.GetTypeInRunTimeAssemblies(_currentContent.Helper); if (type != null) { _currentHelper = Activator.CreateInstance(type) as StepHelper; _currentHelper.Parameters = _currentContent.Parameters; for (int i = 0; i < _currentHelper.Parameters.Count; i++) { if (_currentHelper.Parameters[i].Type == StepParameter.ParameterType.GameObject) { if (_targets.ContainsKey(_currentHelper.Parameters[i].GameObjectGUID)) { _currentHelper.Parameters[i].GameObjectValue = _targets[_currentHelper.Parameters[i].GameObjectGUID].gameObject; } } } _currentHelper.Content = _currentContent; _currentHelper.Target = _currentTarget; _currentHelper.Task = CurrentTask = StepHelperTask.SkipImmediate; _currentHelper.OnInit(); } else { Log.Error(string.Format("步骤控制器:【步骤:{0}】【{1}】的助手 {2} 丢失!", _currentStepIndex + 1, _currentContent.Name, _currentContent.Helper)); } } _currentContent.SkipImmediate(); //助手执行跳过,等待生命周期结束后销毁助手 if (_currentHelper != null) { _currentHelper.Task = CurrentTask = StepHelperTask.SkipImmediate; _currentHelper.OnSkipImmediate(); _currentHelper.OnTermination(); _currentHelper = null; } _currentStepIndex += 1; } BeginCurrentStep(); }
public static void ShowWindow(StepEditorWindow stepEditorWindow, StepContentAsset contentAsset, StepContent content) { StepParameterWindow window = GetWindow <StepParameterWindow>(); window.titleContent.image = EditorGUIUtility.IconContent("d_editicon.sml").image; window.titleContent.text = "Parameters"; window._stepEditorWindow = stepEditorWindow; window._contentAsset = contentAsset; window._content = content; window.minSize = new Vector2(300, 300); window.maxSize = new Vector2(300, 900); window.Show(); }
/// <summary> /// 跳过到指定步骤 /// </summary> /// <param name="index">步骤索引</param> private IEnumerator SkipStepCoroutine(int index) { _executing = true; _skipTargetIndex = index; CurrentTask = StepHelperTask.Skip; while (_currentStepIndex < _skipTargetIndex) { _currentContent = _stepContents[_currentStepIndex]; _currentTarget = _currentContent.Target.GetComponent <StepTarget>(); //UGUI按钮点击型步骤,自动执行按钮事件 if (_currentContent.Trigger == StepTrigger.ButtonClick) { if (_currentButton) { _currentButton.onClick.Invoke(); _currentButton.onClick.RemoveListener(ButtonClickCallback); } else { _currentButton = _currentContent.Target.GetComponent <Button>(); if (_currentButton) { _currentButton.onClick.Invoke(); } else { Log.Error(string.Format("步骤控制器:【步骤:{0}】【{1}】的目标丢失Button组件!", _currentStepIndex + 1, _currentContent.Name)); } } _currentButton = null; } //创建步骤助手 if (_currentHelper == null) { _currentHelper = CreateHelper(_currentContent, StepHelperTask.Skip); } _currentContent.Skip(); SkipStepEvent?.Invoke(_currentContent, _currentContent.IsEnable && _currentContent.IsEnableRunTime); float elapseTime = _currentContent.Instant ? 0 : (_currentHelper != null ? _currentHelper.ElapseTime : _currentContent.ElapseTime); //助手执行跳过,等待生命周期结束后销毁助手 if (_currentHelper != null) { _currentHelper.Task = StepHelperTask.Skip; _currentHelper.OnSkip(); if (_currentHelper.SkipLifeTime > 0) { yield return(YieldInstructioner.GetWaitForSeconds(_currentHelper.SkipLifeTime)); } _currentHelper.OnTermination(); _currentHelper = null; } yield return(YieldInstructioner.GetWaitForSeconds(elapseTime)); _currentStepIndex += 1; } SkipStepDoneEvent?.Invoke(); _waitCoroutine = Main.Current.StartCoroutine(WaitCoroutine(BeginCurrentStep, 0)); }
/// <summary> /// 设置预览目标的初始变换 /// </summary> /// <param name="stepContent">步骤内容</param> /// <param name="operationIndex">步骤操作的索引</param> internal void SetPreviewTransform(StepContent stepContent, int operationIndex) { //已读取的节点 HashSet <int> alreadyReads = new HashSet <int>(); //是否已设置预览目标位置 bool isSetPosition = false; //是否已设置预览目标旋转 bool isSetRotation = false; //是否已设置预览目标缩放 bool isSetScale = false; //当前的连线右端节点 int index = operationIndex; while (true) { //已经完成预览目标的变换设置,结束遍历 if (isSetPosition && isSetRotation && isSetScale) { break; } //标记节点已读取 alreadyReads.Add(index); //读取连线左侧节点 int leftIndex = stepContent.GetLeftIndex(index); //左侧存在节点 if (leftIndex >= 0) { //如果重复读取到相同节点,则存在循环连线,结束遍历 if (alreadyReads.Contains(leftIndex)) { break; } //获取左侧节点,并设置位置、旋转、缩放 StepOperation operation = stepContent.Operations[leftIndex]; if (operation.Target == Target) { if (!isSetPosition) { if (operation.OperationType == StepOperationType.Move) { PreviewTarget.transform.localPosition = operation.Vector3Value; isSetPosition = true; } else if (operation.OperationType == StepOperationType.Transform) { PreviewTarget.transform.localPosition = operation.Vector3Value; isSetPosition = true; } } if (!isSetRotation) { if (operation.OperationType == StepOperationType.Rotate) { PreviewTarget.transform.localRotation = operation.Vector3Value.ToQuaternion(); isSetRotation = true; } else if (operation.OperationType == StepOperationType.Transform) { PreviewTarget.transform.localRotation = operation.Vector3Value2.ToQuaternion(); isSetRotation = true; } } if (!isSetScale) { if (operation.OperationType == StepOperationType.Scale) { PreviewTarget.transform.localScale = operation.Vector3Value; isSetScale = true; } else if (operation.OperationType == StepOperationType.Transform) { PreviewTarget.transform.localScale = operation.Vector3Value3; isSetScale = true; } } } index = leftIndex; } //左侧已不存在节点,结束遍历 else { break; } } //未找到连线中的移动相关节点,设置位置为初始值 if (!isSetPosition) { PreviewTarget.transform.localPosition = Target.transform.localPosition; } //未找到连线中的旋转相关节点,设置旋转为初始值 if (!isSetRotation) { PreviewTarget.transform.localRotation = Target.transform.localRotation; } //未找到连线中的缩放相关节点,设置缩放为初始值 if (!isSetScale) { PreviewTarget.transform.localScale = Target.transform.localScale; } alreadyReads = null; }