Răsfoiți Sursa

【箭头提示】

CHIVA\bj 6 luni în urmă
părinte
comite
deb5b941df
23 a modificat fișierele cu 1008 adăugiri și 22 ștergeri
  1. 43 0
      Framework/Scripts/Proxys/FreeStepListProxy.cs
  2. 11 0
      Framework/Scripts/Proxys/FreeStepListProxy.cs.meta
  3. 1 5
      Framework/Scripts/Proxys/Models/OperationStepDataInfo.cs
  4. 21 0
      Framework/Scripts/Proxys/Models/OperationStepFreeCondition.cs
  5. 11 0
      Framework/Scripts/Proxys/Models/OperationStepFreeCondition.cs.meta
  6. 1 1
      Framework/Scripts/ScaleContronl.cs
  7. 34 3
      Framework/Scripts/UI/PCController/OperateSetting.cs
  8. 2 1
      Framework/SimulationToolDev/BuilderDriver/OperationListener.cs
  9. 63 0
      Framework/SimulationToolDev/OperationDriver/OperationData-Example/TriggerMode/OpTrigger_Toolbackpack/OpTrigger_ToolPack.cs
  10. 128 0
      Framework/SimulationToolDev/Process/Scripts/Manager/FreeProcessManagement.cs
  11. 11 0
      Framework/SimulationToolDev/Process/Scripts/Manager/FreeProcessManagement.cs.meta
  12. 7 4
      OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel.Designer.cs
  13. 126 4
      OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel.cs
  14. 8 0
      OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel.meta
  15. 29 0
      OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel/TipsFreeIconItem.Designer.cs
  16. 11 0
      OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel/TipsFreeIconItem.Designer.cs.meta
  17. 30 0
      OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel/TipsFreeIconItem.cs
  18. 11 0
      OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel/TipsFreeIconItem.cs.meta
  19. 16 0
      OperationUIFrame/OperationUIFrameV2/Scripts/UI/PC_OperatePanel.cs
  20. 0 1
      OperationUIFrame/OperationUIFrameV2/Scripts/UI/PC_OperatePanel/OperateStep.cs
  21. 0 2
      OperationUIFrame/OperationUIFrameV2/Scripts/UI/PC_OperatePanel/OperateStep/SecondStepItem.cs
  22. 24 0
      OperationUIFrame/OperationUIFrameV2/Scripts/UI/PC_OperatePanel/StartTips.cs
  23. 420 1
      OperationUIFrame/OperationUIFrameV2/UIPrefabs/ArrowTipsPanel.prefab

+ 43 - 0
Framework/Scripts/Proxys/FreeStepListProxy.cs

@@ -0,0 +1,43 @@
+using System.Collections.Generic;
+
+public class FreeStepListProxy : DataProxy
+{
+    public List<OperationStepFreeCondition> m_OpertaionFreeConditions;
+
+    /// <summary>
+    /// 表格名称
+    /// </summary>
+    string m_TableName;
+
+    /// <summary>
+    /// 根据id获取信息
+    /// </summary>
+    public OperationStepFreeCondition GetOpStepDataInfoById(int operationId)
+    {
+        return m_OpertaionFreeConditions.Find(t => t.id == operationId.ToString());
+    }
+
+    /// <summary>
+    /// 从Excel文件读取流程信息
+    /// </summary>
+    /// <param name="tableName">表明</param>
+    /// <param name="headCount">表头</param>
+    /// <returns></returns>
+    public List<OperationStepFreeCondition> ReadStepMsgInfoFromTable(string tableName)
+    {
+        m_TableName = tableName + "_FreeCondition" + GlobalConfig.excelSuffix;
+
+        m_OpertaionFreeConditions = new List<OperationStepFreeCondition>();
+
+        string tmpPath = System.IO.Path.Combine(GlobalConfig.operateTablePath, m_TableName);
+
+        m_OpertaionFreeConditions = ExcelHelper.ReadInfoFromExcel<OperationStepFreeCondition>(tmpPath, 1);
+
+        return m_OpertaionFreeConditions;
+    }
+
+    public OperationStepFreeCondition GetOperationStepDataInfoById(int id)
+    {
+        return m_OpertaionFreeConditions.Find(t => int.Parse(t.id) == id);
+    }
+}

+ 11 - 0
Framework/Scripts/Proxys/FreeStepListProxy.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 543314d536a79ba44968c144967638f4
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1 - 5
Framework/Scripts/Proxys/Models/OperationStepDataInfo.cs

@@ -70,8 +70,6 @@ public class OperationStepDataInfo
     [ReadOnly]
     public string guid;
 
-
-
     /// <summary>
     /// 获取所有的视频名称
     /// </summary>
@@ -80,9 +78,7 @@ public class OperationStepDataInfo
     public List<string> GetVideoNames()
     {
         if (string.IsNullOrEmpty(stepVideoNames)) return null;
-
         string[] tmpVideoNames = stepVideoNames.Split('/');
-
         UnityEngine.Debug.Log(tmpVideoNames.Length);
         return tmpVideoNames.ToList();
     }
