//-------------------------------------------------------- // [Author]: 第二世界 // [ Date ]: Wednesday, November 22, 2017 //-------------------------------------------------------- using UnityEngine; using System.Collections; using UnityEngine.UI; using System; namespace vnxbqy.UI { public class FunctionalGuideBehaviour : MonoBehaviour { [SerializeField] RectTransform m_Pivot; [SerializeField] RectTransform m_ClickHintRoot; [SerializeField] RectTransform m_ClickHint; public RectTransform clickHintRoot { get { return m_ClickHintRoot; } } [SerializeField] RectTransform m_ContainerLeft; [SerializeField] RectTransform m_ContainerRight; [SerializeField] Text m_DialogueLeft; [SerializeField] Text m_DialogueRight; [SerializeField] UIEffect m_Effect; [SerializeField] RectTransform m_ContainerArrow; [SerializeField] Image m_Arrow; [SerializeField] PositionTween m_ArrowTween; RectTransform selectBox; int selectBoxPatternBuf = -1; int m_Guide; public int guide { get { return m_Guide; } private set { m_Guide = value; } } float protectTimer = 0f; string clickTargetName; Transform m_ClickTarget; RectTransform rectTransform { get { return this.transform as RectTransform; } } RectMask2D mask; public void BeginGuide(int _guide) { guide = _guide; var guideConfig = GuideConfig.Get(guide); var stepConfig = ScriptableObjectLoader.LoadSoFunctionalGuideStep(guideConfig.Steps[0]); if (string.IsNullOrEmpty(stepConfig.GetTipContent(GuideType.Functional))) { m_ContainerLeft.SetActive(false); m_ContainerRight.SetActive(false); } else { if (stepConfig.clickPosition.x > 0) { m_ContainerLeft.SetActive(true); m_ContainerRight.SetActive(false); m_DialogueLeft.text = stepConfig.GetTipContent(GuideType.Functional); } else { m_ContainerLeft.SetActive(false); m_ContainerRight.SetActive(true); m_DialogueRight.text = stepConfig.GetTipContent(GuideType.Functional); } } m_ContainerArrow.SetActive(stepConfig.arrowPosition != NewBieGuideScriptableObject.ArrowPosition.None); if (stepConfig.arrowPosition != NewBieGuideScriptableObject.ArrowPosition.None) { switch (stepConfig.arrowPosition) { case NewBieGuideScriptableObject.ArrowPosition.Left: m_ContainerArrow.localPosition = new Vector2(-stepConfig.clickSize.x * 0.5f - m_ContainerArrow.rect.width * 0.5f, 0f); m_Arrow.transform.localEulerAngles = new Vector3(0, 0, 90); m_ArrowTween.from = new Vector3(8, 0, 0); m_ArrowTween.to = new Vector3(-8, 0, 0); break; case NewBieGuideScriptableObject.ArrowPosition.Right: m_ContainerArrow.localPosition = new Vector2(stepConfig.clickSize.x * 0.5f + m_ContainerArrow.rect.width * 0.5f, 0f); m_Arrow.transform.localEulerAngles = new Vector3(0, 0, 270); m_ArrowTween.from = new Vector3(8, 0, 0); m_ArrowTween.to = new Vector3(-8, 0, 0); break; case NewBieGuideScriptableObject.ArrowPosition.Top: m_ContainerArrow.localPosition = new Vector2(0f, stepConfig.clickSize.y * 0.5f + m_ContainerArrow.rect.height * 0.5f); m_Arrow.transform.localEulerAngles = new Vector3(0, 0, 0); m_ArrowTween.from = new Vector3(0, 8, 0); m_ArrowTween.to = new Vector3(0, -8, 0); break; case NewBieGuideScriptableObject.ArrowPosition.Bottom: m_ContainerArrow.localPosition = new Vector2(0f, -stepConfig.clickSize.y * 0.5f - m_ContainerArrow.rect.height * 0.5f); m_Arrow.transform.localEulerAngles = new Vector3(0, 0, 180); m_ArrowTween.from = new Vector3(0, 8, 0); m_ArrowTween.to = new Vector3(0, -8, 0); break; } } m_ClickHintRoot.localPosition = stepConfig.clickPosition; m_ClickHintRoot.sizeDelta = stepConfig.clickSize; if ((int)stepConfig.selectBox != selectBoxPatternBuf || selectBox == null) { var selectBosAssetName = string.Empty; switch (stepConfig.selectBox) { case NewBieGuideScriptableObject.SelectBoxPattern.Pattern1: selectBosAssetName = "SelectBox1"; break; case NewBieGuideScriptableObject.SelectBoxPattern.Pattern2: selectBosAssetName = "SelectBox2"; break; case NewBieGuideScriptableObject.SelectBoxPattern.None: selectBosAssetName = ""; break; } if (selectBox != null) { Destroy(selectBox.gameObject); selectBox = null; } if (!string.IsNullOrEmpty(selectBosAssetName)) { selectBox = UIUtility.CreateWidget(selectBosAssetName, selectBosAssetName).transform as RectTransform; selectBox.MatchWhith(m_ClickHint); } selectBoxPatternBuf = (int)stepConfig.selectBox; } clickTargetName = string.Empty; m_ClickTarget = null; mask = null; m_ClickHintRoot.SetActive(false); StopEffect(); FindClickTarget(); protectTimer = 0f; } private void ReportGuideComplete() { UnAttachTrigger(); clickTargetName = string.Empty; m_ClickTarget = null; mask = null; FunctionalGuideCenter.Instance.FinishGuide(guide); guide = 0; FunctionalGuideBehaviourPool.Recycle(this.gameObject); } private void ClickToCompleteGuide() { UnAttachTrigger(); clickTargetName = string.Empty; m_ClickTarget = null; mask = null; var config = GuideConfig.Get(guide); if (config != null) { if (config.CannotCompleteByClick != 1) { FunctionalGuideCenter.Instance.FinishGuide(guide); } } guide = 0; FunctionalGuideBehaviourPool.Recycle(this.gameObject); } private void LateUpdate() { if (m_ClickTarget != null) { if (clickTargetName != m_ClickTarget.name) { UnAttachTrigger(); m_ClickTarget = null; mask = null; protectTimer = 0f; } } FindClickTarget(); if (mask != null) { this.rectTransform.position = mask.rectTransform.position; } if (guide == 0 || NewBieCenter.Instance.IsGuideCompleted(guide)) { UnAttachTrigger(); clickTargetName = string.Empty; m_ClickTarget = null; mask = null; guide = 0; FunctionalGuideBehaviourPool.Recycle(this.gameObject); } } private void FindClickTarget() { if (m_ClickTarget == null) { try { protectTimer += Time.deltaTime; var guideConfig = GuideConfig.Get(guide); var stepConfig = ScriptableObjectLoader.LoadSoFunctionalGuideStep(guideConfig.Steps[0]); FindAndAttachTrigger(stepConfig.UIElementPath); } catch (Exception ex) { DebugEx.Log(ex); ReportGuideComplete(); } if (protectTimer > 3f) { Debug.LogFormat("新手引导:{0}因为点击对象获取超时异常结束,张维杰,请检查配置!", guide); ReportGuideComplete(); protectTimer = 0f; } } if (m_ClickTarget != null) { if (m_ClickTarget.gameObject.activeInHierarchy) { if (m_ClickTarget != null && m_ClickTarget.position != m_ClickHintRoot.position) { var screenPoint = CameraManager.uiCamera.WorldToViewportPoint(m_ClickTarget.position).SetZ(0); if (screenPoint.x < 1f && screenPoint.x > 0f && screenPoint.y < 1f && screenPoint.y > 0f) { m_ClickHintRoot.SetActive(true); PlayEffect(); m_ClickHintRoot.position = m_ClickTarget.position; } else { StopEffect(); m_ClickHintRoot.SetActive(false); } } } else { StopEffect(); m_ClickHintRoot.SetActive(false); } } } private void FindAndAttachTrigger(string _path) { m_ClickTarget = WindowCenter.Instance.uiRoot.transform.Find(_path); if (m_ClickTarget != null) { clickTargetName = m_ClickTarget.name; var trigger = NewBieEventTrigger.SetPointClick(m_ClickTarget.gameObject); if (trigger != null) { trigger.onClick.RemoveAllListeners(); trigger.onClick.AddListener(ClickToCompleteGuide); } mask = m_ClickTarget.GetComponentInParent(); if (mask != null) { this.rectTransform.sizeDelta = mask.rectTransform.sizeDelta; this.rectTransform.anchorMax = mask.rectTransform.anchorMax; this.rectTransform.anchorMin = mask.rectTransform.anchorMin; this.rectTransform.pivot = mask.rectTransform.pivot; this.rectTransform.position = mask.rectTransform.position; this.m_Pivot.MatchWhith(this.rectTransform); this.m_Pivot.pivot = new Vector2(0.5f, 0.5f); this.m_Pivot.sizeDelta = this.m_Pivot.sizeDelta + new Vector2(0, 20); this.m_Pivot.AddMissingComponent(); } else { var rectMask2D = this.rectTransform.GetComponent(); if (rectMask2D != null) { Destroy(rectMask2D); } } } } private void UnAttachTrigger() { if (m_ClickTarget != null) { NewBiePointerClickTrigger.Release(m_ClickTarget.gameObject); } } private void PlayEffect() { var guideConfig = GuideConfig.Get(guide); var effectId = 0; if (guideConfig != null) { var stepConfig = ScriptableObjectLoader.LoadSoFunctionalGuideStep(guideConfig.Steps[0]); if (stepConfig != null) { effectId = stepConfig.effect2; } } if (effectId != 0) { if (!m_Effect.IsPlaying) { m_Effect.Play(); } } else { if (m_Effect.IsPlaying) { m_Effect.Stop(); } } } private void StopEffect() { if (m_Effect.IsPlaying) { m_Effect.Stop(); } } } public class FunctionalGuideBehaviourPool { static GameObjectPoolManager.GameObjectPool pool = null; public static FunctionalGuideBehaviour Require() { if (pool == null) { var prefab = UILoader.LoadPrefab("FunctionalGuideBehaviour"); if (prefab != null) { pool = GameObjectPoolManager.Instance.RequestPool(prefab); } } if (pool != null) { var instance = pool.Request(); return instance.GetComponent(); } else { return null; } } public static void Recycle(GameObject _gameObject) { if (pool != null) { pool.Release(_gameObject); _gameObject.transform.SetParent(null); _gameObject.SetActive(false); } } public static void Clear() { if (pool != null) { pool.Clear(); pool = null; } } } }