using System.Collections.Generic; using Core.Language; using Excel2Json; using Fort23.Core; using Fort23.Mono.Phases; using Fort23.UTool; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using Utility; using Utility.CTween; namespace Fort23.Mono { public class PlayerGuideManager : Singleton { public bool isSkip = false; public bool isUnLockAll = false; /// /// 调试模式. /// public bool isDebugging; public List debugPhase = new List(); public UnityAction overCallBack; /// /// 是否完成强制引导 /// public bool isForceDone = true; /// /// 是否完成非强制引导 /// public bool isTriggerDone = true; /// /// 手指 /// public Transform finger; /// /// 黑底Obj /// public GameObject blackBaseObj; /// /// 新手引导表 /// public PlayerGuideConfig guideConfig; /// /// 光圈(方) /// public Transform fxTrans01; /// /// 光圈(圆) /// public Transform fxTrans02; /// /// 高亮区域 /// // public GameObject fxHighLightObj; public Image highLightSpr; /// /// 保存 被改变父级的引用 /// private Transform myMother; /// /// 被改变的目标 /// private GameObject target; /// /// 引导目标上一次的坐标 /// private Vector3 lastPos; /// /// 当前引导id /// public int curPhase = -1; /// /// 当前步骤 /// public int curStep; // private bool mIsNew = false; // // public bool IsNewUser // { // get { return mIsNew; } // set { mIsNew = value; } // } public DialogBox dialogBox = new DialogBox(); public IGuideLogic guideLogic; /// /// 简化配置用. /// public bool isReadFingerPos; public bool isInitGuide = false; public GameRuntimeConfig GameRuntimeConfig; public Map ALLGuideStepData = new Map(); public PlayerGuideManager() { InitGuide(); } /// /// 引导重置 /// /// public void GuideReset(int id) { if (AccountFileInfo.Instance.playerData.phaseKey.Contains(id)) { int maxCount = 0; if (ALLGuideStepData.ContainsKey(id)) { maxCount = ALLGuideStepData[id]; } var idx = AccountFileInfo.Instance.playerData.phaseKey.IndexOf(id); if (AccountFileInfo.Instance.playerData.phaseValue[idx] < maxCount) { AccountFileInfo.Instance.playerData.phaseValue[idx] = -1; } } } /// /// 新手引导是否能做 步数从0开始 需要看对应逻辑所在的索引 /// /// /// public bool GuideIsCanDo(int groupID, int curstep = 0) { // if (!(groupID == 9 || groupID == 910 || groupID == 320)) // { // return false; // } // if (groupID != 330) // { // return false; // } if (curstep > 1 && guideLogic == null) { return false; } if (AccountFileInfo.Instance.playerData == null) //todo 容错测试场景没有玩家数据 { LogTool.Log("AccountFileInfo.Instance.playerSetting = " + AccountFileInfo.Instance.playerData); return false; } if (isSkip) { return false; } if (isDebugging) { if (!debugPhase.Contains(groupID) !) { return false; } } if (guideLogic != null) { if (guideLogic.guideID != groupID) { return false; } } // // if (!isDebugging) //如果不是指定调试就要判断是否能触发 // { // if (groupID >= 0) // { // int configId = (groupID + 1) * 100 + 1; // PlayerGuideConfig playerGuideConfig = ConfigComponent.Instance.Get(configId); // // if (playerGuideConfig.NeedLevel > PlayerManager.Instance.Level) // { // return false; // } // } // } int maxCount = 0; if (ALLGuideStepData.ContainsKey(groupID)) { maxCount = ALLGuideStepData[groupID]; } int step = GetPhaseStep(groupID); if (curstep != -1) //判断这个新手引导这一步能否做 { if (curstep <= step) { return false; } if (curstep - step > 1) //只能比当前步数多1才可以执行 { return false; } } if (step >= maxCount) { return false; } return true; } public TimerEntity _timerEntity; public void ChangeBtnSkip() { GuidePanel guidePanel = UIManager.Instance.GetComponent(); if (guidePanel != null) guidePanel.Btn_Skip.gameObject.SetActive(false); _timerEntity?.Dispose(); _timerEntity = null; _timerEntity = TimerComponent.Instance.AddTimer(10000, () => { if (UIManager.Instance.GetComponent() != null) UIManager.Instance.GetComponent().Btn_Skip.gameObject.SetActive(true); }); } /// /// 引导初始化 /// public void InitGuide() { foreach (var playerGuideConfig in ConfigComponent.Instance.GetAll()) { if (!ALLGuideStepData.ContainsKey(playerGuideConfig.groupID)) { ALLGuideStepData.Add(playerGuideConfig.groupID, 1); } else { ALLGuideStepData[playerGuideConfig.groupID] += 1; } } // // EventManager.Instance.AddEventListener(CustomEventType.NextGuide, RunNextGuide); // GameRuntimeConfig = GameApplction.Instance.runtimeConfig; // LogTool.Log("InitGuide************************"); // if (isInitGuide) // { // LogTool.Log("已初始化"); // return; // } // // if (GameRuntimeConfig.ClearGuideData) // { // AccountFileInfo.Instance.ClearGuideData(); // } // // // isSkip = GameRuntimeConfig.isSkip; // // // IsUseServerData = GameRuntimeConfig.IsUseServerData; #if UNITY_IPHONE || UNITY_ANDROID&&!UNITY_EDITOR IsUseServerData = true; #endif // // isDebugging = GameRuntimeConfig.isDebug; // isUnLockAll = GameRuntimeConfig.isUnlockAll; #if !UNITY_EDITOR isSkip = false; isDebugging = false; isUnLockAll = false; IsUseServerData = true; #endif // List ids = new List(); // // if (GameRuntimeConfig.debugPhase.x != 0) // { // ids.Add((int)GameRuntimeConfig.debugPhase.x); // } // // if (GameRuntimeConfig.debugPhase.y != 0) // { // ids.Add((int)GameRuntimeConfig.debugPhase.y); // } // // if (GameRuntimeConfig.debugPhase.z != 0) // { // ids.Add((int)GameRuntimeConfig.debugPhase.z); // } // // if (GameRuntimeConfig.debugPhase.w != 0) // { // ids.Add((int)GameRuntimeConfig.debugPhase.w); // } // debugPhase = ids; if (isDebugging) { for (var i = 0; i < debugPhase.Count; i++) { if (AccountFileInfo.Instance.playerData.phaseKey.Contains((int)debugPhase[i])) { var idx = AccountFileInfo.Instance.playerData.phaseKey.IndexOf(debugPhase[i]); AccountFileInfo.Instance.playerData.phaseValue[idx] = -1; } } } if (isSkip || isDebugging) { isInitGuide = true; isForceDone = true; return; } isForceDone = AccountFileInfo.Instance.playerData.isForceDone; curPhase = AccountFileInfo.Instance.playerData.curPhase; curStep = AccountFileInfo.Instance.playerData.curStep; //完成强制引导 if (isForceDone) { isInitGuide = true; return; } //新用户,从未做过新手引导 if (PlayerManager.Instance.curGuideGroupId == 0 && curPhase <= 0) { curPhase = 0; } // //没有引导记录,但有游戏记录(不是第一次玩) // else if (PlayerManager.Instance.currStageId > 1 && curPhase <= 0) // { // LogTool.Warning("玩家更换了设备,或者本地引导记录被删除,跳过所有强制引导:" + PlayerManager.Instance.PlayerId); // isForceDone = true; // isInitGuide = true; // AccountFileInfo.Instance.playerSetting.isForceDone = true; // AccountFileInfo.Instance.Save(); // return; // } // else if (PlayerManager.Instance.currStageId > 10) // { // LogTool.Warning("超过10关了,强制引导已经完成:" + PlayerManager.Instance.PlayerId); // isForceDone = true; // isInitGuide = true; // AccountFileInfo.Instance.playerSetting.isForceDone = true; // AccountFileInfo.Instance.Save(); // return; // } // else // { // // } isInitGuide = true; } private int GetPhaseStep(int key) { if (AccountFileInfo.Instance.playerData.phaseKey.Contains(key)) { int idx = AccountFileInfo.Instance.playerData.phaseKey.IndexOf(key); return AccountFileInfo.Instance.playerData.phaseValue[idx]; } else { return -1; } } /// /// 将目标加到新手引导的Panel里面. /// /// public void JoinMe(GameObject target) { finger.gameObject.SetActive(false); if (target == null) { LogTool.Log("______" + "找不到目标"); return; } Transform transform = UIManager.Instance.GetComponent().transform; if (target.transform.parent.Equals(transform)) { LogTool.Log("______" + "重复改变目标的父节点,自动忽略,可能是断网重连造成的,请检查"); return; } this.lastPos = target.transform.localPosition; myMother = target.transform.parent; this.target = target; target.transform.parent = transform; target.transform.localScale = Vector3.one; fxTrans01.gameObject.SetActive(true); fxTrans01.position = target.transform.position; } /// /// 还原对象 /// public void ReductionTargetObject() { target.transform.parent = myMother; target.transform.localPosition = lastPos; } public void JoinMe(GameObject target, Vector3 vector3) { if (target == null) { LogTool.Log("______" + "找不到目标"); return; } Transform transform = UIManager.Instance.GetComponent().transform; if (target.transform.parent.Equals(transform)) { LogTool.Log("______" + "重复改变目标的父节点,自动忽略,可能是断网重连造成的,请检查"); return; } this.lastPos = target.transform.localPosition; myMother = target.transform.parent; this.target = target; target.transform.parent = transform; target.transform.localScale = Vector3.one; fxTrans01.gameObject.SetActive(true); fxTrans01.parent = target.transform; fxTrans01.localPosition = vector3; fxTrans01.parent = transform; finger.gameObject.SetActive(false); } public void RestGuide() { curPhase = 0; curStep = 0; } /// /// 设置新手引导 /// /// public async CTask SetGuid(int phase) { if (isDebugging) { if (!debugPhase.Contains(phase)) { return; } } if (isSkip) { return; } if (guideLogic != null) { return; } UIManager.Instance.SetEventSystemEnable(false); curPhase = phase; guideLogic = null; guideLogic = GetIGuideLogic(curPhase); GuidePanel guildPanel = await UIManager.Instance.LoadAndOpenPanel(null, UILayer.Top, isFocus: false); dialogBox.Init(); UIManager.Instance.SetEventSystemEnable(true); finger = guildPanel.GuideHand; fxTrans01 = guildPanel.FocusFrame01; fxTrans02 = guildPanel.FocusFrame02; blackBaseObj = guildPanel.Btn_Bg.gameObject; guideLogic.SavePhase(curPhase); guideLogic.ClearList(); guideLogic.Active(); guideLogic.Begin(); NextGuideEx(); } public IGuideLogic GetIGuideLogic(int groupId) { IGuideLogic guideLogic = null; switch (groupId) { case 1: guideLogic = new Phase1(this); break; } return guideLogic; } /// /// 关闭引导,重置到初始状态. /// public void ResetPlayerGuide() { Transform transform = UIManager.Instance.GetComponent().transform; finger.transform.parent = transform; finger.transform.localScale = new Vector3(1, 1, 1); SetFingerVisiable(false); } public void SetFingerVisiable(bool b, string playName = "Loop") { finger.gameObject.SetActive(b); GuidePanel guidePanel = UIManager.Instance.GetComponent(); switch (guideConfig.FingerType) { case 1: guidePanel.GuideHandState.ChangeState(0); break; case 2: guidePanel.GuideHandState.ChangeState(1); break; case 3: guidePanel.GuideHandState.ChangeState(2); break; case 4: playName = "changan"; guidePanel.GuideHandState.ChangeState(1); break; case -1: finger.gameObject.SetActive(false); break; } SetFingerAnimation(playName); } public void SetFingerSize(Vector3 size) { finger.localScale = size; } public void SetfxTransVisiable(bool b, int type = 0) { switch (type) { case 0: fxTrans01.gameObject.SetActive(b); break; case 1: fxTrans02.gameObject.SetActive(b); break; } } public void SetBlackBaseVisiable(bool b) { blackBaseObj.gameObject.SetActive(b); } public void SetBlackA(byte b) { Color c = new Color32(0, 0, 0, b); blackBaseObj.gameObject.GetComponent().color = c; } public void FinishATriggerGuide() { SetBlackBaseVisiable(false); if (guideLogic != null) { guideLogic = null; } } public bool IsStepSkip = false; public async CTask ConfigLogic(int configID, System.Action action, int diTyp = 1, string str = null) { IsStepSkip = false; guideConfig = ConfigComponent.Instance.Get(configID); // if (IsUseServerData) // { // PlayerManager.Instance.PlayerGuideDataComponent.UpdateData(configID); // await HttpSendManager.Instance.SendSaveGuideDataRequest(configID, SaveGuideDataCallBack); //记录服务器 // } if (guideConfig.IsSkip == 1) { IsStepSkip = true; NextGuide(); return; } if (guideConfig.Highlighting == 0) { SetfxTransVisiable(false); } int[] fPos = guideConfig.fingerPos; int[] dPos = guideConfig.dialogPos; //int[] nPos = guideConfig.NpcPos; isReadFingerPos = true; SetFingerVisiable(false); SetFingerPos(fPos); SetDialogPos(dPos); // if (guideConfig.SpeakerStyle == 3) // { // SetDilogBGSize(new Vector2(guideConfig.TextSize[0], guideConfig.TextSize[1])); // } // SetNpcPos(nPos); SetBlackBaseVisiable(true); SetBlackAlpha(guideConfig.blackAlpha); ShowDialogBox(action, str); await dialogBox.SetDiTex(guideConfig, guideConfig.SpeakerImage); // int[] scale = new[] { 750, 750 }; // SetNpcSize(scale); } /// /// 下一步引导 /// public void NextGuide() { if (BreakGuide(guideLogic)) { return; } try { //容错: guideLogic.Guide(); } catch (System.Exception e) { LogTool.Error("打印异常信息:" + e); ResetPlayerGuide(); CloseForceGuide(); LogTool.Error("引导出错,出错步骤,Phase=" + curPhase + "-" + curStep); } EventManager.Instance.Dispatch(CustomEventType.NextGuide,null); } public CTask CanDoNextCTask; public async void RunNextGuide(IEventData eventData) { if (CanDoNextCTask != null) { await CanDoNextCTask; NextGuideEx(); } else { NextGuideEx(); } CanDoNextCTask = null; } public void NextGuideEx() { if (BreakGuide(guideLogic)) { return; } try { //容错: guideLogic.Guide(); } catch (System.Exception e) { LogTool.Error("打印异常信息:" + e); ResetPlayerGuide(); CloseForceGuide(); LogTool.Error("引导出错,出错步骤,Phase=" + curPhase + "-" + curStep); } ChangeBtnSkip(); } private bool BreakGuide(IGuideLogic guideLogic) { //#if UNITY_EDITOR if (isSkip) { this.guideLogic = null; return true; } //#endif if (guideLogic == null) { return true; } if (guideLogic.isSkipGuide) { LogTool.Log("引导开启条件不符合,不再执行"); this.guideLogic = null; return true; } //强制和非强制引导都完成 if (isForceDone && isTriggerDone) { LogTool.Log("引导完成"); this.guideLogic = null; return true; } return false; } public void SkipGuide() { } /// /// 关闭强制引导 /// public void CloseForceGuide() { HideDialogBox(); isForceDone = true; SetBlackBaseVisiable(false); if (guideLogic != null) { guideLogic = null; } overCallBack?.Invoke(); overCallBack = null; UIManager.Instance.HideUIUIPanel(UIDestroyType.ImmediatelyDestroy); } public void SetBlackAlpha(float f) { if (f == 0) { f = 0.05f; } Color color = blackBaseObj.GetComponent().color; color.a = f; blackBaseObj.GetComponent().color = color; } public BetterList dialogList = new BetterList(); public void HideDialogBox(bool isHide = true) { GuidePanel guidePanel = UIManager.Instance.GetComponent(); if (guidePanel != null) { if (isHide) { guidePanel.DialogBoxState.gameObject.SetActive(false); } } } /// /// 显示对话框 /// public void ShowDialogBox(System.Action action = null, string key = null) { if (guideConfig.desc == -1) { action?.Invoke(); action = null; return; } GuidePanel guidePanel = UIManager.Instance.GetComponent(); switch (guideConfig.SpeakerStyle) { case 1: guidePanel.DialogBoxState.ChangeState(0); break; case 2: guidePanel.DialogBoxState.ChangeState(1); break; case 3: guidePanel.DialogBoxState.ChangeState(2); break; } dialogBox.ChangeState(guideConfig.SpeakerStyle); if (guideConfig.SpeakerStyle != 3) { SetDialogPos(guideConfig.dialogPos); } string str = null; if (key == null) { str = LanguageManager.Instance.Text(guideConfig.desc); } else { str = string.Format(LanguageManager.Instance.Text(guideConfig.desc), key); } string[] textArr = str.Split(';'); dialogList.Clear(); foreach (string tex in textArr) { dialogList.Add(tex); } dialogBox.Open(dialogList, action); } private void SetDialogPos(int[] dPos) { if (dPos != null) { Vector3 pos = new Vector3(dPos[0], dPos[1], 0); float ratio = Screen.width / 1624f; pos.x *= ratio; dialogBox.MessageBG.localPosition = pos; } else { dialogBox.MessageBG.localPosition = new Vector3(-125, -100, 0); } } private void SetNpcPos(int[] nPos) { if (nPos != null) { Vector3 pos = new Vector3(nPos[0], nPos[1], 0); // dialogBox.UISpiritLoader.transform.localPosition = pos; } else { // dialogBox.UISpiritLoader.transform.localPosition = new Vector3(422, -100, 0); } } public void SetFingerPos(Vector3 pos, GameObject gameObject = null) { if (gameObject != null) { finger.GetComponent().pivot = gameObject.GetComponent().pivot; } else { finger.GetComponent().pivot = new Vector2(0.5f, 0.5f); } finger.transform.localPosition = pos; } private CustomVectorTween _customVectorTween; public void SetFingerTweenMove(Vector3 starPos, Vector3 endPos, float time) { // SetFingerAnimation("Loop"); _customVectorTween?.Kill(); _customVectorTween = null; _customVectorTween = CustomTweenManager.To(() => starPos, x => SetFingerPos(x), endPos, time, finger.gameObject) .SetEase(CustomTweenEX.CustomAnimationCurve.Line).SetLoop(true); } public void SetFingerAnimation(string playerName) { // SetFingerAnimation("Loop"); finger.GetComponent().Play(playerName); } private void SetFingerPos(int[] fPos) { SetFingerPos(new Vector3(9999, 9999, 0)); if (fPos != null && fPos.Length >= 2) { Vector3 pos = new Vector3(fPos[0], fPos[1], 0); SetFingerPos(pos); } else { isReadFingerPos = false; } // if (guideConfig.reversalFinger == 1) // { // finger.transform.localScale = new Vector3(1, 1, 1); // } // else if (guideConfig.reversalFinger == 2) // { // finger.transform.localScale = new Vector3(-1, 1, 1); // } } public Vector2 GetProperPos(Vector3 pos, Vector2 size, GameObject gameObject = null) { if (gameObject != null) { Vector2 pivot = gameObject.GetComponent().pivot; Vector2 pivot1 = pivot - Vector2.one * 0.5f; float x = pos.x - size.x * pivot1.x; float y = pos.y - size.y * pivot1.y; return new Vector2(x, y); } else { return pos; } } /// /// 设置展示框的大小和位置 如果有锚点同步传入对应gameobject /// /// /// /// 0是矩阵 1是圆形 /// public void SetShowFramePosAndSize(Vector3 pos, Vector2 size, int type = 0, GameObject gameObject = null) { switch (type) { case 0: if (gameObject != null) { RectTransform rectTransform = gameObject.GetComponent(); Vector2 pivot = rectTransform.pivot; Vector2 pivot1 = pivot - Vector2.one * 0.5f; float x = pos.x - size.x * pivot1.x; float y = pos.y - size.y * pivot1.y; fxTrans01.transform.localPosition = new Vector3(x, y, 0); //fxTrans01.GetComponent().pivot = gameObject.GetComponent().pivot; } else { fxTrans01.GetComponent().pivot = new Vector2(0.5f, 0.5f); fxTrans01.transform.localPosition = pos; } fxTrans01.GetComponent().sizeDelta = size * 2f; CustomTweenManager.To(() => fxTrans01.GetComponent().sizeDelta, x => fxTrans01.GetComponent().sizeDelta = x, size, 0.3f, fxTrans01.gameObject).OnComplete( () => { fxTrans01.GetComponent().sizeDelta = size; }).SetEase(CustomTweenEX.CustomAnimationCurve.InExpo); //fxTrans01.GetComponent().sizeDelta = size; break; case 1: if (gameObject != null) { fxTrans02.GetComponent().pivot = gameObject.GetComponent().pivot; } else { fxTrans02.GetComponent().pivot = new Vector2(0.5f, 0.5f); } fxTrans02.transform.localPosition = pos; fxTrans02.GetComponent().sizeDelta = size; break; } } /// /// 设置文本大小 /// /// public void SetDilogBGSize(Vector2 size) { dialogBox.MessageBG.GetComponent().sizeDelta = size; } /// /// 设置mpc大小 /// /// public void SetNpcSize(int[] scale) { dialogBox.UISpiritLoader.GetComponent().sizeDelta = new Vector2(scale[0], scale[1]); dialogBox.UISpiritLoader.SetLoaderSpirit(); } public Vector3 WorldPosToLocalPos(Vector3 pos) { Vector3 localPos = UIManager.Instance.GetComponent().transform.InverseTransformPoint(pos); return localPos; } public void SetMaskTarget(GameObject gameObject) { // if (guideConfig.ForceOnclick == 0) // { // return; // } UIManager.Instance.GetComponent().SetTarget(gameObject); } public void SetOnClickMask(bool value) { SetOnClickMaskSize(Vector2.zero); UIManager.Instance.GetComponent().OnClickMask.onClick.RemoveAllListeners(); UIManager.Instance.GetComponent().SetOnClickMask(value); } public void SetOnClickMaskSize(Vector2 size) { UIManager.Instance.GetComponent().SetOnClickMaskSize(size); } public void SetOnClickMaskOnClickAction(UnityAction unityAction) { UIManager.Instance.GetComponent().SetOnClickMaskOnClickAction(unityAction); } /// /// 阶段初始化 /// public void StepInit() { _customVectorTween?.Kill(); _customVectorTween = null; UIManager.Instance.GetComponent().transform.SetAsLastSibling(); if (guideConfig.SpeakerStyle == 3) { HideDialogBox(false); } else { HideDialogBox(); } SetfxTransVisiable(false); SetMaskTarget(null); SetFingerVisiable(false); SetBlackBaseVisiable(true); } public void TweenAlpha() { } } }