@@ -100,4 +96,4 @@ public class OperationStepDataInfo
         UnityEngine.Debug.Log(tmpPictureNames.Length);
         return tmpPictureNames.ToList();
     }
-}
+}

+ 21 - 0
Framework/Scripts/Proxys/Models/OperationStepFreeCondition.cs

@@ -0,0 +1,21 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class OperationStepFreeCondition 
+{
+    /// <summary>
+    /// 步骤ID
+    /// </summary>
+    public string id;
+
+    /// <summary>
+    /// 步骤名称
+    /// </summary>
+    public string stepName;
+
+    /// <summary>
+    /// 前置步骤ID列表
+    /// </summary>
+    public string preStepCondition;
+}

+ 11 - 0
Framework/Scripts/Proxys/Models/OperationStepFreeCondition.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 6c6bd2dc052de924c98a430594c934a8
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1 - 1
Framework/Scripts/ScaleContronl.cs

@@ -26,4 +26,4 @@ public class ScaleContronl : MonoBehaviour
             t.localScale = new Vector3(t.localScale.x,scale,t.localScale.z);
         }
     }
-}
+}

+ 34 - 3
Framework/Scripts/UI/PCController/OperateSetting.cs

@@ -30,6 +30,16 @@ public enum OperationMode
     /// </summary>
     [LabelText("闯关模式")]
     Challenge,
+    /// <summary>
+    /// 自由练习
+    /// </summary>
+    [LabelText("自由练习模式")]
+    FreeParctice,
+    /// <summary>
+    /// 自由考核
+    /// </summary>
+    [LabelText("自由考核模式")]
+    FreeExam,
 
     [LabelText("默认空模式")]
     None
@@ -212,14 +222,27 @@ public class OperateSetting : MonoSingleton<OperateSetting>
         }
 
         InitOperationMode();
-        ProcessManagement.Instance.ActiveCurrentProcess();   
+
+        if (m_CurrentOperationMode == OperationMode.FreeParctice || m_CurrentOperationMode == OperationMode.FreeExam)
+        {
+            FreeProcessManagement.Instance.ActiveProcess();
+            //关闭自动执行步骤
+            ProcessManagement.Instance.autoEnterNextProcess = false;
+        }
+        else
+        {
+            ProcessManagement.Instance.ActiveCurrentProcess();
+        }
     }
 
     public void InitOperationMode()
     {
-        foreach (var item in ProcessManagement.Instance.processes)
+        if (m_CurrentOperationMode != OperationMode.FreeParctice)
         {
-            item.preprocess = item.GetOrAddComponent<Preprocess_VoiceAndCamera>();
+            foreach (var item in ProcessManagement.Instance.processes)
+            {
+                item.preprocess = item.GetOrAddComponent<Preprocess_VoiceAndCamera>();
+            }
         }
         switch (m_CurrentOperationMode)
         {
@@ -240,6 +263,14 @@ public class OperateSetting : MonoSingleton<OperateSetting>
                 Preprocess_VoiceAndCamera.WaitAudioFinishedToExit = false;
                 Preprocess_VoiceAndCamera.WaitViewFinishedToExit = false;
 
+                break;
+            case OperationMode.FreeParctice:
+            case OperationMode.FreeExam:
+                Preprocess_VoiceAndCamera.playView = false;
+                Preprocess_VoiceAndCamera.playAudio = false;
+                Preprocess_VoiceAndCamera.WaitAudioFinishedToExit = false;
+                Preprocess_VoiceAndCamera.WaitViewFinishedToExit = false;
+                FreeProcessManagement.Instance.InitFreeProcess(m_CourseName);
                 break;
             case OperationMode.Challenge:
                 break;

+ 2 - 1
Framework/SimulationToolDev/BuilderDriver/OperationListener.cs

@@ -100,6 +100,7 @@ public class OpDataInfo
         {
             Debug.LogError("无该操作名称:" + operationDataName);
         }
+        Debug.Log("激活操作点:" + operationDataName);
         itemOpData.OperationStatus = OperationDataStatus.Listening;
         itemOpData.OperationValueChanged += Trigger;
     }
@@ -149,7 +150,7 @@ public class OpDataInfo
             }
         }
     }
-    /// <summary>
+    /// <summary> 
     /// 动画播放完成
     /// </summary>
     public void OnOpListenerFinished()

+ 63 - 0
Framework/SimulationToolDev/OperationDriver/OperationData-Example/TriggerMode/OpTrigger_Toolbackpack/OpTrigger_ToolPack.cs

@@ -286,6 +286,69 @@ public class OpTrigger_ToolPack : OperationData_TriggerMode
         }
 
         SetHighlighterState(false);
