| using System;  | 
| using System.Collections;  | 
| using System.Collections.Generic;  | 
| using Cysharp.Threading.Tasks;  | 
| using UnityEngine;  | 
| using UnityEngine.UI;  | 
| using DG.Tweening;  | 
|   | 
| //引导功能包含  | 
| // 1.功能开启  | 
| // 2.引导NPC对话  | 
| // 3.点击引导  | 
| public class NewBieWin : UIBase  | 
| {  | 
|     [SerializeField] NewBieMask m_NewBieMask;   //遮罩,可镂空  | 
|   | 
|     //新功能开放  | 
|     [SerializeField] Transform m_NewFunction;     | 
|     [SerializeField] Transform m_ContainerFunctionBg;   | 
|     [SerializeField] Text m_FunctionName;  | 
|     [SerializeField] Image m_FuncIcon;  //功能图片飞入对应位置  | 
|     [SerializeField] UIEffectPlayer unlockEffect; //飞到对应功能后爆开特效  | 
|     [SerializeField] UIEffectPlayer funcEffect; //功能解锁特效  | 
|   | 
|     //引导npc对话  | 
|     [SerializeField] Transform m_GuideTalkRect;  | 
|     [SerializeField] UIEffectPlayer m_newBieGuideNPC;  | 
|     [SerializeField] Button m_ClickTalk;  | 
|     [SerializeField] RichText m_TalkText;  | 
|   | 
|     //点击引导  | 
|     [SerializeField] Transform m_NewBieGuide;  | 
|     [SerializeField] Transform m_ContainerDialogue;  | 
|     [SerializeField] RichText m_Dialogue;  | 
|     [SerializeField] Image m_ArrowUP;  | 
|     [SerializeField] Image m_ArrowDown;  | 
|     [SerializeField] Image m_ArrowLeft;  | 
|     [SerializeField] Image m_ArrowRight;  | 
|     [SerializeField] UIEffectPlayer m_ClickEffect;  | 
|     [SerializeField] ClickScreenOtherSpace m_ClickScreenOtherSpace;  | 
|       | 
|   | 
|     Transform m_ClickTarget;  | 
|     GuideConfig config;  | 
|     NewBieGuideScriptableObject stepConfig; //引导步骤  | 
|   | 
|   | 
|     #region Built-in  | 
|   | 
|     protected override void InitComponent()  | 
|     {  | 
|         m_ClickTalk.AddListener(()=>  | 
|         {  | 
|             ReportStepOver();  | 
|         });  | 
|     }  | 
|   | 
|     protected override void OnPreOpen()  | 
|     {  | 
|         m_ClickTarget = null;  | 
|         //关闭其他可能在主界面显示的窗口等  | 
|         UIManager.Instance.CloseWindow<ChatWin>();  | 
|         NewBieCenter.Instance.guideStepChangeEvent += OnStepChange;  | 
|     }  | 
|   | 
|     protected override void OnClose()  | 
|     {  | 
|         NewBieCenter.Instance.guideStepChangeEvent -= OnStepChange;  | 
|         if (NewBieCenter.Instance.currentGuide != 0)  | 
|         {  | 
|             NewBieCenter.Instance.FinishCurrentGuideWithoutCloseWin();  | 
|         }  | 
|         m_ClickTarget = null;  | 
|         stepConfig = null;  | 
|     }  | 
|   | 
|   | 
|     protected override void NextFrameAfterOpen()  | 
|     {  | 
|         Display();  | 
|     }  | 
|     #endregion  | 
|   | 
|     void Display()  | 
|     {  | 
|         config = GuideConfig.Get(NewBieCenter.Instance.currentGuide);  | 
|         if (config == null)  | 
|         {  | 
|             CloseWindow();  | 
|             return;  | 
|         }  | 
|   | 
|         var step = NewBieCenter.Instance.guideStep;  | 
|         stepConfig = ScriptableObjectLoader.LoadSoNewBieGuideStep(step);  | 
|         if (stepConfig == null)  | 
|         {  | 
|             CloseWindow();  | 
|             return;  | 
|         }  | 
|   | 
|   | 
|         try  | 
|         {  | 
|             m_ClickTarget = FindTransform(stepConfig.UIElementPath);  | 
|             if (m_ClickTarget != null)  | 
|             {  | 
|                 m_lastTargetPosition = m_ClickTarget.position;  | 
|             }  | 
|             else  | 
|             {  | 
|                 #if UNITY_EDITOR  | 
|                 if (!string.IsNullOrEmpty(stepConfig.UIElementPath))  | 
|                     Debug.LogError($"引导步骤{step}找不到目标{stepConfig.UIElementPath}, 若不需要请删除路径");  | 
|                 #endif  | 
|             }  | 
|         }  | 
|         catch (Exception ex)  | 
|         {  | 
|             Debug.LogError(ex);  | 
|             NewBieCenter.Instance.FinishNewBieGuide(NewBieCenter.Instance.currentGuide);  | 
|         }  | 
|   | 
|         var type = stepConfig.guideType;  | 
|         if (type == GuideType.NewBie && stepConfig.clickCompleteNoMask)  | 
|         {   | 
|             m_NewBieMask.SetActive(false);  | 
|         }  | 
|         else  | 
|         {  | 
|             m_NewBieMask.SetActive(true);  | 
|             m_NewBieMask.Display(step, m_ClickTarget);  | 
|         }  | 
|   | 
|         if (type == GuideType.Function)  | 
|         {  | 
|             m_NewFunction.SetActive(true);  | 
|             m_NewBieGuide.SetActive(false);  | 
|             m_GuideTalkRect.SetActive(false);  | 
|             funcEffect.PlayByArrIndex(0);  | 
|             DisplayFunctionUnLock(config.Condition);  | 
|         }  | 
|         else if (type == GuideType.NpcTalk)  | 
|         {  | 
|             m_NewFunction.SetActive(false);  | 
|             m_NewBieGuide.SetActive(false);  | 
|             m_GuideTalkRect.SetActive(true);  | 
|             DisplayNPCTalk();  | 
|         }  | 
|         else  | 
|         {  | 
|             m_NewFunction.SetActive(false);  | 
|             m_NewBieGuide.SetActive(true);  | 
|             m_GuideTalkRect.SetActive(false);  | 
|             DisplayGuide();  | 
|         }  | 
|     }  | 
|   | 
|   | 
|     private void DisplayFunctionUnLock(int _functionId)  | 
|     {  | 
|         var config = FuncOpenLVConfig.Get(_functionId);  | 
|         m_FunctionName.text = config.Name;  | 
|         m_FuncIcon.SetSprite(config.Icon);  | 
|         m_FuncIcon.SetNativeSize();  | 
|         m_ContainerFunctionBg.SetActive(true);  | 
|         m_FunctionName.SetActive(true);  | 
|         m_FuncIcon.SetActive(true);  | 
|         m_FuncIcon.transform.localPosition = Vector3.zero;  | 
|         unlockEffect.Stop();  | 
|   | 
|         Co_FunctionUnLockDelay().Forget();  | 
|     }  | 
|   | 
|   | 
|     void DisplayNPCTalk()  | 
|     {  | 
|         if (stepConfig.effect == 0)  | 
|         {  | 
|             m_newBieGuideNPC.SetActive(false);  | 
|         }  | 
|         else  | 
|         {  | 
|             m_newBieGuideNPC.SetActive(true);  | 
|             m_newBieGuideNPC.effectId = stepConfig.effect;  | 
|             m_newBieGuideNPC.PlayByArrIndex(stepConfig.usherAction);  | 
|             m_newBieGuideNPC.transform.localPosition = stepConfig.usherPosition;  | 
|             m_newBieGuideNPC.transform.localScale = new Vector3(stepConfig.usherOrientation == NewBieGuideScriptableObject.UsherOrientation.Normal ? 1 : -1, 1, 1);  | 
|         }          | 
|         m_TalkText.text = stepConfig.GetTipContent();  | 
|     }  | 
|   | 
|   | 
|     private void DisplayGuide()  | 
|     {  | 
|         Co_DisplayGuide();  | 
|     }  | 
|   | 
|     //完成当前引导步骤  | 
|     private void ReportStepOver()  | 
|     {  | 
|         m_ClickTarget = null;  | 
|         NewBieCenter.Instance.ReportGuideStepComplete(NewBieCenter.Instance.guideStep);  | 
|   | 
|     }  | 
|   | 
|   | 
|     private void OnStepChange()  | 
|     {  | 
|         Display();  | 
|     }  | 
|   | 
|   | 
|     async UniTask Co_FunctionUnLockDelay()  | 
|     {  | 
|         await UniTask.Delay(1300);  | 
|   | 
|         m_ContainerFunctionBg.SetActive(false);  | 
|         m_FunctionName.SetActive(false);  | 
|         unlockEffect.transform.position = m_ClickTarget.position;  | 
|         m_FuncIcon.transform.DOMove(m_ClickTarget.position, 0.5f).SetEase(Ease.OutQuad).OnComplete(() =>  | 
|         {   | 
|             m_FuncIcon.SetActive(false);  | 
|             unlockEffect.onComplete = ReportStepOver;  | 
|             unlockEffect.Play();  | 
|         });  | 
|     }  | 
|   | 
|   | 
|     void Co_DisplayGuide()  | 
|     {  | 
|         if (stepConfig.HasTipContent())  | 
|         {  | 
|             m_ContainerDialogue.SetActive(true);  | 
|             m_Dialogue.text = stepConfig.GetTipContent();  | 
|             m_ArrowUP.SetActive(stepConfig.arrowPosition == NewBieGuideScriptableObject.ArrowPosition.Top);  | 
|             m_ArrowDown.SetActive(stepConfig.arrowPosition == NewBieGuideScriptableObject.ArrowPosition.Bottom);  | 
|             m_ArrowLeft.SetActive(stepConfig.arrowPosition == NewBieGuideScriptableObject.ArrowPosition.Left);  | 
|             m_ArrowRight.SetActive(stepConfig.arrowPosition == NewBieGuideScriptableObject.ArrowPosition.Right);  | 
|             m_ContainerDialogue.transform.position = m_ClickTarget.position;  | 
|             m_ContainerDialogue.transform.localPosition = m_ContainerDialogue.transform.localPosition + (Vector3)stepConfig.tipPosition;  | 
|         }  | 
|         else  | 
|         {  | 
|             m_ContainerDialogue.SetActive(false);  | 
|         }  | 
|   | 
|         m_ClickEffect.effectId = stepConfig.effect; //如果需要点击特效也增加偏移量  | 
|         m_ClickEffect.SetActive(true);  | 
|         m_ClickEffect.Play();  | 
|         m_ClickEffect.transform.position = m_ClickTarget.position;  | 
|         m_ClickEffect.transform.localPosition = m_ClickEffect.transform.localPosition + (Vector3)stepConfig.usherPosition;  | 
|   | 
|         if (stepConfig.clickCompleteNoMask)  | 
|         {  | 
|             m_ClickScreenOtherSpace.enabled = true;  | 
|             m_ClickScreenOtherSpace.AddListener(() =>  | 
|             {  | 
|                 ReportStepOver();  | 
|             });  | 
|         }  | 
|         else  | 
|         {  | 
|             m_ClickScreenOtherSpace.enabled = false;  | 
|             m_ClickScreenOtherSpace.RemoveAllListeners();  | 
|         }  | 
|     }  | 
|   | 
|     void LateUpdate()  | 
|     {  | 
|         if (Input.GetMouseButtonUp(0))  | 
|         {  | 
|             if (stepConfig == null)  | 
|             {  | 
|                 return;  | 
|             }  | 
|             if (stepConfig.clickAnyWhereComplete || m_NewBieMask.mask.IsInCirleArea(Input.mousePosition, CameraManager.uiCamera))  | 
|             {  | 
|                 if (m_ClickTarget == null)  | 
|                 {  | 
|                     Debug.LogError("引导 m_ClickTarget == null; step = " + NewBieCenter.Instance.guideStep);  | 
|                 }  | 
|                 var btn = m_ClickTarget.GetComponent<Button>();  | 
|                 ReportStepOver();  | 
|                 if (btn != null)  | 
|                 {  | 
|                     btn.onClick.Invoke();  | 
|                 }  | 
|             }  | 
|   | 
|         }  | 
|   | 
|         CheckTarget();  | 
|     }  | 
|   | 
|     Vector3 m_lastTargetPosition;  | 
|     //引导的目标发生位置变化的情况  | 
|     void CheckTarget()  | 
|     {  | 
|         if (m_ClickTarget == null)  | 
|             return;  | 
|   | 
|         if (m_lastTargetPosition != m_ClickTarget.position)  | 
|         {  | 
|             Display();  | 
|         }  | 
|   | 
|     }  | 
|   | 
|     //BaseCanvas/MainInterfaceWin/Widget_RightBottom/Container_Function/Function_Grid/Grid_6/Content/Btn_@*  | 
|     //分割成BaseCanvas/MainInterfaceWin/Widget_RightBottom/Container_Function/Function_Grid/Grid_6/Content 和 Btn_  | 
|     //在WindowCenter.Instance.uiRoot的 BaseCanvas/MainInterfaceWin/Widget_RightBottom/Container_Function/Function_Grid/Grid_6/Content下查找以Btn_开头的第一个子物体  | 
|   | 
|         //支持路径末尾加@*做模糊查找  | 
|     private Transform FindTransform(string path)  | 
|     {  | 
|         if (!path.EndsWith("@*"))  | 
|         {  | 
|             return UIManager.Instance.GetUIRoot().transform.Find(path);  | 
|         }  | 
|   | 
|         var paths = path.Split('/');  | 
|         var newPath = string.Join("/", paths, 0, paths.Length - 1);  | 
|         string findName = paths[paths.Length - 1].Replace("@*", "");  | 
|         var parent = UIManager.Instance.GetUIRoot().transform.Find(newPath);  | 
|         if (parent == null)  | 
|         {  | 
|             return null;  | 
|         }  | 
|         var comps = parent.GetComponentsInChildren<Transform>();  | 
|         for (int i = 0; i < comps.Length; i++)  | 
|         {  | 
|             if (comps[i].name.StartsWith(findName))  | 
|             {  | 
|                 return comps[i];  | 
|             }  | 
|         }  | 
|   | 
|         return UIManager.Instance.GetUIRoot().transform.Find(path);  | 
|     }  | 
|   | 
|   | 
|   | 
| }  | 
|   | 
|   | 
|   | 
|   | 
|   |