+        if (OperateSetting.Instance.m_CurrentOperationMode==OperationMode.FreeParctice)
+        {
+            if (useTool && choseToolNames.Count != 0)
+            {
+                if (OperateSetting.Instance.m_ToolLibraryToolConfigs.Count != choseToolNames.Count)
+                {
+                    if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject())
+                    {
+                        OperateSetting.Instance.ToolPackUILogic.SelectWrongTool(this);
+                    }
+                    return false;
+                }
+
+                foreach (var toolName in choseToolNames)
+                {
+                    ToolConfig tmpToolConfig = OperateSetting.Instance.m_ToolLibraryToolConfigs.Find(tool => tool.toolName == toolName);
+
+                    if (tmpToolConfig == null)
+                    {
+                        if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject())
+                        {
+                            OperateSetting.Instance.ToolPackUILogic.SelectWrongTool(this);
+                        }
+                        return false;
+                    }
+                }
+            }
+            else if (choseToolNames.Count == 0 && OperateSetting.Instance.m_ToolLibraryToolConfigs.Count != 0)
+            {
+                if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject())
+                {
+                    OperateSetting.Instance.ToolPackUILogic.SelectWrongTool(this);
+                }
+                return false;
+            }
+
+            if (Input.GetMouseButtonDown(0) && !EventSystem.current.IsPointerOverGameObject())
+            {
+                bool tmpResult = false;
+
+                foreach (var item in targetObjs)
+                {
+                    if (CameraRayCastManager.Instance.CheckCurrentHoverItem(item))
+                    {
+                        tmpResult = true;
+                        continue;
+                    }
+                }
+
+                if (tmpResult)
+                {
+                    OperateSetting.Instance.ToolPackUILogic.SelectRightTargetObj(this);
+                    return true;
+                }
+                else
+                {
+                    OperateSetting.Instance.ToolPackUILogic.SelectWrongTargetObj(this);
+                    return false;
+                }
+            }
+
+            return false;
+        }
 
         bool tmpState = OperateSetting.Instance.ToolPackUILogic.GetHint();
 

+ 128 - 0
Framework/SimulationToolDev/Process/Scripts/Manager/FreeProcessManagement.cs

@@ -0,0 +1,128 @@
+using ChivaXR;
+using ChivaXR.Op;
+using QFramework;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using UnityEngine;
+
+/// <summary>
+/// 自由版流程控制
+/// </summary>
+public class FreeProcessManagement : MonoSingleton<FreeProcessManagement>
+{
+    //自由操作清单
+    public List<FreeProcessElement> freeProcessElements = new List<FreeProcessElement>();
+
+    //当前场景中激活的操作
+    public List<ProcessElement> activeProcessElements = new List<ProcessElement>();
+
+    private List<OperationStepFreeCondition> tmpStepFreeConditionss = new List<OperationStepFreeCondition>();
+    public void InitFreeProcess(string courseName)
+    {
+        FreeStepListProxy m_FreeStepListProxy = DAL.Instance.Get<FreeStepListProxy>();
+        tmpStepFreeConditionss = m_FreeStepListProxy.ReadStepMsgInfoFromTable(courseName);
+
+        for (int i = 0; i < tmpStepFreeConditionss.Count; i++)
+        {
+            FreeProcessElement tmpProcessElement = new FreeProcessElement();
+            tmpProcessElement.freeProcessElement = ProcessManagement.Instance.processes[i];
+            foreach (var item in tmpStepFreeConditionss[i].preStepCondition.Split('/'))
+            {
+                if (string.IsNullOrEmpty(item)) { continue; }
+
+                int id = int.Parse(item);
+
+                if (id == 0) continue;
+
+                tmpProcessElement.preconditions.Add(ProcessManagement.Instance.processes[id - 1]);
+            };
+
+            freeProcessElements.Add(tmpProcessElement);
+        }
+    }
+
+    public void ActiveProcess()
+    {
+        foreach (var item in freeProcessElements)
+        {
+            item.Init();
+        }
+    }
+
+    public void RecordProcessElementActiveState(ProcessElement processElement)
+    {
+        if (!activeProcessElements.Contains(processElement))
+        {
+            activeProcessElements.Add(processElement);
+            UIKit.GetPanel<ArrowTipsPanel>().AddProcessElement(processElement, tmpStepFreeConditionss[processElement.stepID - 1].stepName);
+        }
+    }
+    public void RemoveProcessElementActiveState(ProcessElement processElement)
+    {
+        if (activeProcessElements.Contains(processElement))
+        {
+            activeProcessElements.Remove(processElement);
+
+            UIKit.GetPanel<ArrowTipsPanel>().RemoveProcessElement(processElement);
+        }
+    }
+}
+
+public class FreeProcessElement
+{
+    /// <summary>
+    /// 前置流程条件
+    /// </summary>
+    public List<ProcessElement> preconditions = new List<ProcessElement>();
+    public ProcessElement freeProcessElement;
+
+    public void Init()
+    {
+        if (preconditions.Count == 0)
+        {
+            freeProcessElement.Enter();
+        }
+        foreach (ProcessElement element in preconditions)
+        {
+            element.processElementExitHandle += PreConditionProcessFinished;
+        }
+
+        freeProcessElement.processElementExitHandle += FreeProcessElementFinished;
+    }
+
+    /// <summary>
+    /// 前置流程完成检测
+    /// </summary>
+    /// <param name="element"></param>
+    public void PreConditionProcessFinished(ProcessElement element)
+    {
+        bool allPreConditionFinished = true;
+        foreach (var item in preconditions)
+        {
+            if (!item.finished)
+            {
+                allPreConditionFinished = false;
+            }
+        }
+
+        if (allPreConditionFinished && !freeProcessElement.active && !freeProcessElement.finished)
+        {
+            freeProcessElement.Enter();
+
+            FreeProcessManagement.Instance.RecordProcessElementActiveState(freeProcessElement);
+        }
+    }
+
+    /// <summary>
+    /// 当前自由流程完成
+    /// </summary>
+    /// <param name="element"></param>
+    public void FreeProcessElementFinished(ProcessElement element)
+    {
+        if (freeProcessElement == element)
+        {
+            FreeProcessManagement.Instance.RemoveProcessElementActiveState(freeProcessElement);
+        }
+    }
+}

+ 11 - 0
Framework/SimulationToolDev/Process/Scripts/Manager/FreeProcessManagement.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 54ed25f65d89b7b4c846d3c565b2e9f1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 7 - 4
OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel.Designer.cs

@@ -5,13 +5,11 @@ using QFramework;
 
 namespace QFramework
 {
-	// Generate Id:ae849aaa-600d-4adc-a594-9b9f105b7de6
+	// Generate Id:b7a36b7d-26da-4aa1-b5da-de8be9634d11
 	public partial class ArrowTipsPanel
 	{
 		public const string Name = "ArrowTipsPanel";
 		
-		[SerializeField]
-		public UnityEngine.RectTransform OutViewRot;
 		[SerializeField]
 		public UnityEngine.UI.Image OutViewIcon;
 		[SerializeField]
@@ -22,17 +20,22 @@ namespace QFramework
 		public UnityEngine.UI.Text TextInfo;
 		[SerializeField]
 		public UnityEngine.UI.Text DistanceInfo;
+		[SerializeField]
+		public UnityEngine.RectTransform TipsGroup;
+		[SerializeField]
+		public TipsFreeIconItem TipsFreeIconItem;
 		
 		private ArrowTipsPanelData mPrivateData = null;
 		
 		protected override void ClearUIComponents()
 		{
-			OutViewRot = null;
 			OutViewIcon = null;
 			DirRoot = null;
 			TipsIcon = null;
 			TextInfo = null;
 			DistanceInfo = null;
+			TipsGroup = null;
+			TipsFreeIconItem = null;
 			
 			mData = null;
 		}

+ 126 - 4
OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel.cs

@@ -4,6 +4,7 @@ using QFramework;
 using ChivaXR;
 using ChivaXR.Op;
 using Google.Protobuf.WellKnownTypes;
+using System.Collections.Generic;
 
 namespace QFramework
 {
@@ -16,6 +17,11 @@ namespace QFramework
         private Camera viewCamera;
         private OpTrigger_ToolPack opTrigger_ToolPack;
 
+        //多区域提示功能
+        private List<OpTrigger_ToolPack> opTrigger_ToolPacks = new List<OpTrigger_ToolPack>();
+        private Dictionary<OpTrigger_ToolPack, TipsFreeIconItem> dic_TipsFreeIconItems = new Dictionary<OpTrigger_ToolPack, TipsFreeIconItem>();
+        private List<TipsFreeIconItem> tipsFreeIconItemsPool = new List<TipsFreeIconItem>();
+
         public Camera ViewCamera
         {
             get
@@ -47,15 +53,121 @@ namespace QFramework
             }
             m_Canvas = UIRoot.Instance.GetComponent<Canvas>();
             m_CanvasScaler = m_Canvas.GetComponent<CanvasScaler>();
-            ProcessManagement.Instance.preprocessFnishedEvent += PreProcessFinished;
-            ProcessManagement.Instance.processFinishEvent += FinishedProcess;
+
+            if (OperateSetting.Instance.m_CurrentOperationMode == OperationMode.Practice
+                || OperateSetting.Instance.m_CurrentOperationMode == OperationMode.Exam)
+            {
+                ProcessManagement.Instance.preprocessFnishedEvent  += PreProcessFinished;
+                ProcessManagement.Instance.processFinishEvent += FinishedProcess;
+            }
         }
 
         public void LateUpdate()
+        {
+            if (OperateSetting.Instance.m_CurrentOperationMode == OperationMode.Practice
+                || OperateSetting.Instance.m_CurrentOperationMode == OperationMode.Exam)
+            {
+                CheckOperationHint();
+            }
+
+            if (OperateSetting.Instance.m_CurrentOperationMode == OperationMode.FreeParctice
+           || OperateSetting.Instance.m_CurrentOperationMode == OperationMode.FreeParctice)
+            {
+                CheckFreeOperationHint();
+            }
+        }
+        public void AddProcessElement(ProcessElement process, string processName = null) 
+        {
+            PB_OpData pbOpData = process.GetComponent<PB_OpData>();
+            if (OperationManager.Instance.GetOpData(pbOpData.opData.operationDataName) == null)
+            {
+                return;
+            }
+            OpTrigger_ToolPack opTrigger_ToolPack =
+                OperationManager.Instance.GetOpData(pbOpData.opData.operationDataName).gameObject.GetComponent<OpTrigger_ToolPack>();
+
+            if (opTrigger_ToolPack == null)
+            {
+                return;
+            };
+
+            if (!dic_TipsFreeIconItems.ContainsKey(opTrigger_ToolPack))
+            {
+                dic_TipsFreeIconItems.Add(opTrigger_ToolPack, GetTipsFreeIconItem());
+                dic_TipsFreeIconItems[opTrigger_ToolPack].TipsFreeInfo.text = processName;
+            }
+        }
+        public void RemoveProcessElement(ProcessElement process)
+        {
+            PB_OpData pbOpData = process.GetComponent<PB_OpData>();
+            if (OperationManager.Instance.GetOpData(pbOpData.opData.operationDataName) == null)
+            {
+                return;
+            }
+            OpTrigger_ToolPack opTrigger_ToolPack =
+                OperationManager.Instance.GetOpData(pbOpData.opData.operationDataName).gameObject.GetComponent<OpTrigger_ToolPack>();
+
+            if (opTrigger_ToolPack == null)
+            {
+                return;
+            };
+
+            if (dic_TipsFreeIconItems.ContainsKey(opTrigger_ToolPack))
+            {
+                ReleaseTipsFreeIconItem(dic_TipsFreeIconItems[opTrigger_ToolPack]);
+
+                dic_TipsFreeIconItems.Remove(opTrigger_ToolPack);
+            }
+        }
+
+        public TipsFreeIconItem GetTipsFreeIconItem()
+        {
+            if (tipsFreeIconItemsPool.Count == 0)
+            {
+                TipsFreeIconItem tip = GameObject.Instantiate(TipsFreeIconItem).GetComponent<TipsFreeIconItem>();
+                tip.transform.parent = TipsGroup.transform;
+                tip.transform.localScale = Vector3.one;
+                tip.gameObject.SetActive(true);
+                return tip;
+            }
+            else
+            {
+                TipsFreeIconItem tip = tipsFreeIconItemsPool[0];
+                tipsFreeIconItemsPool.Remove(tip);
+                tip.gameObject.SetActive(true);
+                return tip;
+            }
+        }
+        public void ReleaseTipsFreeIconItem(TipsFreeIconItem tip)
+        {
+            tip.gameObject.SetActive(false);
+            tip.TipsFreeInfo.text = "";
+            tipsFreeIconItemsPool.Add(tip);
+        }
+
+        private void CheckFreeOperationHint()
+        {
+            if (dic_TipsFreeIconItems.Count == 0) return;
+
+            foreach (var item in dic_TipsFreeIconItems)
+            {
+                Vector3 viewPos = ViewCamera.WorldToScreenPoint(item.Key.targetObjs[0].transform.position);
+
+                item.Value.GetRectTransform().anchoredPosition = new Vector3(GetFixed(viewPos.x), GetFixed(viewPos.y));
+
+                float distance = Vector3.Distance(item.Key.targetObjs[0].transform.position, ViewCamera.transform.position);
+                item.Value.TipsFreeDistanceInfo.text = distance.ToString("0.00") + "m";
+            }
+        }
+
+        /// <summary>
+        /// 检测执行线性流程提示
+        /// </summary>
+        private void CheckOperationHint()
         {
             if (targetPoint == null || opTrigger_ToolPack == null) return;
 
-            if(opTrigger_ToolPack.OperationStatus!=OperationDataStatus.Listening)
+            if (opTrigger_ToolPack.OperationStatus != OperationDataStatus.Listening)
             {
                 opTrigger_ToolPack = null;
                 Clear();
@@ -87,6 +199,10 @@ namespace QFramework
             }
         }
 
+        /// <summary>
+        /// 前置步骤结束
+        /// </summary>
+        /// <param name="processElement"></param>
         public void PreProcessFinished(ProcessElement processElement)
         {
             if (processElement.GetComponent<PB_OpData>() != null)
@@ -137,6 +253,10 @@ namespace QFramework
                 return value * m_CanvasScaler.referenceResolution.y / Screen.height;
         }
 
+        /// <summary>
+        /// 初始化提示目标
+        /// </summary>
+        /// <param name="target"></param>
         public void InitTarget(Transform target)
         {
             targetPoint = target;
@@ -145,7 +265,6 @@ namespace QFramework
                 targetPoint = targetPoint.Find("HintPoint");
             };
             Debug.Log(targetPoint.name);
-
         }
 
         public void Clear()
@@ -173,6 +292,9 @@ namespace QFramework
         }
 
         private float targetAngle;
+        /// <summary>
+        /// 箭头控制提示控制
+        /// </summary>
         public void ArrowController()
         {
             if (targetPoint == null) return;

+ 8 - 0
OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 96d136e7375bc2348b00c2d2d17aa0f9
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 29 - 0
OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel/TipsFreeIconItem.Designer.cs

@@ -0,0 +1,29 @@
+/****************************************************************************
+ * 2025.5 CHIVA
+ ****************************************************************************/
+
+using UnityEngine;
+using UnityEngine.UI;
+using QFramework;
+
+namespace QFramework
+{
+	public partial class TipsFreeIconItem
+	{
+		[SerializeField] public UnityEngine.UI.Text TipsFreeDistanceInfo;
+		[SerializeField] public UnityEngine.UI.Text TipsFreeInfo;
+		[SerializeField] public UnityEngine.UI.Image TipsIcon;
+
+		public void Clear()
+		{
+			TipsFreeDistanceInfo = null;
+			TipsFreeInfo = null;
+			TipsIcon = null;
+		}
+
+		public override string ComponentName
+		{
+			get { return "TipsFreeIconItem";}
+		}
+	}
+}

+ 11 - 0
OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel/TipsFreeIconItem.Designer.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8f9149339a9850a42abc8323093cb95c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 30 - 0
OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel/TipsFreeIconItem.cs

@@ -0,0 +1,30 @@
+/****************************************************************************
+ * 2025.5 CHIVA
+ ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.UI;
+using QFramework;
+
+namespace QFramework
+{
+	public partial class TipsFreeIconItem : UIElement
+	{
+		private RectTransform _rectTransform;
+		private void Awake()
+		{
+			_rectTransform = GetComponent<RectTransform>();
+		}
+
+		public RectTransform GetRectTransform()
+		{
+			return _rectTransform;
+		}
+
+		protected override void OnBeforeDestroy()
+		{
+		}
+	}
+}

+ 11 - 0
OperationUIFrame/OperationUIFrameV2/Scripts/UI/ArrowTipsPanel/TipsFreeIconItem.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: fc406b98cdc369147a55a7dc2dc06101
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 16 - 0
OperationUIFrame/OperationUIFrameV2/Scripts/UI/PC_OperatePanel.cs

@@ -142,6 +142,22 @@ namespace QFramework
                     OperateStep.EndExam.gameObject.SetActive(true);
                     OperateStep.SubtitleBg.gameObject.SetActive(false);
                     break;
+                case OperationMode.FreeParctice:
+                    operateName = "操作步骤";
+                    OperateStep.HelpBtn.gameObject.SetActive(true);
+                    OperateStep.AutoPlayBtn.gameObject.SetActive(false);
+                    OperateStep.ToolLibraryBtn.gameObject.SetActive(true);
+                    OperateStep.EndExam.gameObject.SetActive(false);
+                    break;
+                case OperationMode.FreeExam:
+                    operateName = "操作步骤";
+                    TitleTextLayoutGroup.gameObject.SetActive(false);
+                    OperateStep.HelpBtn.gameObject.SetActive(false);
+                    OperateStep.AutoPlayBtn.gameObject.SetActive(false);
+                    OperateStep.ToolLibraryBtn.gameObject.SetActive(true);
+                    OperateStep.EndExam.gameObject.SetActive(true);
+                    OperateStep.SubtitleBg.gameObject.SetActive(false);
+                    break;
                 case OperationMode.Challenge:
                     operateName = "操作步骤";
                     OperateStep.HelpBtn.gameObject.SetActive(false);

+ 0 - 1
OperationUIFrame/OperationUIFrameV2/Scripts/UI/PC_OperatePanel/OperateStep.cs

@@ -127,7 +127,6 @@ namespace QFramework
             UIKit.GetPanel<PC_OperatePanel>().SubmitResult.gameObject.SetActive(true);
         }
 
-
         private void OnToolLibraryBtnClick()
         {
             ToolLibraryForm tmpToolLibraryForm = UIKit.GetPanel<ToolLibraryForm>();

+ 0 - 2
OperationUIFrame/OperationUIFrameV2/Scripts/UI/PC_OperatePanel/OperateStep/SecondStepItem.cs

@@ -138,11 +138,9 @@ namespace QFramework
             }
         }
 
-
         protected override void OnBeforeDestroy()
         {
         }
-
         #region ¶àÓïÑÔ
 
         public void RefrushLocalization()

+ 24 - 0
OperationUIFrame/OperationUIFrameV2/Scripts/UI/PC_OperatePanel/StartTips.cs

@@ -57,6 +57,30 @@ namespace QFramework
                         StartInfo.text = "点击任意处开始考试";
                     }
                     break;
+                case OperationMode.FreeParctice:
+                    StartTitle.text = ScriptLocalization.tips.startparticing;
+
+                    if (LocalizationConfig.localization && LocalizationManager.CurrentLanguage == "English")
+                    {
+                        StartInfo.text = "Click to start practicing";
+                    }
+                    else
+                    {
+                        StartInfo.text = "点击任意处开始自由练习";
+                    }
+                    break;
+                case OperationMode.FreeExam:
+                    StartTitle.text = ScriptLocalization.tips.startexam;
+
+                    if (LocalizationConfig.localization && LocalizationManager.CurrentLanguage == "English")
+                    {
+                        StartInfo.text = "Click to start the exam";
+                    }
+                    else
+                    {
+                        StartInfo.text = "点击任意处开始自由考试";
+                    }
+                    break;
                 case OperationMode.Challenge:
                     break;
                 default:

+ 420 - 1
OperationUIFrame/OperationUIFrameV2/UIPrefabs/ArrowTipsPanel.prefab

@@ -148,6 +148,98 @@ MonoBehaviour:
   ComponentGeneratePath: 
   CustomComment: 
   mComponentName: UnityEngine.UI.Image
+--- !u!1 &2975716528522666086
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 7997971434767085548}
+  - component: {fileID: 7083137093642129047}
+  - component: {fileID: 220622125793127717}
+  - component: {fileID: 7830824012931014884}
+  m_Layer: 5
+  m_Name: TipsIcon
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &7997971434767085548
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2975716528522666086}
+  m_LocalRotation: {x: 0, y: 0, z: 0.35836798, w: 0.93358046}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 4963108840602843046}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 42}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 22, y: 40}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &7083137093642129047
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2975716528522666086}
+  m_CullTransparentMesh: 0
+--- !u!114 &220622125793127717
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2975716528522666086}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 0.5568628, b: 0, a: 0.6117647}
+  m_RaycastTarget: 0
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_Sprite: {fileID: 21300000, guid: 84d8a60c5463a254b91e096b45b95fcb, type: 3}
+  m_Type: 0
+  m_PreserveAspect: 0
+  m_FillCenter: 1
+  m_FillMethod: 4
+  m_FillAmount: 1
+  m_FillClockwise: 1
+  m_FillOrigin: 0
+  m_UseSpriteMesh: 0
+  m_PixelsPerUnitMultiplier: 1
+--- !u!114 &7830824012931014884
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 2975716528522666086}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0d51f3a7c41ab0346b49ae50d456bece, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  MarkType: 0
+  CustomComponentName: TipsIcon
+  ComponentGeneratePath: 
+  CustomComment: 
+  mComponentName: UnityEngine.UI.Image
 --- !u!1 &4986953989404606185
 GameObject:
   m_ObjectHideFlags: 0
@@ -244,6 +336,69 @@ MonoBehaviour:
   ComponentGeneratePath: 
   CustomComment: 
   mComponentName: UnityEngine.UI.Text
+--- !u!1 &5660767109672116034
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 4963108840602843046}
+  - component: {fileID: 6282262807917450133}
+  - component: {fileID: -1828617895003550709}
+  m_Layer: 5
+  m_Name: TipsFreeIconItem
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 0
+--- !u!224 &4963108840602843046
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5660767109672116034}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 7871946730989972981}
+  - {fileID: 8317964850212505717}
+  - {fileID: 7997971434767085548}
+  m_Father: {fileID: 1933937345230459504}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 0, y: 0}
+  m_AnchoredPosition: {x: 1039.5, y: 540}
+  m_SizeDelta: {x: 22, y: 40}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &6282262807917450133
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5660767109672116034}
+  m_CullTransparentMesh: 0
+--- !u!114 &-1828617895003550709
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 5660767109672116034}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: fc406b98cdc369147a55a7dc2dc06101, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  TipsFreeDistanceInfo: {fileID: 3866713734906809122}
+  TipsFreeInfo: {fileID: 4159299806600508353}
+  TipsIcon: {fileID: 220622125793127717}
 --- !u!1 &5944042392112209522
 GameObject:
   m_ObjectHideFlags: 0
@@ -367,6 +522,7 @@ RectTransform:
   m_Children:
   - {fileID: 5644093020826214090}
   - {fileID: 4702926574991604468}
+  - {fileID: 1933937345230459504}
   m_Father: {fileID: 0}
   m_RootOrder: 0
   m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
@@ -387,12 +543,67 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 1e8aef27dd4e3a74d993ca0066147dff, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
-  OutViewRot: {fileID: 0}
   OutViewIcon: {fileID: 3980019796785462024}
   DirRoot: {fileID: 4644898829103029097}
   TipsIcon: {fileID: 1739155864769243425}
   TextInfo: {fileID: 6341556919001058411}
   DistanceInfo: {fileID: 536085273444228543}
+  TipsGroup: {fileID: 1933937345230459504}
+  TipsFreeIconItem: {fileID: -1828617895003550709}
+--- !u!1 &6635742060741568579
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 1933937345230459504}
+  - component: {fileID: 1305929652721192479}
+  m_Layer: 5
+  m_Name: TipsGroup
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &1933937345230459504
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6635742060741568579}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children:
+  - {fileID: 4963108840602843046}
+  m_Father: {fileID: 4553548533444560457}
+  m_RootOrder: 2
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0, y: 0}
+  m_AnchorMax: {x: 1, y: 1}
+  m_AnchoredPosition: {x: 0, y: 0}
+  m_SizeDelta: {x: 0, y: 0}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!114 &1305929652721192479
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 6635742060741568579}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0d51f3a7c41ab0346b49ae50d456bece, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  MarkType: 0
+  CustomComponentName: TipsGroup
+  ComponentGeneratePath: 
+  CustomComment: 
+  mComponentName: UnityEngine.RectTransform
 --- !u!1 &6688968852540380078
 GameObject:
   m_ObjectHideFlags: 0
@@ -579,3 +790,211 @@ MonoBehaviour:
   m_FillOrigin: 0
   m_UseSpriteMesh: 0
   m_PixelsPerUnitMultiplier: 1
+--- !u!1 &8587068105891204732
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 8317964850212505717}
+  - component: {fileID: 6573828909150343973}
+  - component: {fileID: 4159299806600508353}
+  - component: {fileID: 7973209621444137291}
+  m_Layer: 5
+  m_Name: TipsFreeInfo
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &8317964850212505717
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8587068105891204732}
+  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 4963108840602843046}
+  m_RootOrder: 1
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 0.5}
+  m_AnchorMax: {x: 0.5, y: 0.5}
+  m_AnchoredPosition: {x: 0, y: 58.1}
+  m_SizeDelta: {x: 256.91943, y: 69.37344}
+  m_Pivot: {x: 0.5, y: 0.5}
+--- !u!222 &6573828909150343973
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8587068105891204732}
+  m_CullTransparentMesh: 0
+--- !u!114 &4159299806600508353
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8587068105891204732}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 0
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 12800000, guid: ee53ec8263684344e83f8193df0f4948, type: 3}
+    m_FontSize: 20
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 1
+    m_MaxSize: 40
+    m_Alignment: 7
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 1
+    m_LineSpacing: 1
+  m_Text: 
+--- !u!114 &7973209621444137291
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 8587068105891204732}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0d51f3a7c41ab0346b49ae50d456bece, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  MarkType: 0
+  CustomComponentName: TipsFreeInfo
+  ComponentGeneratePath: 
+  CustomComment: 
+  mComponentName: UnityEngine.UI.Text
+--- !u!1 &9147752839191043481
+GameObject:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  serializedVersion: 6
+  m_Component:
+  - component: {fileID: 7871946730989972981}
+  - component: {fileID: 5451306178017641390}
+  - component: {fileID: 3866713734906809122}
+  - component: {fileID: 4977625811136254066}
+  - component: {fileID: 494481767906295022}
+  m_Layer: 5
+  m_Name: TipsFreeDistanceInfo
+  m_TagString: Untagged
+  m_Icon: {fileID: 0}
+  m_NavMeshLayer: 0
+  m_StaticEditorFlags: 0
+  m_IsActive: 1
+--- !u!224 &7871946730989972981
+RectTransform:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 9147752839191043481}
+  m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
+  m_LocalPosition: {x: 0, y: 0, z: 0}
+  m_LocalScale: {x: 1, y: 1, z: 1}
+  m_Children: []
+  m_Father: {fileID: 4963108840602843046}
+  m_RootOrder: 0
+  m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
+  m_AnchorMin: {x: 0.5, y: 1}
+  m_AnchorMax: {x: 0.5, y: 1}
+  m_AnchoredPosition: {x: 0, y: -94.06}
+  m_SizeDelta: {x: 148.2085, y: 56.60794}
+  m_Pivot: {x: 0.5, y: 0}
+--- !u!222 &5451306178017641390
+CanvasRenderer:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 9147752839191043481}
+  m_CullTransparentMesh: 0
+--- !u!114 &3866713734906809122
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 9147752839191043481}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_Material: {fileID: 0}
+  m_Color: {r: 1, g: 1, b: 1, a: 1}
+  m_RaycastTarget: 0
+  m_Maskable: 1
+  m_OnCullStateChanged:
+    m_PersistentCalls:
+      m_Calls: []
+  m_FontData:
+    m_Font: {fileID: 12800000, guid: ee53ec8263684344e83f8193df0f4948, type: 3}
+    m_FontSize: 20
+    m_FontStyle: 0
+    m_BestFit: 0
+    m_MinSize: 1
+    m_MaxSize: 40
+    m_Alignment: 1
+    m_AlignByGeometry: 0
+    m_RichText: 1
+    m_HorizontalOverflow: 0
+    m_VerticalOverflow: 0
+    m_LineSpacing: 1
+  m_Text: 1.4m
+--- !u!114 &4977625811136254066
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 9147752839191043481}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 0d51f3a7c41ab0346b49ae50d456bece, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  MarkType: 0
+  CustomComponentName: DistanceInfo
+  ComponentGeneratePath: 
+  CustomComment: 
+  mComponentName: UnityEngine.UI.Text
+--- !u!114 &494481767906295022
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 9147752839191043481}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: cfabb0440166ab443bba8876756fdfa9, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
+  m_EffectColor: {r: 0.09411765, g: 0.09411765, b: 0.09411765, a: 0.7529412}
+  m_EffectDistance: {x: 1.2, y: -1.2}
+  m_UseGraphicAlpha: 1